> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/cloudflare/agents/llms.txt
> Use this file to discover all available pages before exploring further.

# McpAgent

> Base class for building MCP (Model Context Protocol) servers

## Overview

`McpAgent` extends the `Agent` class to provide a foundation for building MCP servers. It handles transport initialization, session management, and client communication.

```typescript theme={null}
import { McpAgent } from "agents/mcp";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";

class MyMcpServer extends McpAgent {
  server = new Server({
    name: "my-mcp-server",
    version: "1.0.0"
  }, {
    capabilities: {
      tools: {}
    }
  });

  async init() {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: "get_weather",
          description: "Get weather for a location",
          inputSchema: {
            type: "object",
            properties: {
              location: { type: "string" }
            }
          }
        }
      ]
    }));
  }
}
```

## Type Parameters

<ParamField path="Env" type="Cloudflare.Env" default="Cloudflare.Env">
  Environment type containing bindings
</ParamField>

<ParamField path="State" type="unknown" default="unknown">
  State type for the Agent
</ParamField>

<ParamField path="Props" type="Record<string, unknown>" default="Record<string, unknown>">
  Props passed to the Agent
</ParamField>

## Abstract Members

### server

<ResponseField name="server" type="MaybePromise<McpServer | Server>" required>
  The MCP server instance. Can be a Server or McpServer from the MCP SDK.

  ```typescript theme={null}
  server = new Server({
    name: "my-server",
    version: "1.0.0"
  }, {
    capabilities: { tools: {}, prompts: {}, resources: {} }
  });
  ```
</ResponseField>

### init()

<ResponseField name="init" type="() => Promise<void>" required>
  Initialize the MCP server. Called on Agent start. Set up request handlers here.

  ```typescript theme={null}
  async init() {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [/* ... */]
    }));
  }
  ```
</ResponseField>

## Methods

### elicitInput()

Request user input with a message and schema (elicitation protocol).

<ParamField path="params" type="ElicitInputParams" required>
  <ParamField path="message" type="string" required>
    Message to show the user
  </ParamField>

  <ParamField path="requestedSchema" type="unknown" required>
    JSON schema for the expected input
  </ParamField>
</ParamField>

```typescript theme={null}
const result = await this.elicitInput({
  message: "Please enter your name",
  requestedSchema: {
    type: "object",
    properties: {
      name: { type: "string" }
    }
  }
});

console.log("User input:", result);
```

**Returns:** `Promise<ElicitResult>` - User's response or cancellation

### getTransportType()

Get the transport type for this MCP Agent instance.

```typescript theme={null}
const transport = this.getTransportType();
// "sse" | "streamable-http" | "rpc"
```

**Returns:** `"sse" | "streamable-http" | "rpc"`

<Note>
  The transport type is determined by the naming scheme: `sse:${sessionId}`, `streamable-http:${sessionId}`, or `rpc:${sessionId}`.
</Note>

### getSessionId()

Get the session ID for this MCP Agent instance.

```typescript theme={null}
const sessionId = this.getSessionId();
console.log("Session ID:", sessionId);
```

**Returns:** `string` - Session ID

### getWebSocket()

Get the unique WebSocket connection (SSE transport only).

```typescript theme={null}
const ws = this.getWebSocket();
if (ws) {
  ws.send("Custom message");
}
```

**Returns:** `Connection | null` - WebSocket connection or null

### getRpcTransportOptions()

Override to customize RPC transport behavior (e.g., timeout).

```typescript theme={null}
protected getRpcTransportOptions(): RPCServerTransportOptions {
  return { timeout: 120000 }; // 2 minutes
}
```

**Returns:** `RPCServerTransportOptions`

## Static Methods

### serve()

Create a fetch handler for the MCP server.

<ParamField path="path" type="string" required>
  URL path to serve the MCP server on
</ParamField>

<ParamField path="options" type="ServeOptions">
  <ParamField path="binding" type="string" default="MCP_OBJECT">
    Name of the Durable Object binding in wrangler.jsonc
  </ParamField>

  <ParamField path="transport" type="'streamable-http' | 'sse'" default="streamable-http">
    MCP transport mode
  </ParamField>

  <ParamField path="corsOptions" type="CorsOptions">
    CORS configuration
  </ParamField>

  <ParamField path="jurisdiction" type="DurableObjectJurisdiction">
    Durable Object jurisdiction
  </ParamField>
</ParamField>

```typescript theme={null}
export default {
  "/mcp": MyMcpServer.serve("/mcp", {
    binding: "MY_MCP_SERVER",
    transport: "streamable-http"
  })
};
```

**Returns:** Fetch handler object

### serveSSE()

Create a fetch handler for SSE transport (legacy).

```typescript theme={null}
export default {
  "/mcp": MyMcpServer.serveSSE("/mcp")
};
```

**Returns:** Fetch handler object

## Lifecycle

### onStart()

Called when the Agent starts. Sets up the MCP transport and connects the server.

```typescript theme={null}
async onStart(props?: Props) {
  // Custom initialization
  console.log("MCP server starting with props:", props);
}
```

### onConnect()

Validates new WebSocket connections for MCP protocol.

```typescript theme={null}
async onConnect(conn: Connection, ctx: ConnectionContext) {
  // Custom connection validation
  const authToken = ctx.request.headers.get("Authorization");
  if (!authToken) {
    conn.close(1008, "Unauthorized");
  }
}
```

## Transport Types

### Streamable HTTP

Recommended transport for modern MCP clients.

```typescript theme={null}
export default {
  "/mcp": MyMcpServer.serve("/mcp", {
    transport: "streamable-http"
  })
};
```

### SSE (Legacy)

Server-Sent Events transport for older clients.

```typescript theme={null}
export default {
  "/mcp": MyMcpServer.serve("/mcp", {
    transport: "sse"
  })
};
```

### RPC (Durable Object)

Direct Durable Object binding for internal MCP servers.

```typescript theme={null}
// Server side
class InternalMcpServer extends McpAgent {
  // ...
}

// Client side (in another Agent)
await this.mcp.addRpcMcpServer("my-server", env.INTERNAL_MCP_SERVER, {
  props: { config: "value" }
});
```

## Full Example

```typescript theme={null}
import { McpAgent } from "agents/mcp";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import {
  ListToolsRequestSchema,
  CallToolRequestSchema,
  type CallToolRequest
} from "@modelcontextprotocol/sdk/types.js";

class WeatherMcpServer extends McpAgent {
  server = new Server({
    name: "weather-server",
    version: "1.0.0"
  }, {
    capabilities: {
      tools: {}
    }
  });

  async init() {
    // List available tools
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: "get_weather",
          description: "Get current weather for a location",
          inputSchema: {
            type: "object",
            properties: {
              location: {
                type: "string",
                description: "City name or zip code"
              }
            },
            required: ["location"]
          }
        }
      ]
    }));

    // Handle tool calls
    this.server.setRequestHandler(
      CallToolRequestSchema,
      async (request: CallToolRequest) => {
        if (request.params.name === "get_weather") {
          const { location } = request.params.arguments as {
            location: string;
          };

          // Fetch weather data
          const weather = await this.fetchWeather(location);

          return {
            content: [
              {
                type: "text",
                text: `Weather in ${location}: ${weather.temp}°F, ${weather.condition}`
              }
            ]
          };
        }

        return {
          content: [
            {
              type: "text",
              text: "Unknown tool"
            }
          ],
          isError: true
        };
      }
    );
  }

  private async fetchWeather(location: string) {
    // Implementation
    return { temp: 72, condition: "Sunny" };
  }
}

export default {
  "/mcp": WeatherMcpServer.serve("/mcp")
};
```

## wrangler.jsonc Configuration

```jsonc theme={null}
{
  "name": "weather-mcp-server",
  "main": "src/index.ts",
  "compatibility_date": "2026-01-28",
  "compatibility_flags": ["nodejs_compat"],
  "durable_objects": {
    "bindings": [
      {
        "name": "WEATHER_MCP_SERVER",
        "class_name": "WeatherMcpServer",
        "script_name": "weather-mcp-server"
      }
    ]
  }
}
```

## Related

* [MCPClientManager](/api/mcp-client-manager) - Connect to MCP servers from Agents
* [Agent Class](/api/agent-class) - Base Agent class
* [MCP SDK](https://modelcontextprotocol.io/) - Model Context Protocol
