diff --git a/public/__redirects b/public/__redirects index 9cd9d1ed45ef45b..71f7ee93497a7ce 100644 --- a/public/__redirects +++ b/public/__redirects @@ -110,7 +110,7 @@ /agents/examples/build-mcp-server/ /agents/api-reference/build-mcp-server/ 301 /agents/api-reference/build-mcp-server/ /agents/guides/build-mcp-server/ 301 /agents/api-reference/sdk/ /agents/api-reference/ 301 - +/agents/guides/build-mcp-server/ /agents/guides/remote-mcp-server/ 301 # ai /ai/ /use-cases/ai/ 301 diff --git a/src/assets/images/agents/mcp-demo-oauth-flow.png b/src/assets/images/agents/mcp-demo-oauth-flow.png new file mode 100644 index 000000000000000..beb9181b8e8dac4 Binary files /dev/null and b/src/assets/images/agents/mcp-demo-oauth-flow.png differ diff --git a/src/assets/images/agents/mcp-inspector-authenticated.png b/src/assets/images/agents/mcp-inspector-authenticated.png new file mode 100644 index 000000000000000..7029fc27bc42807 Binary files /dev/null and b/src/assets/images/agents/mcp-inspector-authenticated.png differ diff --git a/src/assets/images/agents/mcp-inspector-enter-url.png b/src/assets/images/agents/mcp-inspector-enter-url.png new file mode 100644 index 000000000000000..ed3596f4045bab9 Binary files /dev/null and b/src/assets/images/agents/mcp-inspector-enter-url.png differ diff --git a/src/content/docs/agents/guides/build-mcp-server.mdx b/src/content/docs/agents/guides/build-mcp-server.mdx deleted file mode 100644 index d1fa5c5aa5ddede..000000000000000 --- a/src/content/docs/agents/guides/build-mcp-server.mdx +++ /dev/null @@ -1,211 +0,0 @@ ---- -pcx_content_type: tutorial -title: Build an MCP Server -sidebar: - order: 100 - group: - hideIndex: true -description: Build and deploy an MCP server on Cloudflare Workers ---- - -import { MetaInfo, Render, Type, TypeScriptExample, WranglerConfig } from "~/components"; -import { Aside } from '@astrojs/starlight/components'; - -[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open standard that allows AI agents and assistants (like [Claude Desktop](https://claude.ai/download) or [Cursor](https://www.cursor.com/)) to interact with services directly. If you want users to access your service through an AI assistant, you can spin up an MCP server for your application. - -### Building an MCP Server on Workers - -With Cloudflare Workers and the [workers-mcp](https://github.com/cloudflare/workers-mcp/) package, you can turn any API or service into an MCP server with minimal setup. Just define your API methods as TypeScript functions, and workers-mcp takes care of tool discovery, protocol handling, and request routing. Once deployed, MCP clients like Claude can connect and interact with your service automatically. - -Below we will run you through an example of building an MCP server that fetches weather data from an external API and exposes it as an MCP tool that Claude can call directly: - -**How it works:** -* **TypeScript methods as MCP tools:** Each public method in your class is exposed as an MCP tool that agents can call. In this example, getWeather is the tool that fetches data from an external weather API. -* **Automatic tool documentation:** JSDoc comments define the tool description, parameters, and return values, so Claude knows exactly how to call your method and interpret the response. -* **Build-in MCP compatibility:** The `ProxyToSelf` class translates incoming requests into relevant JS RPC methods -* **Enforced type safety:** Parameter and return types are automatically derived from your TypeScript definitions - -## Get Started - -Follow these steps to create and deploy your own MCP server on Cloudflare Workers. - - - - -### Create a new Worker - -If you haven't already, install [Wrangler](https://developers.cloudflare.com/workers/wrangler/) and log in: - -```bash -npm install wrangler -wrangler login -``` - -Initialize a new project: -```bash -npx create-cloudflare@latest my-mcp-worker -cd my-mcp-worker -``` - -### Configure your wrangler file - -When you run the setup command, it will build your Worker using the configuration in your wrangler.toml or wrangler.jsonc file. By default, no additional configuration is needed, but if you have multiple Cloudflare accounts, you'll need to specify your account ID as shown below. - - -```toml -name = "my-mcp-worker" -main = "src/index.ts" -compatibility_date = "2025-03-03" -account_id = "your-account-id" -``` - - -### Install the MCP tooling -Inside your project directory, install the [workers-mcp](https://github.com/cloudflare/workers-mcp) package: - -```bash -npm install workers-mcp -``` - -This package provides the tools needed to run your Worker as an MCP server. - -### Configure your Worker to support MCP -Run the following setup command: - -```bash -npx workers-mcp setup -``` - -This guided installation process takes a brand new or existing Workers project and adds the required tooling to turn it into an MCP server: -- Automatic documentation generation -- Shared-secret security using Wrangler Secrets -- Installs a local proxy so you can access it from your MCP desktop clients (like Claude Desktop) - -### Set up the MCP Server -The setup command will automatically update your src/index.ts with the following code: - -```ts -import { WorkerEntrypoint } from 'cloudflare:workers'; -import { ProxyToSelf } from 'workers-mcp'; - -export default class MyWorker extends WorkerEntrypoint { - /** - * A warm, friendly greeting from your new MCP server. - * @param name {string} The name of the person to greet. - * @return {string} The greeting message. - */ - sayHello(name: string) { - return `Hello from an MCP Worker, ${name}!`; - } - - /** - * @ignore - */ - async fetch(request: Request): Promise { - // ProxyToSelf handles MCP protocol compliance. - return new ProxyToSelf(this).fetch(request); - } -} -``` - -This converts your Cloudflare Worker into an MCP server, enabling interactions with AI assistants. **The key components are:** -- **WorkerEntrypoint:** The WorkerEntrypoint class handles all incoming request management and routing. This provides the structure needed to expose MCP tools within the Worker. -- **Tool Definition:** Methods, for example, sayHello, are annotated with JSDoc, which automatically registers the method as an MCP tool. AI assistants can call this method dynamically, passing a name and receiving a greeting in response. Additional tools can be defined using the same pattern. -- **ProxyToSelf:** MCP servers must follow a specific request/response format. ProxyToSelf ensures that incoming requests are properly routed to the correct MCP tools. Without this, you would need to manually parse requests and validate responses. - - -**Note:** Every public method that is annotated with JSDoc becomes an MCP tool that is discoverable by AI assistants. - -### Add data fetching to the MCP - -When building an MCP, in many cases, you will need to connect to a resource or an API to take an action. To do this you can use the `fetch` method to make direct API calls, such as in the example below for grabbing the current wearther: - -```ts -import { WorkerEntrypoint } from 'cloudflare:workers'; -import { ProxyToSelf } from 'workers-mcp'; - -export default class WeatherWorker extends WorkerEntrypoint { - /** - * Get current weather for a location - * @param location {string} City name or zip code - * @return {object} Weather information - */ - async getWeather(location: string) { - // Connect to a weather API - const response = await fetch(`https://api.weather.example/v1/${location}`); - const data = await response.json(); - return { - temperature: data.temp, - conditions: data.conditions, - forecast: data.forecast - }; - } - - /** - * @ignore - */ - async fetch(request: Request): Promise { - // ProxyToSelf handles MCP protocol compliance - return new ProxyToSelf(this).fetch(request); - } -} -``` - -### Deploy the MCP server -Update your wrangler.toml with the appropriate configuration then deploy your Worker: -```bash -npx wrangler deploy -``` - -Your MCP server is now deployed globally and all your public class methods are exposed as MCP tools that AI assistants can now interact with. - -#### Updating your MCP server -When you make changes to your MCP server, run the following command to update it: -```bash -npm run deploy -``` -**Note:** If you change method names, parameters, or add/remove methods, Claude and other MCP clients will not see these updates until you restart them. This is because MCP clients cache the tool metadata for performance reasons. -### Connecting MCP clients to your server -The `workers-mcp setup` command automatically configures Claude Desktop to work with your MCP server. To use your MCP server through other [MCP clients](https://modelcontextprotocol.io/clients), you'll need to configure them manually. - -#### Cursor -To get your Cloudflare MCP server working in [Cursor](https://modelcontextprotocol.io/clients#cursor), you need to combine the 'command' and 'args' from your config file into a single string and use type 'command'. - -In Cursor, create an MCP server entry with: - -type: command -command: /path/to/workers-mcp run your-mcp-server-name https://your-server-url.workers.dev /path/to/your/project - -For example, using the same configuration as above, your Cursor command would be: -``` -/Users/username/path/to/my-new-worker/node_modules/.bin/workers-mcp run my-new-worker https://my-new-worker.username.workers.dev /Users/username/path/to/my-new-worker -``` - -#### Other MCP clients -For [Windsurf](https://modelcontextprotocol.io/clients#windsurf-editor) and other [MCP clients](https://modelcontextprotocol.io/clients#client-details), update your configuration file to include your worker using the same format as Claude Desktop: -```json -{ - "mcpServers": { - "your-mcp-server-name": { - "command": "/path/to/workers-mcp", - "args": [ - "run", - "your-mcp-server-name", - "https://your-server-url.workers.dev", - "/path/to/your/project" - ], - "env": {} - } - } -} -``` -Make sure to replace the placeholders with your actual server name, URL, and project path. -### Coming soon -The Model Context Protocol spec is [actively evolving](https://github.com/modelcontextprotocol/specification/discussions) and we're working on expanding Cloudflare's MCP support. Here's what we're working on: - -- **Remote MCP support**: Connect to MCP servers directly without requiring a local proxy -- **Authentication**: OAuth support for secure MCP server connections -- **Real-time communication**: SSE (Server-Sent Events) and WebSocket support for persistent connections and stateful interactions between clients and servers -- **Extended capabilities**: Native support for more MCP protocol capabilities like [resources](https://modelcontextprotocol.io/docs/concepts/resources), [prompts](https://modelcontextprotocol.io/docs/concepts/prompts) and [sampling](https://modelcontextprotocol.io/docs/concepts/sampling) \ No newline at end of file diff --git a/src/content/docs/agents/guides/remote-mcp-server.mdx b/src/content/docs/agents/guides/remote-mcp-server.mdx new file mode 100644 index 000000000000000..8b628c46009dee7 --- /dev/null +++ b/src/content/docs/agents/guides/remote-mcp-server.mdx @@ -0,0 +1,227 @@ +--- +pcx_content_type: concept +title: Build a remote MCP server +sidebar: + order: 4 +--- + +import { Details, Render, PackageManagers } from "~/components"; + +## Deploy your first MCP server + +This guide will walk you through how to deploy an [example MCP server](https://github.com/cloudflare/ai/tree/main/demos/remote-mcp-server) to your Cloudflare account. You will then customize this example to suit your needs. + +The link below will guide you through everything you need to do to deploy this [example MCP server](https://github.com/cloudflare/ai/tree/main/demos/remote-mcp-server) to your Cloudflare account: + +[![Deploy to Workers](https://deploy.workers.cloudflare.com/button)](https://dash.cloudflare.com/?to=/:account/workers-and-pages/create/deploy-to-workers&repository=https://github.com/cloudflare/ai/tree/main/demos/remote-mcp-server) + +At the end of this process, you will have a new git repository on your GitHub or GitLab account for your MCP server, configured to automatically deploy Cloudflare each time you push a change or merge a pull request to the main branch of the repository. You can then clone this repository, [develop locally](/agents/guides/remote-mcp-server/#local-development), and start writing code and building. + +Alternatively, you can use the command line as shown below to create a new MCP Server on your local machine. + + + +Now, you have the MCP server setup, with dependencies installed. Move into that project folder: + +```sh +cd my-mcp-server +``` + +### Local development + +In the directory of your new project, run the following command to start the development server: + +```sh +npm start +``` + +Your MCP server is now running on `http://localhost:8787/sse`. + +In a new terminal, run the [MCP inspector](https://github.com/modelcontextprotocol/mcp-inspector). The MCP inspector is an interactive MCP client that allows you to connect to your MCP server and invoke tools from a web browser. + +```sh +npx @modelcontextprotocol/inspector@latest +``` + +Open the MCP inspector in your web browser: + +```sh +open http://localhost:5173 +``` + +In the inspector, enter the URL of your MCP server, `http://localhost:8787/sse`, and click **Connect**: + +![MCP inspector — where to enter the URL of your MCP server](~/assets/images/agents/mcp-inspector-enter-url.png) + +You will be redirected to an example OAuth login page. Enter any username and password and click "Log in and approve" to continue. (you can add your own authentication and/or authorization provider to replace this. Refer to the [authorization](/agents/model-context-protocol/authorization/) section for details on how to do this.) + +![MCP OAuth Login Page](~/assets/images/agents/mcp-demo-oauth-flow.png) + +Once you have logged in, you will be redirected back to the inspector. You should see the "List Tools" button, which will list the tools that your MCP server exposes. + +![MCP inspector — authenticated](~/assets/images/agents/mcp-inspector-authenticated.png) + +### Deploy your MCP server + +You can deploy your MCP server to Cloudflare using the following [Wrangler CLI command](/workers/wrangler) within the example project: + +```sh +npx wrangler@latest deploy +``` + +If you have already [connected a git repository](/workers/ci-cd/builds/) to the Worker with your MCP server, you can deploy your MCP server by pushing a change or merging a pull request to the main branch of the repository. + +After deploying, take the URL of your deployed MCP server, and enter it in the MCP inspector running on `http://localhost:5173`. You now have a remote MCP server, deployed to Cloudflare, that MCP clients can connect to. + +### Connect your remote MCP server to Claude and other MCP Clients via a local proxy + +Now that your MCP server is running with OAuth authentication, you can use the [`mcp-remote` local proxy](https://www.npmjs.com/package/mcp-remote) to connect Claude Desktop or other MCP clients to it — even though these tools aren't yet _remote_ MCP clients, and don't support remote transport or authorization on the client side. This lets you to test what an interaction with your OAuth-enabled MCP server will be like with a real MCP client. + +Update your Claude Desktop configuration to point to the URL of your MCP server. You can use either the `localhost:8787/sse` URL, or the URL of your deployed MCP server: + +```json +{ + "mcpServers": { + "math": { + "command": "npx", + "args": [ + "mcp-remote", + "https://your-worker-name.your-account.workers.dev/sse" + ] + } + } +} +``` + +Restart Claude Desktop and complete the authentication flow again. Once this is done, Claude will be able to make calls to your remote MCP server. you can test this by asking Claude to use one of your tools. For example: "Could you use the math tool to add 23 and 19?". Claude should invoke the tool and show the result generated by the MCP server. + +Learn more about other ways of using remote MCP servers with MCP clients here in [this section](/agents/guides/test-remote-mcp-server). + +## Add Authentication + +The example MCP server you just deployed above acts as an OAuth provider to MCP clients, handling authorization, but has a placeholder authentication flow. It lets you enter any username and password to log in, and doesn't actually authenticate you against any user database. + +In the next section, you will add a real authentication provider to your MCP server. Even if you already have an authentication provider in place, following these steps will show you more clearly how to integrate it with your MCP server. + +We'll use GitHub as the authentication provider here, but you can use any OAuth provider that supports the OAuth 2.0 specification, including Google, Slack, Stytch, Auth0, and more. + +### Step 1 — Create and deploy a new MCP server + +Run the following command to create a new MCP server: + + + +Now, you have the MCP server setup, with dependencies installed. Move into that project folder: + +```sh +cd my-mcp-server-github-auth +``` + +Then, run the following command to deploy the MCP server: + +```sh +npx wrangler@latest deploy +``` + +You'll notice that in the example MCP server, if you open `src/index.ts`, the primary difference is that the `defaultHandler` is set to the `GitHubHandler`: + +```ts ins="OAuthProvider.GitHubHandler" +import GitHubHandler from "./github-handler"; + +export default new OAuthProvider({ + apiRoute: "/sse", + apiHandler: MyMCP.Router, + defaultHandler: GitHubHandler, + authorizeEndpoint: "/authorize", + tokenEndpoint: "/token", + clientRegistrationEndpoint: "/register", +}); +``` + +This will ensure that your users are redirected to GitHub to authenticate. To get this working though, you need to create OAuth client apps in the steps below. + +### Step 2 — Create an OAuth App + +You'll need to create two [GitHub OAuth Apps](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) to use GitHub as an authentication provider for your MCP server — one for local development, and one for production. + +#### First create a new OAuth App for local development + +Navigate to [github.com/settings/developers](https://github.com/settings/developers) to create a new OAuth App with the following settings: + +- **Application name**: `My MCP Server (local)` +- **Homepage URL**: `http://localhost:8787` +- **Authorization callback URL**: `http://localhost:8787/callback` + +For the OAuth app you just created, add the client ID of the OAuth app as `GITHUB_CLIENT_ID` and generate a client secret, adding it as `GITHUB_CLIENT_SECRET` to a `.dev.vars` file in the root of your project, which [will be used to set secrets in local development](/workers/configuration/secrets/). + +```sh +touch .dev.vars +echo 'GITHUB_CLIENT_ID="your-client-id"' >> .dev.vars +echo 'GITHUB_CLIENT_SECRET="your-client-secret"' >> .dev.vars +cat .dev.vars +``` + +#### Next, run your MCP server locally + +Run the following command to start the development server: + +```sh +npm start +``` + +Your MCP server is now running on `http://localhost:8787/sse`. + +In a new terminal, run the [MCP inspector](https://github.com/modelcontextprotocol/mcp-inspector). The MCP inspector is an interactive MCP client that allows you to connect to your MCP server and invoke tools from a web browser. + +```sh +npx @modelcontextprotocol/inspector@latest +``` + +Open the MCP inspector in your web browser: + +```sh +open http://localhost:5173 +``` + +In the inspector, enter the URL of your MCP server, `http://localhost:8787/sse`, and click **Connect**: + +You should be redirected to a GitHub login or authorization page. After authorizing the MCP Client (the inspector) access to your GitHub account, you will be redirected back to the inspector. You should see the "List Tools" button, which will list the tools that your MCP server exposes. + +#### Second — create a new OAuth App for production + +You'll need to repeat these steps to create a new OAuth App for production. + +Navigate to [github.com/settings/developers](https://github.com/settings/developers) to create a new OAuth App with the following settings: + +- **Application name**: `My MCP Server (production)` +- **Homepage URL**: Enter the workers.dev URL of your deployed MCP server (ex: `worker-name.account-name.workers.dev`) +- **Authorization callback URL**: Enter the `/callback` path of the workers.dev URL of your deployed MCP server (ex: `worker-name.account-name.workers.dev/callback`) + +For the OAuth app you just created, add the client ID and client secret, using Wrangler CLI: + +```sh +wrangler secret put GITHUB_CLIENT_ID +``` + +```sh +wrangler secret put GITHUB_CLIENT_SECRET +``` + +#### Finally, connect to your MCP server + +Now that you've added the ID and secret of your production OAuth app, you should now be able to connect to your MCP server running at `worker-name.account-name.workers.dev/sse` using the MCP inspector or ([other MCP clients](/agents/guides/remote-mcp-server/#connect-your-mcp-server-to-claude-and-other-mcp-clients)), and authenticate with GitHub. + +## Next steps + +- Add [tools](/agents/model-context-protocol/tools/) to your MCP server. +- Customize your MCP Server's [authentication and authorization](/agents/model-context-protocol/authorization/). diff --git a/src/content/docs/agents/guides/test-remote-mcp-server.mdx b/src/content/docs/agents/guides/test-remote-mcp-server.mdx new file mode 100644 index 000000000000000..5a5c8e07e12eb46 --- /dev/null +++ b/src/content/docs/agents/guides/test-remote-mcp-server.mdx @@ -0,0 +1,73 @@ +--- +pcx_content_type: concept +title: Test a Remote MCP Server +sidebar: + order: 6 +--- + +import { Render } from "~/components"; + +Remote, authorized connections are an evolving part of the [Model Context Protocol (MCP) specification](https://spec.modelcontextprotocol.io/specification/draft/basic/authorization/). Not all MCP clients support remote connections yet. + +This guide will show you options for how to start using your remote MCP server with MCP clients that support remote connections. If you haven't yet created and deployed a remote MCP server, you should follow the [Build a Remote MCP Server](/agents/guides/remote-mcp-server/) guide first. + +## The Model Context Protocol (MCP) inspector + +The [`@modelcontextprotocol/inspector` package](https://github.com/modelcontextprotocol/inspector) is a visual testing tool for MCP servers. + +You can run it locally by running the following command: + +```bash +npx @modelcontextprotocol/inspector +``` + +Then, enter the URL of your remote MCP server. You can use an MCP server running on your local machine on localhost, or you can use a remote MCP server running on Cloudflare. + +![MCP inspector](~/assets/images/agents/mcp-inspector-enter-url.png) + +Once you have authenticated, you will be redirected back to the inspector. You should see the "List Tools" button, which will list the tools that your MCP server exposes. + +![MCP inspector — authenticated](~/assets/images/agents/mcp-inspector-authenticated.png) + +## Connect your remote MCP server to Claude Desktop via a local proxy + +Even though [Claude Desktop](https://claude.ai/download) doesn't yet support remote MCP clients, you can use the [`mcp-remote` local proxy](https://www.npmjs.com/package/mcp-remote) to connect it to your remote MCP server. This lets you to test what an interaction with your remote MCP server will be like with a real-world MCP client. + +1. Open Claude Desktop and navigate to Settings -> Developer -> Edit Config. This opens the configuration file that controls which MCP servers Claude can access. +2. Replace the content with a configuration like this: + +```json +{ + "mcpServers": { + "math": { + "command": "npx", + "args": ["mcp-remote", "http://my-mcp-server.my-account.workers.dev/sse"] + } + } +} +``` + +This tells Claude to communicate with your MCP server running at `http://localhost:8787/sse`. + +3. Save the file and restart Claude Desktop (command/ctrl + R). When Claude restarts, a browser window will open showing your OAuth login page. Complete the authorization flow to grant Claude access to your MCP server. + +Once authenticated, you'll be able to see your tools by clicking the tools icon in the bottom right corner of Claude's interface. + +## Connect your remote MCP server to Cursor + +To connect [Cursor](https://www.cursor.com/) with your remote MCP server, choose `Type`: "Command" and in the `Command` field, combine the command and args fields into one (e.g.`npx mcp-remote https://your-worker-name.your-account.workers.dev/sse`). + +## Connect your remote MCP server to Windsurf + +You can connect your remote MCP server to [Windsurf](https://codeium.com/windsurf) by editing the [`mcp_config.json` file](https://docs.codeium.com/windsurf/mcp), and adding the following configuration: + +```json +{ + "mcpServers": { + "math": { + "command": "npx", + "args": ["mcp-remote", "http://my-mcp-server.my-account.workers.dev/sse"] + } + } +} +``` diff --git a/src/content/docs/agents/model-context-protocol/authorization.mdx b/src/content/docs/agents/model-context-protocol/authorization.mdx new file mode 100644 index 000000000000000..bb7d7da859343bd --- /dev/null +++ b/src/content/docs/agents/model-context-protocol/authorization.mdx @@ -0,0 +1,132 @@ +--- +title: Authorization +sidebar: + order: 2 + group: + hideIndex: true +--- + +import { DirectoryListing } from "~/components"; + +When building a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server, you need both a way to allow users to login (authentication) and allow them to grant the MCP client access to resources on their account (authorization). + + + + + +The Model Context Protocol uses [a subset of OAuth 2.1 for authorization](https://spec.modelcontextprotocol.io/specification/draft/basic/authorization/). OAuth allows your users to grant limited access to resources, without them having to share API keys or other credentials. + +Cloudflare provides an [OAuth Provider Library](https://github.com/cloudflare/workers-oauth-provider) that implements the provider side of the OAuth 2.1 protocol, allowing you to easily add authorization to your MCP server. + +You can use the OAuth Provider Library in three ways: + +1. **Your Worker handles authorization itself.** Your MCP server, running on Cloudflare, handles the complete OAuth flow. ([Example](/agents/guides/remote-mcp-server/)) +2. **Integrate directly with a third-party OAuth provider**, such as GitHub or Google. +3. **Integrate with your own OAuth provider**, including authorization-as-a-service providers you might already rely on, such as Stytch and Auth0. + +The following sections describe each of these options and link to runnable code examples for each. + +## Authorization options + +### (1) Your MCP Server handles authorization and authentication itself + +Your MCP Server, using the [OAuth Provider Library](https://github.com/cloudflare/workers-oauth-provider), can handle the complete OAuth authorization flow, without any third-party involvement. + +The [Workers OAuth Provider Library](https://github.com/cloudflare/workers-oauth-provider) is a Cloudflare Worker that implements a [`fetch()` handler](/workers/runtime-apis/handlers/fetch/), and handles incoming requests to your MCP server. + +You provide your own handlers for your MCP Server's API, and autentication and authorization logic, and URI paths for the OAuth endpoints, as shown below: + +```ts +export default new OAuthProvider({ + apiRoute: "/mcp", + // Your MCP server: + apiHandler: MyMCPServer.Router, + // Your handler for authentication and authorization: + defaultHandler: MyAuthHandler, + authorizeEndpoint: "/authorize", + tokenEndpoint: "/token", + clientRegistrationEndpoint: "/register", +}); +``` + +Refer to the [getting started example](/agents/guides/remote-mcp-server/) for a complete example of the `OAuthProvider` in use, with a mock authentication flow. + +The authorization flow in this case works like this: + +```mermaid +sequenceDiagram + participant B as User-Agent (Browser) + participant C as MCP Client + participant M as MCP Server (your Worker) + + C->>M: MCP Request + M->>C: HTTP 401 Unauthorized + Note over C: Generate code_verifier and code_challenge + C->>B: Open browser with authorization URL + code_challenge + B->>M: GET /authorize + Note over M: User logs in and authorizes + M->>B: Redirect to callback URL with auth code + B->>C: Callback with authorization code + C->>M: Token Request with code + code_verifier + M->>C: Access Token (+ Refresh Token) + C->>M: MCP Request with Access Token + Note over C,M: Begin standard MCP message exchange +``` + +Remember — [authentication is different from authorization](https://www.cloudflare.com/learning/access-management/authn-vs-authz/). Your MCP Server can handle authorization itself, while still relying on an external authentication service to first authenticate users. The [example](/agents/guides/remote-mcp-server) in getting started provides a mock authentdcation flow. You will need to implement your own authentication handler — either handling authentication yourself, or using an external authentication services. + +### (2) Third-party OAuth Provider + +The [OAuth Provider Library](https://github.com/cloudflare/workers-oauth-provider) can be configured to use a third-party OAuth provider, such as GitHub or Google. You can see a complete example of this in the [GitHub example](/agents/guides/remote-mcp-server/#add-authentication). + +When you use a third-party OAuth provider, you must provide a handler to the `OAuthProvider` that implements the OAuth flow for the third-party provider. + +```ts ins="defaultHandler: MyAuthHandler," +import MyAuthHandler from "./auth-handler"; + +export default new OAuthProvider({ + apiRoute: "/mcp", + // Your MCP server: + apiHandler: MyMCPServer.Router, + // Replace this handler with your own handler for authentication and authorization with the third-party provider: + defaultHandler: MyAuthHandler, + authorizeEndpoint: "/authorize", + tokenEndpoint: "/token", + clientRegistrationEndpoint: "/register", +}); +``` + +Note that as [defined in the Model Context Protocol specification](https://spec.modelcontextprotocol.io/specification/draft/basic/authorization/#292-flow-description) when you use a third-party OAuth provider, the MCP Server (your Worker) generates and issues its own token to the MCP client: + +```mermaid +sequenceDiagram + participant B as User-Agent (Browser) + participant C as MCP Client + participant M as MCP Server (your Worker) + participant T as Third-Party Auth Server + + C->>M: Initial OAuth Request + M->>B: Redirect to Third-Party /authorize + B->>T: Authorization Request + Note over T: User authorizes + T->>B: Redirect to MCP Server callback + B->>M: Authorization code + M->>T: Exchange code for token + T->>M: Third-party access token + Note over M: Generate bound MCP token + M->>B: Redirect to MCP Client callback + B->>C: MCP authorization code + C->>M: Exchange code for token + M->>C: MCP access token +``` + +Read the docs for the [Workers oAuth Provider Library](https://github.com/cloudflare/workers-oauth-provider) for more details. + +### (3) Bring your own OAuth Provider + +If your application already implements an Oauth Provider itself, or you use Stytch, Auth0, or authorization-as-a-service provider, you can use this in the same way that you would use a third-party OAuth provider, described above in (2). + +## Next steps + +- [Learn how to use the Workers OAuth Provider Library](https://github.com/cloudflare/workers-oauth-provider) +- Learn how to use a third-party OAuth provider, using the [GitHub](/agents/guides/remote-mcp-server/#add-authentication) example MCP server. diff --git a/src/content/docs/agents/model-context-protocol/index.mdx b/src/content/docs/agents/model-context-protocol/index.mdx new file mode 100644 index 000000000000000..0ba9dce0cb5f929 --- /dev/null +++ b/src/content/docs/agents/model-context-protocol/index.mdx @@ -0,0 +1,31 @@ +--- +title: Model Context Protocol (MCP) +pcx_content_type: navigation +sidebar: + order: 4 + group: + hideIndex: false +--- + +You can build and deploy [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers on Cloudflare. + +## What is the Model Context Protocol (MCP)? + +[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that connects AI systems with external applications. Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various accessories, MCP provides a standardized way to connect AI agents to different services. + +### MCP Terminology + +- **MCP Hosts**: AI assistants (like [Claude](http://claude.ai) or [Cursor](http://cursor.com)), AI agents, or applications that need to access external capabilities. +- **MCP Clients**: Clients embedded within the MCP hosts that connect to MCP servers and invoke tools. Each MCP client instance has a single connection to an MCP server. +- **MCP Servers**: Applications that expose [tools](/agents/model-context-protocol/tools/), [prompts](https://modelcontextprotocol.io/docs/concepts/prompts), and [resources](https://modelcontextprotocol.io/docs/concepts/resources) that MCP clients can use. + +### Remote vs. local MCP connections + +The MCP standard supports two modes of operation: + +- **Remote MCP connections**: MCP clients connect to MCP servers over the Internet, establishing a [long-lived connection using HTTP and Server-Sent Events (SSE)](/agents/model-context-protocol/transport/), and authorizing the MCP client access to resources on the user's account using [OAuth](/agents/model-context-protocol/authorization/). +- **Local MCP connections**: MCP clients connect to MCP servers on the same machine, using [stdio](https://spec.modelcontextprotocol.io/specification/draft/basic/transports/#stdio) as a local transport method. + +### Get Started + +Go to the [Getting Started](/agents/guides/remote-mcp-server/) guide to learn how to build and deploy your first remote MCP server to Cloudflare. diff --git a/src/content/docs/agents/model-context-protocol/tools.mdx b/src/content/docs/agents/model-context-protocol/tools.mdx new file mode 100644 index 000000000000000..d1e6aaa1483ee68 --- /dev/null +++ b/src/content/docs/agents/model-context-protocol/tools.mdx @@ -0,0 +1,34 @@ +--- +pcx_content_type: concept +title: Tools +sidebar: + order: 3 +--- + +import { Render, TypeScriptExample } from "~/components"; + +Model Context Protocol (MCP) tools are functions that a [MCP Server](/agents/model-context-protocol) provides and MCP clients can call. + +When you build MCP Servers with the `@cloudflare/model-context-protocol` package, you can define tools the [same way as shown in the `@modelcontextprotocol/typescript-sdk` package's examples](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#tools). + +For example, the following code from [this example MCP server](https://github.com/cloudflare/ai/tree/main/demos/remote-mcp-server) defines a simple MCP server that adds two numbers together: + + +```ts title="src/index.ts" +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp"; +import { DurableMCP } from "@cloudflare/model-context-protocol"; + +export class MyMCP extends DurableMCP { + server = new McpServer({ name: "Demo", version: "1.0.0" }); + async init() { + this.server.tool( + "add", + { a: z.number(), b: z.number() }, + async ({ a, b }) => ({ + content: [{ type: "text", text: String(a + b) }], + }), + ); + } +} +``` + diff --git a/src/content/docs/agents/model-context-protocol/transport.mdx b/src/content/docs/agents/model-context-protocol/transport.mdx new file mode 100644 index 000000000000000..06f4291848dc2e3 --- /dev/null +++ b/src/content/docs/agents/model-context-protocol/transport.mdx @@ -0,0 +1,21 @@ +--- +pcx_content_type: concept +title: Transport +sidebar: + order: 5 +--- + +import { Render } from "~/components"; + +The Model Context Protocol (MCP) specification defines [two standard transport mechanisms](https://spec.modelcontextprotocol.io/specification/draft/basic/transports/): + +1. **stdio, communication over standard in and standard out** — designed for local MCP connections +2. **HTTP with Server-Sent Events (SSE)** — designed for remote MCP connections + +MCP Servers deployed to Cloudflare support remote MCP connections, using HTTP with Server-Sent Events (SSE) as transport. SSE requires a persistent HTTP connection, which is supported by Cloudflare [Durable Objects](/durable-objects/). Transport is configured and handled automatically. You don't need to configure anything — it just works. + +:::note +Even if the MCP client you are using only supports local MCP connections, you can still connect it to a remote MCP server. + +Follow [this guide](/agents/guides/test-remote-mcp-server/) for instructions on how to connect to your remote MCP server from Claude Desktop, Cursor, Windsurf, and other local MCP clients, using the [`mcp-remote` local proxy](https://www.npmjs.com/package/mcp-remote). +:::