How to Use Model Context Protocol (MCP) with MCPStdioTool and MCPStreamableHTTPTool in Agent Framework
The Microsoft Agent Framework treats MCP servers as attachable tools, enabling agents to discover and invoke remote functions through either local STDIO processes via MCPStdioTool or HTTP endpoints via MCPStreamableHTTPTool.
The Model Context Protocol (MCP) provides a standardized interface for AI agents to interact with external data sources and services. According to the microsoft/agent-framework source code, the integration resides in python/packages/core/agent_framework/_mcp.py, where the abstract MCPTool class manages the MCP lifecycle and two concrete implementations handle different transport mechanisms. This guide demonstrates how to instantiate these tools, manage connections with async context managers, and authenticate HTTP requests.
Architecture of MCP Integration
The MCP implementation in the Agent Framework follows a layered architecture that abstracts transport details while exposing a unified interface to agents.
The MCPTool Base Class
The MCPTool class serves as the foundation for all MCP integrations in _mcp.py. It handles session management, automatic reconnection, and the conversion of remote MCP functions into local FunctionTool objects that agents can invoke.
Key methods include:
connect()– Establishes the client transport and opens aClientSessionwith the MCP serverload_tools()andload_prompts()– Query the server for available capabilities and wrap them as callable functionscall_tool()– Forwards invocations to the remote server, injects OpenTelemetry metadata, and handles response parsing__aenter__/__aexit__– Enable use as an async context manager for automatic connection cleanup
MCPStdioTool Implementation
Located at line 1244 of _mcp.py, MCPStdioTool wraps the stdio_client from the official MCP SDK. It spawns a local subprocess defined by a command and argument list, communicating over standard input/output streams. This approach is ideal for local development or when running self-contained MCP executables.
MCPStreamableHTTPTool Implementation
Starting at line 1380 of _mcp.py, MCPStreamableHTTPTool utilizes streamable_http_client for connecting to hosted MCP services. It supports custom HTTP header injection through a header_provider callback, which receives runtime kwargs and returns headers for authentication or request signing. The class uses a ContextVar to propagate these headers into the underlying HTTP transport during tool invocation.
Using MCPStdioTool for Local Subprocess Servers
MCPStdioTool is the optimal choice when your MCP server runs as a local command-line executable, such as the official filesystem server or custom Python scripts.
The class accepts command and args parameters that define how to spawn the subprocess. When wrapped in an async context manager, it automatically starts the server, discovers available functions, and cleans up the process on exit.
from agent_framework import Agent, MCPStdioTool
from agent_framework.openai import OpenAIChatClient
async def demo_stdio():
# Initialize the tool with server command details
mcp_tool = MCPStdioTool(
name="filesystem",
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
description="File-system operations via MCP",
)
# Context manager handles connection lifecycle
async with mcp_tool:
agent = Agent(
client=OpenAIChatClient(),
name="DocsAgent",
instructions="You are a helpful assistant that can read/write files.",
tools=mcp_tool, # All discovered functions become available
)
# Agent automatically calls remote MCP functions
result = await agent.run("List the files in the current directory")
print(result)
# asyncio.run(demo_stdio())
Key implementation details:
- The tool spawns the process defined by
commandandargsupon entering the context manager - All functions exposed by the MCP server (e.g.,
list_files,read_file) are automatically loaded viaload_tools() - Connection errors trigger automatic reconnection attempts through the base class logic
Using MCPStreamableHTTPTool for HTTP Endpoints
For cloud-hosted MCP services or microservices architectures, MCPStreamableHTTPTool provides HTTP-based connectivity with support for dynamic authentication headers.
The header_provider callback enables per-request customization of HTTP headers. It receives the runtime kwargs from the agent invocation and returns a dictionary of headers, allowing you to inject bearer tokens, API keys, or correlation IDs.
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.openai import OpenAIChatClient
def auth_header_provider(kwargs: dict) -> dict[str, str]:
"""Dynamically generate headers for each tool call."""
token = kwargs.get("auth_token", "unknown")
return {"Authorization": f"Bearer {token}"}
async def demo_http():
mcp_tool = MCPStreamableHTTPTool(
name="learn-mcp",
url="https://learn.microsoft.com/api/mcp",
description="Microsoft Learn MCP endpoint",
header_provider=auth_header_provider, # Called on every invocation
)
async with mcp_tool:
agent = Agent(
client=OpenAIChatClient(),
name="LearnAgent",
instructions="You can query Microsoft Learn content via the MCP endpoint.",
tools=mcp_tool,
)
# Pass runtime kwargs that header_provider can access
result = await agent.run(
"What is the latest version of the Agent Framework?",
stream=False,
)
print(result)
# asyncio.run(demo_http())
Implementation specifics:
- Headers returned by
header_providerare temporarily stored in aContextVar(_mcp_call_headers) during the request lifecycle - The overridden
call_toolmethod injects these headers into the HTTP transport before delegating to the base implementation - You can provide a custom
httpx.AsyncClientvia the constructor, or let the tool create one automatically
For a complete end-to-end example, see python/samples/02-agents/providers/openai/client_with_local_mcp.py in the repository, which demonstrates streaming responses with MCPStreamableHTTPTool.
Selecting the Right Transport Protocol
Choose between STDIO and HTTP transports based on your deployment environment and security requirements.
-
Use
MCPStdioToolwhen running local development servers, packaged CLI tools, or when network egress is restricted. The subprocess model provides isolation but requires the executable to be present on the local filesystem. -
Use
MCPStreamableHTTPToolwhen integrating with SaaS platforms, microservices, or geographically distributed teams. The HTTP transport supports load balancing and requires no local dependencies beyond network access, though you must implementheader_providerfor authentication.
Both classes are exported publicly from agent_framework/__init__.py, making them available as top-level imports.
Summary
MCPToolin_mcp.pyprovides the abstract foundation for MCP integration, handling session lifecycle and tool discoveryMCPStdioTool(line 1244) connects to local subprocesses via STDIO, ideal for command-line MCP serversMCPStreamableHTTPTool(line 1380) connects to HTTP endpoints and supports dynamic headers viaheader_provider- Both implementations work as async context managers, ensuring proper connection cleanup
- The framework automatically converts remote MCP functions into
FunctionToolobjects that agents invoke through standardagent.run()calls
Frequently Asked Questions
What is the difference between MCPStdioTool and MCPStreamableHTTPTool?
MCPStdioTool spawns a local subprocess and communicates over standard input/output streams, making it suitable for local executables like the filesystem server. MCPStreamableHTTPTool connects to remote HTTP endpoints using the streamable_http_client transport, designed for cloud-hosted MCP services that require network connectivity.
How do I authenticate requests with MCPStreamableHTTPTool?
Supply a header_provider callback function that receives the runtime kwargs from the agent invocation and returns a dictionary of HTTP headers. The tool injects these headers into every request through a ContextVar mechanism, enabling dynamic token injection without global state.
Can I use multiple MCP tools with a single Agent?
Yes. The Agent's tools parameter accepts a list, allowing you to pass multiple MCPTool instances simultaneously. Each tool establishes its own connection and registers its discovered functions, enabling agents to call functions across different MCP servers within the same conversation.
What happens if the MCP server disconnects during execution?
The base MCPTool class implements automatic reconnection logic. If the connection drops, the framework attempts to re-establish the session before failing the tool call, ensuring resilience against transient network issues or subprocess restarts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →