Use this file to discover all available pages before exploring further.
Connect your agent to external MCP (Model Context Protocol) servers to use their tools, resources, and prompts. This enables your agent to interact with GitHub, Slack, databases, and other services through a standardized protocol.
import { Agent } from "agents";export class MyAgent extends Agent { async onRequest(request: Request) { // Add an MCP server const result = await this.addMcpServer( "github", "https://mcp.github.com/mcp" ); if (result.state === "authenticating") { // Server requires OAuth - redirect user to authorize return Response.redirect(result.authUrl); } // Server is ready - tools are now available const state = this.getMcpServers(); console.log(`Connected! ${state.tools.length} tools available`); return new Response("MCP server connected"); }}
These options are persisted and used when reconnecting after hibernation or after OAuth completion. Default: 3 attempts, 500ms base delay, 5s max delay.
For example: https://my-worker.workers.dev/agents/my-agent/default/callbackOAuth tokens are securely stored in SQLite and persist across agent restarts.
By default, agents use dynamic client registration to authenticate with MCP servers. If you need to use a different OAuth strategy — such as pre-registered client credentials, mTLS-based authentication, or other mechanisms — override the createMcpOAuthProvider method in your agent subclass:
import { Agent } from "agents";import type { AgentMcpOAuthProvider } from "agents";class MyAgent extends Agent { createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider { return new MyCustomOAuthProvider(this.ctx.storage, this.name, callbackUrl); }}
Your custom class must implement the AgentMcpOAuthProvider interface, which extends the MCP SDK’s OAuthClientProvider with additional properties (authUrl, clientId, serverId) and methods (checkState, consumeState, deleteCodeVerifier) used by the agent’s MCP connection lifecycle.
The most common customization is using a different storage backend while keeping the built-in OAuth logic (CSRF state, PKCE, nonce generation, token management). Import DurableObjectOAuthClientProvider and pass your own storage adapter:
import { Agent, DurableObjectOAuthClientProvider } from "agents";import type { AgentMcpOAuthProvider } from "agents";class MyAgent extends Agent { createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider { return new DurableObjectOAuthClientProvider( myCustomStorage, // any DurableObjectStorage-compatible adapter this.name, callbackUrl ); }}
const state = this.getMcpServers();// All tools from all connected serversfor (const tool of state.tools) { console.log(`Tool: ${tool.name}`); console.log(` From server: ${tool.serverId}`); console.log(` Description: ${tool.description}`);}
const state = this.getMcpServers();// Available resourcesfor (const resource of state.resources) { console.log(`Resource: ${resource.name} (${resource.uri})`);}// Available promptsfor (const prompt of state.prompts) { console.log(`Prompt: ${prompt.name}`);}
// Listen for state changes (onServerStateChanged is an Event<void>)const disposable = this.mcp.onServerStateChanged(() => { console.log("MCP server state changed"); this.broadcastMcpServers(); // Notify connected clients});// Clean up the subscription when no longer needed// disposable.dispose();
After hibernation or when connections are being restored in the background, MCP tools may not be immediately available. Use waitForConnections() to wait until all in-flight connection and discovery operations have settled:
// Wait indefinitely for all connections to be readyawait this.mcp.waitForConnections();// Wait with a timeout (in milliseconds)await this.mcp.waitForConnections({ timeout: 10_000 });
This is useful when you need to call this.mcp.getAITools() immediately after the agent wakes from hibernation. Without waiting, tools from servers that are still reconnecting will be missing.
AIChatAgent handles this automatically via the waitForMcpConnections property (defaults to { timeout: 10_000 }). You only need waitForConnections() directly when using Agent with MCP, or when you want finer control inside onChatMessage.
Add and connect to an MCP server. Throws if connection or discovery fails.For non-OAuth servers, callbackHost is not required — you can call addMcpServer("name", url) with no options. For RPC transport, pass a DurableObjectNamespace binding instead of a URL. See MCP Transports for details.
Calling addMcpServer is idempotent when both the server name and URL match an existing active connection — the existing connection is returned without creating a duplicate. This makes it safe to call in onStart() without worrying about duplicate connections on restart.If you call addMcpServer with the same name but a different URL, a new connection is created. Both connections remain active and their tools are merged in getAITools(). To replace a server, call removeMcpServer(oldId) first.URLs are normalized before comparison (trailing slashes, default ports, and hostname case are handled), so https://MCP.Example.com and https://mcp.example.com/ are treated as the same URL.