Overview
MCPManager is the one class handling the client side of MCP in Swarms. Point it at one or more servers and it takes care of transport selection, authentication, tool discovery, schema caching, and routing each tool call to the server that owns it.
Every Agent holds one as agent.mcp_manager. It is enabled when you set mcp_url, mcp_urls, mcp_config, or mcp_configs on the agent. You can also use it directly, with no agent involved.
MCPDeployer.
MCPManager works with mcp 1.28.1 and later, including the 2.x line, from swarms 15.0.1 onward. On 15.0.0 with mcp 2.x, failed tool calls were reported as successes; upgrade swarms.Import
MCPManager is also exported from swarms.tools.
Constructor
Settings passed here are defaults for every server. Credentials and OAuth only fill in servers that do not set their own;transport and timeout replace each server’s own value.
Union[str, MCPConnection, Dict]
A single server — URL string, connection object, or dict.
List[Union[str, MCPConnection, Dict]]
Several servers. Entries may mix forms, so different servers can use different authentication. Two entries with the same URL (or the same stdio command and args) are merged into one.
Union[MCPConnection, Dict]
Full configuration for one server.
List[Union[MCPConnection, Dict]]
Full configuration for several servers.
str
API key applied to every server that does not define its own. Sent as
Authorization: Bearer <key> unless the connection changes api_key_header or api_key_prefix.str
Bearer token applied to every server that does not define its own. Sent as
Authorization: Bearer <token> unless an API key already set the Authorization header.Union[MCPOAuthConfig, Dict]
OAuth 2.1 configuration applied to every server that does not define its own.
Dict[str, str]
Extra headers merged into every request. A server’s own
headers win on conflicts.str
default:"None"
Force
streamable_http, sse, stdio, or auto on every server. Hyphenated forms like streamable-http are normalized. When unset, each connection keeps its own transport, which defaults to streamable_http. See Transport.int
default:"None"
HTTP timeout in seconds, applied to every configured connection and replacing its own value. Left unset by default, so each connection keeps
MCPConnection.timeout, which defaults to 30. It does not bound how long a tool may run; that is MCPConnection.tool_timeout.str
default:"agent"
Name used in log messages.
bool
default:"false"
Log each discovery and tool call.
int
default:"3"
Attempts at listing a server’s tools before giving up, with a 1, 2, 4, … second backoff between them. Values below 1 become 1. Tool calls are not retried. An
Agent passes its tool_retry_attempts here.MCPConnection
swarms.schemas.mcp_schemas.MCPConnection configures one server. Pass it as mcp_url, mcp_config, or an entry in mcp_urls / mcp_configs, on the manager or on an Agent. A dict with the same keys works too.
api_key, authorization_token, the OAuth access_token, client_id, client_secret and token_url, and stdio env values accept "env:NAME" or "${NAME}" and are read from the environment when the connection is made. headers values are sent as written.
Transport
Connections default tostreamable_http, whatever the URL looks like. Set transport="sse" for an SSE server, or transport="auto" to choose from the URL: a URL ending in /sse uses SSE and anything else uses streamable HTTP. A URL without http:// or https:// is rejected, never run as a command. Only a connection with command uses stdio. The stdio server process does not inherit your environment: it gets HOME, PATH, SHELL, TERM, USER and LOGNAME, plus the variables in env, so pass any key the server needs there.
Discovery
get_tools
force_refresh=True to re-fetch.
AgentMCPConnectionError is raised only when no tools could be loaded and at least one server failed.
Async form: await manager.aget_tools(...).
Only the default
"openai" format fills the cache and the tool-to-server routing table. call_tool and execute_tool_calls fetch the OpenAI schemas themselves when that table is empty, so routing works whichever format you listed with.list_tool_names
Execution
call_tool
is_error is True when the server reports the tool failed; result then holds the server’s error text. When the call itself fails on the client side, the envelope has an error string instead of result.
With several servers, an unknown name raises AgentMCPToolError. With one server, every name is sent to it and the server reports unknown tools. A server that cannot be reached raises AgentMCPConnectionError.
Async form: await manager.acall_tool(...).
execute_tool_calls
Agent performs between LLM turns.
Any
required
An LLM response: a JSON string, one tool call, a list of tool calls, or a whole assistant message with
tool_calls, as dicts or SDK objects."dict" | "json" | "str"
default:"dict"
Result format: the list of envelopes, that list as a JSON string, or one
tool @ server -> result line per call.is_error: True and an error string, so one bad call cannot abort a batch. A response with no tool calls returns [] ("[]" for json). With no servers configured, it raises AgentMCPConnectionError.
Async form: await manager.aexecute_tool_calls(...). To re-render results you already hold, use the static MCPManager.format_results(results, output_type).
What result holds
result is a native Python value; swarms never encodes it:
Most servers,
MCPDeployer included, send dicts and numbers as JSON text, so a str result may itself be JSON. Check the type before parsing:
Configuration management
Authentication
OAuth 2.1
MCPOAuthConfig supports three modes:
- Authorization code (
grant_type="authorization_code", the default). The interactive browser flow with PKCE, run by themcpSDK, which discovers the endpoints and registers the client dynamically (RFC 7591). A loopback listener onredirect_uri(defaulthttp://127.0.0.1:8765/callback) catches the redirect, and tokens are cached in~/.swarms/mcp_auth/<server>.jsonwith0600permissions, so the browser step runs once. - Client credentials (
grant_type="client_credentials"). Headless. Needsclient_id, and usuallyclient_secret. The token endpoint is discovered from the server’s well-known metadata unlesstoken_urlis set, and a new token is fetched shortly before the old one expires. - Pre-issued token (
access_token="..."). No flow runs; the token is sent as a bearer credential.
scopes, client_name (default "Swarms Agent") and client_uri for registration, token_storage_path, use_token_cache (default True; False keeps tokens in memory only), open_browser (default True; False logs the URL instead), and callback_timeout (default 300 seconds).
MCPFileTokenStorage, exported from swarms.tools, is the on-disk token cache. Call .clear() on one to force a fresh authorization.
Mixed auth across servers
Errors
All live in
swarms.schemas.agent_mcp_errors. Tool discovery retries up to retry_attempts times before raising.
Failures during execute_tool_calls are never raised; they come back as is_error: True envelopes. call_tool also returns an envelope when the tool itself fails.
With
mcp 2.x, an HTTP error from the server, including 401, reaches the client as Server returned an error response; the status code is not available. Check the server’s own logs to see why a request was refused.Migration
The standalone functions inswarms.tools.mcp_client_tools were removed once everything moved onto this class.
Two behavioral differences to be aware of:
output_typeon tool fetching is gone.get_tools_for_multiple_mcp_serversaccepted the argument but never applied it. Useformat="openai" | "mcp"to pick the schema shape.- Execution results are wrapped. The old functions returned the raw MCP
CallToolResultdump.execute_tool_callsreturns one envelope per call, so results from several servers stay attributable. Readresult["result"]for the tool’s own payload.
Related
MCP Integration
Using MCP servers from an agent
Agent
Set
mcp_url / mcp_urls to wire this in automaticallyMCPDeployer
Serve an agent or swarm as an MCP server
Authentication patterns
Every credential shape, with code