docs/docs/learn/programming/mcp.md
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to language models. DSPy supports MCP, allowing you to use tools from any MCP server with DSPy agents.
Install DSPy with MCP support:
pip install -U "dspy[mcp]"
MCP enables you to:
DSPy does not handle MCP server connections directly. Use a client interface from the mcp library, then pass the client or session to dspy.Tool.from_mcp_tool. DSPy supports both major versions of the mcp Python SDK.
With mcp SDK v2, use the high-level Client for a remote server:
import asyncio
import dspy
from mcp.client import Client
async def main():
async with Client("http://localhost:8000/mcp") as client:
response = await client.list_tools()
dspy_tools = [dspy.Tool.from_mcp_tool(client, tool) for tool in response.tools]
asyncio.run(main())
With SDK v1, use the streamable HTTP transport and a ClientSession:
import asyncio
import dspy
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
# Connect to HTTP MCP server
async with streamablehttp_client("http://localhost:8000/mcp") as (read, write):
async with ClientSession(read, write) as session:
# Initialize the session
await session.initialize()
# List and convert tools
response = await session.list_tools()
dspy_tools = [
dspy.Tool.from_mcp_tool(session, tool)
for tool in response.tools
]
# Create and use ReAct agent
class TaskSignature(dspy.Signature):
task: str = dspy.InputField()
result: str = dspy.OutputField()
react_agent = dspy.ReAct(
signature=TaskSignature,
tools=dspy_tools,
max_iters=5
)
result = await react_agent.acall(task="Check the weather in Tokyo")
print(result.result)
asyncio.run(main())
The most common way to use MCP is with a local server process communicating via stdio. This example works with both SDK versions:
import asyncio
import dspy
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
# Configure the stdio server
server_params = StdioServerParameters(
command="python", # Command to run
args=["path/to/your/mcp_server.py"], # Server script path
env=None, # Optional environment variables
)
# Connect to the server
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the session
await session.initialize()
# List available tools
response = await session.list_tools()
# Convert MCP tools to DSPy tools
dspy_tools = [
dspy.Tool.from_mcp_tool(session, tool)
for tool in response.tools
]
# Create a ReAct agent with the tools
class QuestionAnswer(dspy.Signature):
"""Answer questions using available tools."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
react_agent = dspy.ReAct(
signature=QuestionAnswer,
tools=dspy_tools,
max_iters=5
)
# Use the agent
result = await react_agent.acall(
question="What is 25 + 17?"
)
print(result.answer)
# Run the async function
asyncio.run(main())
DSPy automatically handles the conversion from MCP tools to DSPy tools:
# MCP tool from session
mcp_tool = response.tools[0]
# Convert to DSPy tool
dspy_tool = dspy.Tool.from_mcp_tool(session, mcp_tool)
# The DSPy tool preserves:
# - Tool name and description
# - Parameter schemas and types
# - Argument descriptions
# - Async execution support
# Use it like any DSPy tool
result = await dspy_tool.acall(param1="value", param2=123)
By default, MCP tools return the content field. Pass result_mode="structured" to dspy.Tool.from_mcp_tool to return structuredContent when available; if it is absent, DSPy falls back to the default conversion.
MCP integration in DSPy makes it easy to use standardized tools from any MCP server, enabling powerful agent capabilities with minimal setup.