FoundationaLLM MCP Client Tool
The FoundationaLLM MCP client tool allows agents to call any Model Context Protocol server using the official Python SDK. It mirrors the configuration patterns used by other FoundationaLLM tools while adding transport-specific options and telemetry instrumentation.
Capabilities
- Connects to arbitrary MCP servers over STDIO, streamable HTTP, or HTTP + Server-Sent Events (SSE) transports.
- Supports both synchronous (
_run) and asynchronous (_arun) invocation paths. - Emits rich content artifacts summarizing the invocation, including transport details, session identifiers, initialization metadata, and structured responses.
- Records OpenTelemetry spans for connection and request execution phases, aligning with existing FoundationaLLM tooling expectations.
- Provides per-invocation transport overrides so that agents can adjust endpoints or headers dynamically without redeploying the tool configuration.
Plugin Architecture
The MCP client tool is part of the foundationallm-agent-plugins package (v0.9.8-beta117) within the FoundationaLLM plugin system.
Package layout
src/python/plugins/
├── core/ # Core platform library (foundationallm)
│ └── pkg/foundationallm/
│ ├── langchain/common/
│ │ ├── foundationallm_tool_base.py # FoundationaLLMToolBase
│ │ └── foundationallm_tool_result.py # FoundationaLLMToolResult
│ ├── models/agents/agent_tool.py # AgentTool configuration model
│ └── plugins/ # ToolPluginManagerBase (abstract)
├── agent_core/ # Agent tool implementations
│ ├── pkg/foundationallm_agent_plugins/
│ │ ├── tools/
│ │ │ ├── __init__.py # Tool exports
│ │ │ ├── foundationallm_mcp_client_tool.py
│ │ │ └── foundationallm_mcp_client_tool_input.py
│ │ └── tool_plugin_manager.py # FoundationaLLMAgentToolPluginManager
│ ├── pkg/pyproject.toml
│ └── requirements.txt
├── agent_azure_ai/ # Azure AI-specific tools and workflows
├── agent_langchain/ # LangChain workflow implementations
└── agent_experimental/ # Experimental tools
How tools are registered
All agent-core tools are exported from foundationallm_agent_plugins.tools.__init__:
from .foundationallm_mcp_client_tool import FoundationaLLMMCPClientTool
The FoundationaLLMAgentToolPluginManager in tool_plugin_manager.py acts as a factory that routes tool creation by class_name:
class FoundationaLLMAgentToolPluginManager(ToolPluginManagerBase):
FOUNDATIONALLM_MCP_CLIENT_TOOL_CLASS = 'FoundationaLLMMCPClientTool'
def create_tool(self, tool_config, objects, user_identity, config, intercept_http_calls=False):
match tool_config.class_name:
case self.FOUNDATIONALLM_MCP_CLIENT_TOOL_CLASS:
return FoundationaLLMMCPClientTool(tool_config, objects, user_identity, config)
# ... other tools ...
Base class
FoundationaLLMMCPClientTool extends FoundationaLLMToolBase (defined in the foundationallm core package at foundationallm.langchain.common). The base class provides:
get_main_language_model()— resolves the LLM from the tool'sresource_object_idswhere the role ismain_model.get_main_prompt()— resolves the orchestration prompt from the tool'sresource_object_idswhere the role ismain_prompt.create_content_artifact()/create_error_content_artifact()— standard artifact helpers.tracer/logger— OpenTelemetry instrumentation fromfoundationallm.telemetry.config— platformConfigurationinstance for secret resolution.
Installation
The mcp SDK is pinned in src/python/plugins/agent_core/requirements.txt:
mcp==1.17.0
Configuration Reference
Register the tool in an agent definition using the FoundationaLLMMCPClientTool class. Tool properties are validated by a Pydantic model with the following top-level fields:
| Property | Type | Description |
|---|---|---|
transport |
"stdio" \| "streamable_http" \| "http_sse" |
Transport protocol to use. Defaults to streamable_http. |
endpoint_object_id |
String | Preferred for HTTP transports. References a FoundationaLLM.Configuration/apiEndpointConfigurations resource; the runtime resolves URL, headers, and timeouts from that endpoint. |
stdio |
Object | Required when transport is stdio; see below. |
streamable_http |
Object | Required when transport is streamable_http and no endpoint_object_id is set; see below. |
http_sse |
Object | Required when transport is http_sse and no endpoint_object_id is set; see below. |
client_name |
String | Reported to the server as the MCP client name. Defaults to foundationallm-mcp-client. |
client_version |
String | Reported to the server as the MCP client version. Defaults to 1.0.0. |
default_operation_timeout_seconds |
Number | Optional default timeout applied to operations that accept a read_timeout_seconds parameter (e.g., call_tool). |
STDIO settings
Note: STDIO transport is intended for advanced and local-development scenarios. It is not configurable via the Management Portal — use the API to configure agents with STDIO transport.
{
"transport": "stdio",
"stdio": {
"command": "./my-mcp-server",
"args": ["--flag"],
"env": {"API_TOKEN": "config://my-secret"},
"cwd": "/opt/mcp",
"encoding": "utf-8",
"encoding_error_handler": "strict"
}
}
Streamable HTTP settings
{
"transport": "streamable_http",
"streamable_http": {
"url": "https://example.com/mcp",
"headers": {
"Authorization": "config://my-service-token"
},
"timeout_seconds": 30,
"sse_read_timeout_seconds": 300,
"terminate_on_close": true
}
}
HTTP + SSE settings
{
"transport": "http_sse",
"http_sse": {
"url": "https://example.com/mcp",
"headers": {},
"timeout_seconds": 15,
"sse_read_timeout_seconds": 120
}
}
Configuration values that begin with config:// are resolved through Configuration.get_value, allowing secrets to be stored in Azure App Configuration or Key Vault. Values beginning with env:// are also resolved through Configuration.get_value, enabling environment variable lookups when the platform is configured to allow them.
Values beginning with context:// are runtime system headers resolved at MCP invocation time (HTTP transports only). They are configured in the Management Portal HTTP Headers editor under System / runtime context and are never stored as resolved values.
| Token | HTTP header | Resolved from |
|---|---|---|
context://user_identity |
X-USER-IDENTITY |
Signed-in user identity JSON |
context://conversation_id |
X-FLLM-SESSION-ID |
Conversation/session ID for the current chat |
Trusted internal MCP servers that call CoreAPI on behalf of the user (for example the Memory MCP server) typically require X-USER-IDENTITY = context://user_identity. See the Personalized Memory API Reference for the CoreAPI contract those servers must call.
System headers are opt-in: if a header row is not configured, nothing is sent. The MCP client tool does not implicitly inject user identity or session headers.
Example endpoint headers for an internal MCP server (Genesis):
{
"X-USER-IDENTITY": "context://user_identity",
"X-FLLM-SESSION-ID": "context://conversation_id"
}
For a full apiEndpointConfigurations resource you can POST via the Management API, see genesis-mcp-endpoint-template.json. Replace the placeholder URL with your Genesis MCP server base URL before creating or updating the endpoint.
External MCP servers (Perplexity, Microsoft Learn, etc.) should typically not include system context headers unless the server explicitly requires them.
Invocation Schema
The tool exposes the following input schema (see FoundationaLLMMCPClientToolInput):
{
"operation": "list_tools",
"arguments": {
"cursor": null
},
"transport_overrides": {
"headers": {"X-MCP-Trace": "123"}
},
"response_format": "json"
}
operationmust match one of the supportedClientSessioncoroutine names:list_tools,list_resources,read_resource,list_prompts,get_prompt,call_tool,complete,ping, orintelligent_execute.argumentsis forwarded directly to the MCP SDK after basic validation (timeouts are converted totimedelta, URLs validated, etc.).transport_overridesapplies per-call URL, header, or timeout adjustments on top of the configured transport. Unsupported fields are ignored for non-HTTP transports.response_formatcan bejson(default) ortext. JSON responses are pretty-printed before being returned.
Content Artifacts
Each invocation produces a TOOL_EXECUTION artifact containing:
- The structured response body (JSON by default).
- Metadata describing the transport (
stdio,streamable_http, orhttp_sse), target endpoint or command, resolved headers/env (with secrets redacted upstream), and initialization payload returned by the MCP server. - A normalized record of the request arguments so downstream components can audit calls.
Errors generate an additional TOOL_ERROR artifact populated with the exception details.
Example: Microsoft Learn MCP Server
To connect to the Microsoft Learn MCP server (anonymous HTTP access), configure the tool in the agent's AgentTool definition:
{
"name": "mslearn_mcp",
"description": "Call the Microsoft Learn MCP server for training content.",
"package_name": "foundationallm_agent_plugins",
"class_name": "FoundationaLLMMCPClientTool",
"properties": {
"transport": "streamable_http",
"streamable_http": {
"url": "https://learn.microsoft.com/api/mcp",
"headers": {},
"timeout_seconds": 30,
"sse_read_timeout_seconds": 300,
"terminate_on_close": true
}
}
}
Invoke the tool with the following payload to enumerate available tools:
{
"operation": "list_tools",
"arguments": {}
}
Intelligent Execute Operation
The MCP Client Tool supports an intelligent_execute operation that uses an LLM to orchestrate multi-turn MCP operations. This provides a simplified interface for complex MCP workflows without requiring the agent to manually discover and execute tools.
Configuration Requirements
To use intelligent_execute, the tool's AgentTool definition must include resource_object_ids entries for:
- Main Model — a resource object ID with
object_role: "main_model"pointing to a configuredFoundationaLLM.AIModelresource. This is resolved at init time viaget_main_language_model(). - Main Prompt — a resource object ID with
object_role: "main_prompt"pointing to aFoundationaLLM.Promptresource whoseprefixfield contains the orchestration prompt text. This is resolved viaget_main_prompt().
See mcp-orchestration-prompt.md for the recommended orchestration prompt template.
Usage
The intelligent_execute operation accepts a user prompt and automatically:
- Discovers available MCP tools via
list_tools - Plans the execution strategy using the LLM
- Executes the planned MCP operations
- Synthesizes results into a coherent response
{
"operation": "intelligent_execute",
"arguments": {
"prompt": "Search Microsoft Learn for MCP documentation"
}
}
Example: Microsoft Learn Search
For the MS Learn MCP server, the tool will:
- Call
list_toolsto discovermicrosoft_docs_search - Use the LLM to map the user prompt to appropriate tool arguments
- Execute
call_toolwith{"name": "microsoft_docs_search", "arguments": {"query": "MCP documentation"}} - Synthesize the search results into a comprehensive response
Token Tracking
The intelligent_execute operation tracks LLM token usage across the planning and synthesis phases. The totals are reported in the returned FoundationaLLMToolResult.input_tokens and output_tokens fields, as well as in the content artifact metadata.
Testing
Tests for the MCP client tool are located at:
src/python/FoundationaLLMAgentPlugins/test/foundationallm_mcp_client_tool/test_tool.py
Note: The test file remains at the legacy
FoundationaLLMAgentPluginslocation. It should be migrated tosrc/python/plugins/agent_core/test/to align with the new plugin directory structure.
Unit tests
Unit tests validate configuration parsing, transport override merging, synchronous/asynchronous execution paths, and artifact generation using mocked sessions.
Integration tests
An integration test exercises the Microsoft Learn MCP server when the MSLEARN_MCP_ENDPOINT environment variable is present. The test is skipped automatically when the endpoint is unavailable.
Running tests
pytest test/foundationallm_mcp_client_tool
Note: The integration test issues live requests; ensure the endpoint is reachable and stable before enabling it in automated pipelines.
Running the Microsoft Learn search integration test
To invoke the microsoft_docs_search tool with the query "How does Azure use Model Context Protocol (MCP)?", set the endpoint and run the targeted test:
$env:MSLEARN_MCP_ENDPOINT = "https://learn.microsoft.com/api/mcp"
pytest test/foundationallm_mcp_client_tool -k mslearn_docs_search -q
To also print request/response details to stdout, run the test in verbose mode:
$env:MSLEARN_MCP_ENDPOINT = "https://learn.microsoft.com/api/mcp"
pytest test/foundationallm_mcp_client_tool -k mslearn_docs_search -v -q
Showing print output
By default, pytest captures print output. To force printing to the console, add -s (disable capture). You can combine this with verbosity:
$env:MSLEARN_MCP_ENDPOINT = "https://learn.microsoft.com/api/mcp"
pytest test/foundationallm_mcp_client_tool -k mslearn_docs_search -vv -s
Relevant switches:
-k pattern: run tests matching the substring or expression (e.g.,mslearn_docs_search).-v: verbose mode. Shows each test node id as it runs, includes deselected/xfail/xpass summaries, and provides richer assertion diffs.-vv: very verbose. Everything from-v, plus longer/full test node ids (paths and parametrization), more fixture/collection details, and chattier progress output.-s: disable output capturing soprint()statements appear in real time.-q: quiet mode; reduces non-essential output (omit when you want more detail).
Alternative (logging instead of prints):
$env:MSLEARN_MCP_ENDPOINT = "https://learn.microsoft.com/api/mcp"
pytest test/foundationallm_mcp_client_tool -k mslearn_docs_search -vv -o log_cli=true -o log_cli_level=INFO
Agent prompt: Using the MCP Client Tool
Use this prompt snippet to guide the agent when working with MCP (Model Context Protocol) servers.
The MCP Client Tool provides a simplified interface where agents can delegate tool discovery, selection, and execution to the tool itself.
Primary Approach: Intelligent Execute
Use intelligent_execute for most scenarios - this allows the agent to provide a natural language prompt and let the MCP Client Tool handle:
- Discovering available tools on the MCP server
- Selecting appropriate tools based on the user's request
- Executing the tools with proper arguments
- Synthesizing results into a coherent response
Example Usage
{
"operation": "intelligent_execute",
"arguments": {
"prompt": "Search for information about Azure authentication best practices"
}
}
For Microsoft Learn MCP server, this would automatically:
- Discover the
microsoft_docs_searchtool - Execute the search with appropriate query parameters
- Synthesize the results into a comprehensive response
More Examples
{
"operation": "intelligent_execute",
"arguments": {
"prompt": "Find code samples for ASP.NET Core web API development"
}
}
{
"operation": "intelligent_execute",
"arguments": {
"prompt": "Get the latest documentation on Azure Functions deployment"
}
}
Manual Approach (Advanced)
When you need precise control over MCP operations, use the manual approach:
Discover Available Tools
{
"operation": "list_tools",
"arguments": {}
}
Call Specific Tools
{
"operation": "call_tool",
"arguments": {
"name": "tool_name",
"arguments": {
"param1": "value1",
"param2": "value2"
},
"read_timeout_seconds": 30
},
"response_format": "json"
}
Other Operations
{
"operation": "list_resources",
"arguments": {}
}
{
"operation": "read_resource",
"arguments": {
"uri": "resource://path/to/resource"
},
"read_timeout_seconds": 60
}
System Guidance for the Agent
- Prefer
intelligent_executefor most user requests - it handles complexity automatically - The MCP Client Tool requires top-level fields:
operationandarguments - For
intelligent_execute, simply provide a clear, descriptive prompt in thearguments.promptfield - Use manual operations only when you need specific control or when
intelligent_executedoesn't meet your needs - Use
response_format: "json"and set reasonable timeouts for long operations - Token tracking: The tool automatically tracks LLM token usage for
intelligent_executeoperations
Configuration Requirements
For intelligent_execute to work properly, ensure the tool is configured with:
- Main Model Resource: An LLM configured as
main_modelresource viaresource_object_ids - Main Prompt Resource: An orchestration prompt configured as
main_promptresource viaresource_object_ids
Answering Behavior
- Default to
intelligent_executefor user queries that involve MCP server interactions - Provide clear, descriptive prompts that specify what information the user is seeking
- Let the tool handle tool discovery and execution - don't manually discover tools unless necessary
- Present the synthesized results in a user-friendly format
- Include relevant metadata and links returned by the MCP server when appropriate