Skip to content
Cloudflare Docs

Transport

The Model Context Protocol (MCP) specification defines two standard transport mechanisms for communication between clients and servers:

  1. stdio — Communication over standard in and standard out, designed for local MCP connections.
  2. Streamable HTTP — The standard transport method for remote MCP connections, introduced in March 2025. It uses a single HTTP endpoint for bidirectional messaging.

MCP servers built with the Agents SDK use createMcpHandler to handle Streamable HTTP transport.

Implementing remote MCP transport

Use createMcpHandler to create an MCP server that handles Streamable HTTP transport. This is the recommended approach for new MCP servers.

Get started quickly

You can use the "Deploy to Cloudflare" button to create a remote MCP server.

Deploy to Workers

Remote MCP server (without authentication)

Create an MCP server using createMcpHandler. View the complete example on GitHub.

JavaScript
import { createMcpHandler } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({
name: "My MCP Server",
version: "1.0.0",
});
server.registerTool(
"hello",
{
description: "Returns a greeting message",
inputSchema: { name: z.string().optional() },
},
async ({ name }) => {
return {
content: [{ text: `Hello, ${name ?? "World"}!`, type: "text" }],
};
},
);
export default {
fetch: (request, env, ctx) => {
return createMcpHandler(server)(request, env, ctx);
},
};

MCP server with authentication

If your MCP server implements authentication & authorization using the Workers OAuth Provider library, use createMcpHandler with the apiRoute and apiHandler properties. View the complete example on GitHub.

JavaScript
export default new OAuthProvider({
apiRoute: "/mcp",
apiHandler: {
fetch: (request, env, ctx) => {
return createMcpHandler(server)(request, env, ctx);
},
},
// ... other OAuth configuration
});

Stateful MCP servers

If your MCP server needs to maintain state across requests, use createMcpHandler with a WorkerTransport inside an Agent class. This allows you to persist session state in Durable Object storage and use advanced MCP features like elicitation and sampling.

See Stateful MCP Servers for implementation details.

Migrating from McpAgent

If you have an existing MCP server using the McpAgent class:

  • Not using state? Replace your McpAgent class with McpServer from @modelcontextprotocol/sdk and use createMcpHandler(server) in a Worker fetch handler.
  • Using state? Use createMcpHandler with a WorkerTransport inside an Agent class. See Stateful MCP Servers for details.
  • Need SSE support? Continue using McpAgent with serveSSE() for legacy client compatibility. See the McpAgent API reference.

Testing with MCP clients

You can test your MCP server using an MCP client that supports remote connections, or use mcp-remote, an adapter that lets MCP clients that only support local connections work with remote MCP servers.

Follow this guide for instructions on how to connect to your remote MCP server to Claude Desktop, Cursor, Windsurf, and other MCP clients.