symfonic.tools.mcp¶
mcp ¶
symfonic.tools.mcp -- MCP (Model Context Protocol) server adapter.
Provides: - MCPToolDefinition / MCPToolResult -- frozen dataclass models - MCPServerConnection -- structural Protocol (runtime_checkable) - JSONRPCMCPConnection -- HTTP JSON-RPC 2.0 transport (requires httpx) - MCPToolProvider -- discovery + routing bridge to LangChain
JSONRPCMCPConnection ¶
MCP server connection via JSON-RPC 2.0 over HTTP.
Implements the MCP wire protocol: - tools/list — discover available tools - tools/call — invoke a tool by name
Requires httpx::
pip install symfonic-core[mcp]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_url
|
str
|
Full HTTP(S) URL to the MCP server endpoint. |
required |
Example::
conn = JSONRPCMCPConnection("http://localhost:3000/mcp")
tools = await conn.list_tools()
result = await conn.call_tool("search", {"query": "force majeure"})
Source code in src/symfonic/tools/mcp/provider.py
call_tool
async
¶
Send tools/call request and return parsed result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool to invoke. |
required |
arguments
|
dict[str, Any]
|
Arguments matching the tool's input schema. |
required |
Returns:
| Type | Description |
|---|---|
MCPToolResult
|
MCPToolResult with concatenated text content from the response. |
Source code in src/symfonic/tools/mcp/provider.py
close
async
¶
Release connection state and close the pooled HTTP client.
Source code in src/symfonic/tools/mcp/provider.py
list_tools
async
¶
Send tools/list request and parse response.
Returns:
| Type | Description |
|---|---|
list[MCPToolDefinition]
|
List of MCPToolDefinition objects for each tool the server exposes. |
Source code in src/symfonic/tools/mcp/provider.py
MCPServerConnection ¶
Bases: Protocol
Abstract interface for connecting to MCP servers.
Any object that implements list_tools, call_tool, and close
with the correct signatures satisfies this protocol via structural
subtyping — no inheritance required.
Example::
class MyConnection:
async def list_tools(self) -> list[MCPToolDefinition]: ...
async def call_tool(self, tool_name, arguments) -> MCPToolResult: ...
async def close(self) -> None: ...
assert isinstance(MyConnection(), MCPServerConnection)
call_tool
async
¶
Execute a tool on the server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool to invoke. |
required |
arguments
|
dict[str, Any]
|
Key-value arguments matching the tool's input schema. |
required |
Returns:
| Type | Description |
|---|---|
MCPToolResult
|
MCPToolResult with the server's response content. |
Source code in src/symfonic/tools/mcp/protocol.py
close
async
¶
list_tools
async
¶
Discover available tools from the server.
Returns:
| Type | Description |
|---|---|
list[MCPToolDefinition]
|
List of tool definitions reported by the MCP server. |
MCPToolDefinition
dataclass
¶
MCPToolDefinition(
name: str,
description: str,
input_schema: dict[str, Any] = dict(),
server_url: str = "",
)
A tool discovered from an MCP server.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique tool identifier as reported by the server. |
description |
str
|
Human-readable description of what the tool does. |
input_schema |
dict[str, Any]
|
JSON Schema object describing accepted arguments. |
server_url |
str
|
URL of the MCP server that owns this tool. |
MCPToolProvider ¶
Bridge that connects to MCP servers and provides LangChain-compatible tools.
Registers one or more MCPServerConnection instances, discovers their tools, and routes tool calls to the correct server.
Usage::
provider = MCPToolProvider()
provider.add_server("legal", JSONRPCMCPConnection("http://localhost:3000"))
definitions = await provider.discover_tools()
lc_tools = provider.to_langchain_tools()
# Later, invoke a tool directly:
result = await provider.call_tool("search", {"query": "breach of contract"})
# Cleanup:
await provider.close_all()
Source code in src/symfonic/tools/mcp/provider.py
add_server ¶
Register an MCP server connection under a logical name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Logical label for this server (used in log messages). |
required |
connection
|
MCPServerConnection
|
Any object satisfying MCPServerConnection protocol. |
required |
Source code in src/symfonic/tools/mcp/provider.py
call_tool
async
¶
Execute a previously discovered tool by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the tool to invoke. |
required |
arguments
|
dict[str, Any]
|
Arguments to pass to the tool. |
required |
Returns:
| Type | Description |
|---|---|
MCPToolResult
|
MCPToolResult. If |
MCPToolResult
|
error result without raising. |
Source code in src/symfonic/tools/mcp/provider.py
close_all
async
¶
Close all registered server connections.
discover_tools
async
¶
Discover all tools from all registered servers.
Failed servers are skipped with a warning — partial discovery is preferred over a hard failure when one server is unavailable.
Returns:
| Type | Description |
|---|---|
list[MCPToolDefinition]
|
Flat list of MCPToolDefinition from all reachable servers. |
Source code in src/symfonic/tools/mcp/provider.py
to_langchain_tools ¶
Convert discovered MCP tools to LangChain StructuredTools.
Each tool's name and description from the MCP server are mapped
to the StructuredTool. Invocations are delegated back through
MCPToolProvider.call_tool.
Returns:
| Type | Description |
|---|---|
list[Any]
|
List of LangChain StructuredTool instances, or an empty list |
list[Any]
|
if langchain-core is not installed. |
Source code in src/symfonic/tools/mcp/provider.py
MCPToolResult
dataclass
¶
MCPToolResult(
tool_name: str,
content: str,
is_error: bool = False,
metadata: dict[str, Any] = dict(),
)
Result from executing an MCP tool.
Attributes:
| Name | Type | Description |
|---|---|---|
tool_name |
str
|
Name of the tool that was called. |
content |
str
|
Text content returned by the tool. |
is_error |
bool
|
True when the server reported an error response. |
metadata |
dict[str, Any]
|
Optional extra data from the server response. |