Skip to content
Cloudflare Docs

McpClient — API reference

Your Agent can connect to external Model Context Protocol (MCP) servers to access tools, resources, and prompts. The Agent class provides three methods to manage MCP connections.

MCPConnectionState Enum

The MCPConnectionState enum defines the possible states of an MCP server connection:

TypeScript
import { MCPConnectionState } from "agents";
MCPConnectionState.AUTHENTICATING // "authenticating" - Waiting for OAuth authorization
MCPConnectionState.CONNECTING // "connecting" - Establishing transport connection
MCPConnectionState.DISCOVERING // "discovering" - Discovering server capabilities
MCPConnectionState.READY // "ready" - Fully connected and ready to use
MCPConnectionState.FAILED // "failed" - Connection failed

The connection state machine follows these transitions:

  • Non-OAuth flow: CONNECTINGDISCOVERINGREADY
  • OAuth flow: AUTHENTICATING → (callback) → CONNECTINGDISCOVERINGREADY
  • Error: Any state can transition to FAILED on error

Use these constants instead of string literals when checking connection states.

Migration from String Literals

If you were previously using string literals to check connection states, update your code to use the enum:

JavaScript
// Old approach with string literals
if (server.state === "ready") {
console.log("Server is ready");
}

Agent MCP Client Methods Example

JavaScript
import { Agent } from "agents";
export class MyAgent extends Agent {
async onRequest(request) {
const url = new URL(request.url);
if (url.pathname === "/connect" && request.method === "POST") {
const { id, authUrl } = await this.addMcpServer(
"Weather API",
"https://weather-mcp.example.com/mcp",
);
if (authUrl) {
return new Response(JSON.stringify({ authUrl }), {
headers: { "Content-Type": "application/json" },
});
}
return new Response(`Connected: ${id}`, { status: 200 });
}
}
}

Connections persist in the Agent's SQL storage, and when an Agent connects to an MCP server, all tools from that server become available automatically.

Agent MCP Client Methods

addMcpServer()

Add a connection to an MCP server and make its tools available to your Agent.

TypeScript
async addMcpServer(
serverName: string,
url: string,
callbackHost?: string,
agentsPrefix?: string,
options?: {
client?: ConstructorParameters<typeof Client>[1];
transport?: {
headers?: HeadersInit;
type?: "sse" | "streamable-http" | "auto";
};
}
): Promise<{ id: string; authUrl: string | undefined }>

Parameters

  • serverName (string, required) — Display name for the MCP server
  • url (string, required) — URL of the MCP server endpoint
  • callbackHost (string, optional) — Host for OAuth callback URL. If omitted, automatically derived from the incoming request
  • agentsPrefix (string, optional) — URL prefix for OAuth callback path. Default: "agents"
  • options (object, optional) — Connection configuration:
    • client — MCP client configuration options (passed to @modelcontextprotocol/sdk Client constructor). By default, includes CfWorkerJsonSchemaValidator for validating tool parameters against JSON schemas.
    • transport — Transport layer configuration:
      • headers — Custom HTTP headers for authentication
      • type — Transport type: "sse", "streamable-http", or "auto" (tries streamable-http first, falls back to sse)

Returns

A Promise that resolves to an object containing:

  • id (string) — Unique identifier for this server connection
  • authUrl (string | undefined) — OAuth authorization URL if authentication is required, otherwise undefined

Example

JavaScript
export class MyAgent extends Agent {
async onRequest(request) {
const { id, authUrl } = await this.addMcpServer(
"Weather API",
"https://weather-mcp.example.com/mcp",
);
if (authUrl) {
// User needs to complete OAuth flow
return new Response(JSON.stringify({ serverId: id, authUrl }), {
headers: { "Content-Type": "application/json" },
});
}
return new Response("Connected", { status: 200 });
}
}

If the MCP server requires OAuth authentication, authUrl will be returned for user authentication. Connections persist across requests and the Agent will automatically reconnect if the connection is lost.

Related:

removeMcpServer()

Disconnect from an MCP server and clean up its resources.

TypeScript
async removeMcpServer(id: string): Promise<void>

Parameters

  • id (string, required) — Server connection ID returned from addMcpServer()

Returns

A Promise that resolves when disconnection is complete.

Example

JavaScript
export class MyAgent extends Agent {
async onRequest(request) {
const url = new URL(request.url);
if (url.pathname === "/disconnect" && request.method === "POST") {
const { serverId } = await request.json();
await this.removeMcpServer(serverId);
return new Response("Disconnected", { status: 200 });
}
}
}

Disconnects from the MCP server, removes all related resources, and deletes the server record from storage.

getMcpServers()

Get the current state of all MCP server connections.

TypeScript
getMcpServers(): MCPServersState

Parameters

None.

Returns

An MCPServersState object containing:

TypeScript
import { MCPConnectionState } from "agents";
{
servers: Record<
string,
{
name: string;
server_url: string;
auth_url: string | null;
state: MCPConnectionState;
capabilities: ServerCapabilities | null;
instructions: string | null;
}
>;
tools: Array<Tool & { serverId: string }>;
prompts: Array<Prompt & { serverId: string }>;
resources: Array<Resource & { serverId: string }>;
}

Example

JavaScript
export class MyAgent extends Agent {
async onRequest(request) {
const url = new URL(request.url);
if (url.pathname === "/mcp-state") {
const mcpState = this.getMcpServers();
return new Response(JSON.stringify(mcpState, null, 2), {
headers: { "Content-Type": "application/json" },
});
}
}
}

Use this method to monitor connection status, list available tools, or build UI for connected servers. Check the connection state using the MCPConnectionState enum:

JavaScript
import { MCPConnectionState } from "agents";
export class MyAgent extends Agent {
async onRequest(request) {
const mcpState = this.getMcpServers();
for (const [id, server] of Object.entries(mcpState.servers)) {
if (server.state === MCPConnectionState.READY) {
console.log(`Server ${id} is ready`);
} else if (server.state === MCPConnectionState.AUTHENTICATING) {
console.log(`Server ${id} needs authentication`);
}
}
return new Response("OK");
}
}

OAuth Configuration

Customize OAuth callback behavior using this.mcp.configureOAuthCallback():

JavaScript
export class MyAgent extends Agent {
onStart() {
this.mcp.configureOAuthCallback({
successRedirect: "/connected",
errorRedirect: "/auth-failed",
});
}
}

You can also provide a customHandler function for full control over the callback response. Refer to the OAuth handling guide for details.

Error Handling

Use error detection utilities to handle connection errors:

JavaScript
import { isUnauthorized, isTransportNotImplemented } from "agents/mcp";
export class MyAgent extends Agent {
async onRequest(request) {
try {
await this.addMcpServer("Server", "https://mcp.example.com/mcp");
} catch (error) {
if (isUnauthorized(error)) {
return new Response("Authentication required", { status: 401 });
} else if (isTransportNotImplemented(error)) {
return new Response("Transport not supported", { status: 400 });
}
throw error;
}
}
}

Next Steps