MCPAdapter discovers MCP tools and keeps their connections open so your agent can reuse them across calls. Discover tools with listTools() or listToolsets(), and close the adapter when your application finishes using them.
Choose how long to keep the adapter open:
See Transports for each server’s connection options.
Connection lifecycle
Constructing an adapter validates its configuration without opening connections.listTools(), listToolsets(), getClient(), and the resource methods connect when they run discovery. Keep the adapter open while your agent uses those tools.
To discover tools, run an agent, and release the connections, pass your MCP server’s HTTP URL to runAgent:
close() aborts in-flight adapter work, closes its connections, and clears its caches. You can call listTools() again to open fresh connections, but use the newly returned tools. Previously returned tools retain their closed clients.
Multiple servers
Each named entry inservers gets its own connection, authentication, and protocol mode. One adapter can connect to both HTTP and stdio servers.
To discover tools from both transports, pass a calendar server’s HTTP URL and a files server’s script path to listServerTools:
listToolsets() groups tools by server name. listTools() returns one array; pass a server name or an array of names to select which tools it returns. Selection filters the result, but discovery still contacts every configured server. A failure on an unselected server can fail the call.
The adapter prefixes tool names with their server name by default, such as calendar__search and files__search. Set prefixToolNameWithServerName: false to keep raw names. listTools() throws if its selected tools contain duplicate names.
OpenAI and Anthropic accept only letters, digits, _, and - in tool names (^[a-zA-Z0-9_-]+$), up to 64 characters for OpenAI and 128 for Anthropic. The adapter does not rename a prefixed name that breaks these limits, so keep server names short and free of dots and spaces.
Set defaultToolTimeout (in milliseconds) at the top level to apply it to every server’s tools; it wins over a server’s own defaultToolTimeout.
Scale a deployment
Create the adapter at module scope, outside the graph factory. Each factory call can discover the current tool catalog and build an agent using the shared connections:onConnectionError: "ignore", or provide a callback that returns normally, to continue with the remaining servers. Non-authentication failures keep that connection skipped on later discoveries, even with cacheMode: "refresh". Close the adapter to clear skipped connections before discovering again. Authentication failures are retried on the next discovery.
Stdio servers support restart settings, and HTTP and SSE servers support reconnect settings when configured with mode: "legacy". After a restart, call listTools() again and use the returned tools; tools returned before the restart keep the closed connection.
Modern MCP servers keep no session, so their replicas can run behind any load balancer. A sessionful legacy server still needs sticky routing to one replica. A modern server that runs several replicas must share one requestState signing key across them, or an elicitation answer that reaches a different replica is rejected. See Protect requestState with the codec in the MCP TypeScript SDK documentation.
Caching
The MCP SDK provides an in-memory cache for tool lists. Repeated discovery avoids a network request while the server’sttlMs hint remains valid. Without a positive ttlMs, discovery fetches the list again.
Use cacheMode to control how listTools() and listToolsets() read the response cache:
"use"(the default): Serve a valid cached tool list when one is available, otherwise fetch and store it."refresh": Fetch a fresh tool list and update the cache."bypass": Fetch a fresh tool list without reading or updating the response cache.
Protocol eras
The adapter negotiates the MCP protocol separately for each server. The defaultmode: "auto" supports modern and legacy servers in the same adapter.
The legacy era starts with an initialize handshake. The modern era uses server/discover to discover server capabilities. Override mode when you need to require a specific era:
mode controls its negotiation independently:
"auto"(the default): Try the current protocol and fall back for a legacy-only server."modern": Require protocol version2026-07-28and fail instead of using legacy MCP."legacy": Skip modern probing and use the legacy client interface.
"auto" mode, a URL server that answers the Streamable HTTP request with 404 or 405 is retried over SSE, at the same URL and then with a trailing /mcp replaced by /sse. In "legacy" mode, any 4xx falls back unless automaticSSEFallback: false.
setLoggingLevel() is legacy-only and throws when a connected server negotiated the modern protocol; set logLevel on each modern server instead.
See also
- Authentication: Bearer, OAuth, and per-user credentials.
- Human-in-the-loop: Pause and resume tool calls.
- MCP specification
Connect these docs to your agent of choice via MCP for real-time answers.

