Skip to content

[Agents] Document MCP servers with createMcpHandler only - #34525

Open
mattzcarey wants to merge 11 commits into
productionfrom
docs/agents-mcp-createmcphandler-only
Open

mattzcarey wants to merge 11 commits into
productionfrom
docs/agents-mcp-createmcphandler-only

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

The Agents MCP docs now show one way to build a server: a stateless createMcpHandler from agents/mcp/server with an MCP SDK v2 McpServer. McpAgent is now covered only by its own reference page (still marked deprecated) and Migrate to MCP SDK v2. The McpAgent RPC transport and this.props auth examples move from the transport and authorization pages into that reference page, so nothing is lost for existing users.

McpAgent has been deprecated since agents@0.20.0, but the docs still taught it next to createMcpHandler, including its RPC transport and this.props auth pattern.

  • Handler API: only createMcpHandler. Adds OAuthProvider wrapping, getMcpAuthContext() inside the factory for per-user tools, and the authContext option. Removes the createLegacyMcpHandler section and bumps the install to @modelcontextprotocol/server@2.3.1.
  • Transport: moves the McpAgent RPC transport section to the McpAgent reference and removes the legacy-lane section.
  • Tools / Authorization: rewrites the McpAgent examples as factory functions, including permission-based tool registration and state in bindings.
  • Remote MCP server guide: drops the approach table and the "templates still use McpAgent" note, and updates the GitHub template snippet.
  • x402: withX402 on an SDK v2 server served by createMcpHandler.
  • MPP: no McpAgent or Durable Object. mppx's Transport.mcpSdk() still needs SDK v1, so this one uses createLegacyMcpHandler per request.
  • ChatGPT app demo: SDK v2 and agents/mcp/server instead of the deprecated v1 createMcpHandler overload.
  • Smaller fixes in human-in-the-loop, routing, getCurrentAgent, securing MCP servers, the next-steps partial, and Agent Lee.

Every OAuthProvider example now passes { fetch } wrapping the handler. Passing the createMcpHandler function directly throws at startup, because OAuthProvider only accepts an ExportedHandler object or a WorkerEntrypoint class.

Left alone: the Code Mode MCP guides (codeMcpServer() and openApiMcpServer() still return SDK v1 servers) and Browser Run's Playwright MCP page (@cloudflare/playwright-mcp exports createMcpAgent).

Merge after cloudflare/ai#680, which moves the GitHub OAuth template this guide quotes to createMcpHandler. Repo-side docs: cloudflare/agents#2654.

Every MCP example is a complete Worker in TypeScriptExample:

  • They type-check against agents@0.29, @modelcontextprotocol/server@2.3.1 and @cloudflare/workers-oauth-provider@1.2.4.
  • I ran them under wrangler dev. The auth server and resource server went through registration, consent (escaped client name, framing header, approve and deny), token and an authorized tools/call. The GitHub sign-in example was checked up to the GitHub redirect and the cookie-bound callback. The handler and tools examples were run with real tool calls.

@github-actions github-actions Bot added product:workers Related to Workers product product:agents Build and deploy AI-powered Agents on Cloudflare that can act autonomously. product:agent-lee Related to Agent Lee product labels Oct 22, 2026
@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

AI Review

✅ Reviewed 500ab8c · 10 findings · incremental

👉 Fix in your agent 👈
Fix the following review findings in PR #34525 (https://github.com/cloudflare/cloudflare-docs/pull/34525).

Before making changes, review each finding and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification.
- If you disagree, explain why.
- If you need clarification before deciding, ask those questions.
- Then share your plan for which issues to tackle and in what order.

After triaging, follow this order:
1. Post a comment on this PR for any findings you are skipping, with the finding ID and your reasoning.
2. Then commit the fixes for the legitimate findings.

The comment must come before the commit because the next review reads PR comments.

## Code Review
- C-1f701a91 | src/content/docs/agents/model-context-protocol/protocol/tools.mdx:252 | `server` is undefined in the stateful-tools example
  The rewritten "Tools that need state" code block imports `env` from `cloudflare:workers` and `getMcpAuthContext` from `agents/mcp/server`, then immediately calls `server.registerTool(...)`, but `server` is never declared in the block and `McpServer` is never imported or constructed. The replaced `McpAgent` example defined its server inline; as written, this snippet cannot run.
  ```txt
  server.registerTool(
  ```
- C-1b8f927c | src/content/docs/agents/tools/payments/x402/charge-for-mcp-tools.mdx:64 | x402 example contradicts the MCP SDK v2 migration guide
  The "Integration compatibility" section of /agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/ states that the server-side `withX402` helper still retains SDK v1 server output and must be isolated behind `createLegacyMcpHandler` until it produces SDK v2 servers. This page now wraps an SDK v2 `McpServer` from `@modelcontextprotocol/server` and serves it with `createMcpHandler`, directly contradicting that guidance; the migration guide was not updated in this PR, so the two pages disagree about how to serve a `withX402` server.
  ```txt
  const handler = createMcpHandler(createServer);
  ```

## Style Guide
- S-1d0dfc40 | src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:196 | Lowercase `internet` should be `Internet`
  The terminology rule requires `Internet` when referring to the global network. This line uses the incorrect lowercase form in `without going over the public internet`.
- S-097ef774 | src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:200 | Marketing phrase `perfect for`
  The marketing-language rule flags `Perfect for` and requires direct language stating what the thing does. This bullet is prose (not a code block or backtick span) and uses `perfect for agents calling MCP servers within the same Worker`.
- S-0ea22145 | src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:330 | Heading begins with `-ing` verb
  The heading rule requires imperative form for headings beginning with a verb ending in `-ing`. This heading begins with `Passing`.
- S-0b03c324 | src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:371 | Heading begins with `-ing` verb
  The heading rule requires imperative form for headings beginning with a verb ending in `-ing`. This heading begins with `Configuring` (explicitly listed as an example in the rule).
- S-135ba05e | src/content/docs/agents/model-context-protocol/guides/securing-mcp-server.mdx:147 | Heading begins with a verb ending in `-ing`
  `## Signing in through a third-party provider` starts with the verb "Signing" in the `-ing` form. Per the headings rule, headings that begin with an `-ing` verb must use the imperative form instead.
- S-02bcb5dc | src/content/docs/agents/model-context-protocol/guides/build-codemode-mcp-server.mdx:36 | Directional word `below` in prose
  The added sentence says "as the examples below do", using the directional word `below`. Per the style guide, directional words such as `above`/`below` must be replaced with a direct reference by name or link.
- S-046e672c | src/content/docs/agents/model-context-protocol/protocol/authorization.mdx:279 | Heading begins with a gerund instead of an imperative verb
  Per the heading style rule, a heading that begins with a verb ending in `-ing` must use the imperative form. This heading starts with `Using`, so it should be rewritten in the imperative.

## Conventions
- V-16da4b5e | PR | Description omits removal of the Code Mode MCP guide pages
  The description states the Code Mode MCP guides were "Left alone", but the changed-file index shows `src/content/docs/agents/model-context-protocol/codemode.mdx` and `src/content/docs/agents/model-context-protocol/guides/build-codemode-openapi-mcp-server.mdx` were removed (117 and 216 lines), and `build-codemode-mcp-server.mdx` was substantially rewritten (+230 -15), absorbing the OpenAPI search-and-execute content. The two redirects added in `public/__redirects` confirm these were removed/moved pages. Removed or moved pages and substantial rewrites are core changes the description should name.

Code Review

  • src/content/docs/agents/model-context-protocol/protocol/tools.mdx:252 · server is undefined in the stateful-tools example

    The rewritten "Tools that need state" code block imports env from cloudflare:workers and getMcpAuthContext from agents/mcp/server, then immediately calls server.registerTool(...), but server is never declared in the block and McpServer is never imported or constructed. The replaced McpAgent example defined its server inline; as written, this snippet cannot run.

    server.registerTool(
  • src/content/docs/agents/tools/payments/x402/charge-for-mcp-tools.mdx:64 · x402 example contradicts the MCP SDK v2 migration guide

    The "Integration compatibility" section of /agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/ states that the server-side withX402 helper still retains SDK v1 server output and must be isolated behind createLegacyMcpHandler until it produces SDK v2 servers. This page now wraps an SDK v2 McpServer from @modelcontextprotocol/server and serves it with createMcpHandler, directly contradicting that guidance; the migration guide was not updated in this PR, so the two pages disagree about how to serve a withX402 server.

    const handler = createMcpHandler(createServer);

Style Guide

  • src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:196 · Lowercase internet should be Internet

    The terminology rule requires Internet when referring to the global network. This line uses the incorrect lowercase form in without going over the public internet.

  • src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:200 · Marketing phrase perfect for

    The marketing-language rule flags Perfect for and requires direct language stating what the thing does. This bullet is prose (not a code block or backtick span) and uses perfect for agents calling MCP servers within the same Worker.

  • src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:330 · Heading begins with -ing verb

    The heading rule requires imperative form for headings beginning with a verb ending in -ing. This heading begins with Passing.

  • src/content/docs/agents/model-context-protocol/apis/agent-api.mdx:371 · Heading begins with -ing verb

    The heading rule requires imperative form for headings beginning with a verb ending in -ing. This heading begins with Configuring (explicitly listed as an example in the rule).

  • src/content/docs/agents/model-context-protocol/guides/securing-mcp-server.mdx:147 · Heading begins with a verb ending in -ing

    ## Signing in through a third-party provider starts with the verb "Signing" in the -ing form. Per the headings rule, headings that begin with an -ing verb must use the imperative form instead.

  • src/content/docs/agents/model-context-protocol/guides/build-codemode-mcp-server.mdx:36 · Directional word below in prose

    The added sentence says "as the examples below do", using the directional word below. Per the style guide, directional words such as above/below must be replaced with a direct reference by name or link.

  • src/content/docs/agents/model-context-protocol/protocol/authorization.mdx:279 · Heading begins with a gerund instead of an imperative verb

    Per the heading style rule, a heading that begins with a verb ending in -ing must use the imperative form. This heading starts with Using, so it should be rewritten in the imperative.

Conventions

  • PR · Description omits removal of the Code Mode MCP guide pages

    The description states the Code Mode MCP guides were "Left alone", but the changed-file index shows src/content/docs/agents/model-context-protocol/codemode.mdx and src/content/docs/agents/model-context-protocol/guides/build-codemode-openapi-mcp-server.mdx were removed (117 and 216 lines), and build-codemode-mcp-server.mdx was substantially rewritten (+230 -15), absorbing the OpenAPI search-and-execute content. The two redirects added in public/__redirects confirm these were removed/moved pages. Removed or moved pages and substantial rewrites are core changes the description should name.

Not reviewed (2)
  • src/content/docs/agents/model-context-protocol/codemode.mdx — deleted file
  • src/content/docs/agents/model-context-protocol/guides/build-codemode-openapi-mcp-server.mdx — deleted file
Resolved (1) · Dismissed (0)
  • Resolved: Use TypeScriptExample for the code example · Verified at head via read_repo_file: every runnable code example in handler-api.mdx is now wrapped in <TypeScriptExample>, including the tracked createServer/getMcpAuthContext snippet (wrappers added in this PR). Remaining raw ts fences are pre-existing type/signature declarations, not the flagged code example.
Commands
  • /review Run a review now.
  • /full-review Review the entire PR diff.
  • /disable-auto-review Stop automatic reviews.
  • /rebase Rebase against production.

@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review coverage

✅ All 7 ownership areas are covered.

✅ 7 areas already covered
Area Approved by
workers
1 file changed
irvinebroque
Other
1 file changed
/public/__redirects
irvinebroque
access
1 file changed
irvinebroque
agent-lee
1 file changed
irvinebroque
agents
21 files changed
/src/content/docs/agents/
aron-cf, irvinebroque
agents
1 file changed
/src/content/partials/agents/
irvinebroque
agents
1 file changed
/src/content/changelog/agents/
aron-cf, irvinebroque
CODEOWNERS mappings for displayed areas (7)
Pattern Owners
/src/content/docs/workers/ @GregBrimble, @irvinebroque, @korinne, @MattieTK, @mikenomitch, @vy-ton, @WalshyDev, @cloudflare/deploy-config, @cloudflare/dev-plat-leads, @cloudflare/workers-runtime-1, @cloudflare/wrangler, @cloudflare/product-owners
/public/__redirects @cloudflare/product-owners, @cloudflare/content-engineering
/src/content/changelog/access/ @asamborski, @cloudflare/pm-changelogs, @cloudflare/product-owners
/src/content/docs/agent-lee/ @Brayden, @kczajkowski, @cloudflare/product-owners
/src/content/docs/agents/ @irvinebroque, @rita3ko, @cloudflare/ai-agents, @cloudflare/dev-plat-leads, @cloudflare/product-owners
/src/content/partials/agents/ @irvinebroque, @rita3ko, @thomasgauvin, @vy-ton, @cloudflare/product-owners
/src/content/changelog/agents/ @irvinebroque, @rita3ko, @cloudflare/ai-agents, @cloudflare/dev-plat-leads, @cloudflare/pm-changelogs, @cloudflare/product-owners

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Worker Preview URL: https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com
Worker Preview Deployment URL: https://f89a86f3.previews.developers.cloudflare.com

Files with changes (up to 15)

Original Link Updated Link
https://developers.cloudflare.com/agents/model-context-protocol/guides/securing-mcp-server/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/guides/securing-mcp-server/
https://developers.cloudflare.com/agents/model-context-protocol/protocol/authorization/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/protocol/authorization/
https://developers.cloudflare.com/agents/model-context-protocol/apis/handler-api/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/apis/handler-api/
https://developers.cloudflare.com/agents/model-context-protocol/apis/agent-api/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/apis/agent-api/
https://developers.cloudflare.com/agents/model-context-protocol/protocol/transport/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/protocol/transport/
https://developers.cloudflare.com/agents/model-context-protocol/guides/build-codemode-mcp-server/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/guides/build-codemode-mcp-server/
https://developers.cloudflare.com/agents/model-context-protocol/protocol/tools/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/protocol/tools/
https://developers.cloudflare.com/agents/model-context-protocol/guides/build-codemode-openapi-mcp-server/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/guides/build-codemode-openapi-mcp-server/
https://developers.cloudflare.com/agents/model-context-protocol/guides/remote-mcp-server/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/guides/remote-mcp-server/
https://developers.cloudflare.com/agents/model-context-protocol/codemode/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/codemode/
https://developers.cloudflare.com/agents/tools/payments/x402/charge-for-mcp-tools/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/tools/payments/x402/charge-for-mcp-tools/
https://developers.cloudflare.com/agents/tools/payments/mpp/accept-payments/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/tools/payments/mpp/accept-payments/
https://developers.cloudflare.com/agents/model-context-protocol/apis/client-api/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agents/model-context-protocol/apis/client-api/
https://developers.cloudflare.com/workers/demos/chatgpt-app/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/workers/demos/chatgpt-app/
https://developers.cloudflare.com/agent-lee/ https://gh-docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com/agent-lee/

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://docs-agents-mcp-createmcphandler-only.previews.developers.cloudflare.com (commit 500ab8c)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://bde58c48.previews.developers.cloudflare.com 500ab8c 2026-10-23T08:18:02.133Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://801b2183.previews.developers.cloudflare.com 0555b92 2026-10-22T17:15:57.163Z Visit the dashboard ↗
  • Build: In progress 🔵

View logs ↗
9c3a452 2026-10-22T16:54:31.093Z View logs ↗
  • Build: Failed ❌

View logs ↗
8021516 2026-10-22T16:53:35.531Z View logs ↗
  • Build: In progress 🔵

View logs ↗
707d572 2026-10-22T16:47:01.910Z View logs ↗
  • Build: In progress 🔵

View logs ↗
02fd30c 2026-10-22T16:42:56.176Z View logs ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://8abe9004.previews.developers.cloudflare.com d3c830b 2026-10-22T16:24:21.470Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://2ddbcaf6.previews.developers.cloudflare.com 2af5b92 2026-10-22T11:23:43.823Z Visit the dashboard ↗

Restore agent-api.mdx as the reference for existing McpAgent servers and move
the McpAgent RPC transport and this.props auth examples there, so removing
them from the transport and authorization pages loses nothing. Point the
migration notes at it and drop the redirect.
Authorization now builds an OAuthAuthorizationServer and makes the MCP server
an OAuthResourceServer around createMcpHandler, validated over a Service
Binding. Securing MCP servers uses the library's consent and upstream sign-in
helpers instead of hand-rolled CSRF and state code. Drop the context.http.authInfo
claims (no provider release sets it) and fix the 1.x changelog's migration
links.
@mattzcarey
mattzcarey requested a review from a team as a code owner October 22, 2026 16:30
Replace the hand-written escape helper with an API table for describeConsent,
beginConsent, approveConsent, denyConsent and isConsentRemembered, and add one
for beginUpstream, finishUpstream and tokenExchangeCallback. The library returns
consent values but does not render HTML, so the page still escapes them.
Replace the April 2025 list with current guidance: keep tool definitions out of
the context window with Code Mode on the client or server, use granular
authorization with step-up, and declare accurate input and output schemas so
strict clients accept your tools.
Fold the Code Mode MCP server patterns page and the search-and-execute guide into
Build a Code Mode MCP server, which now covers choosing a pattern, wrapping an
existing server, and publishing a large API with search and execute. Redirect the
removed pages and update links.
@github-actions

Copy link
Copy Markdown
Contributor

This PR changes current filenames or deletes current files. Make sure you have redirects set up to cover the following paths:

  • /agents/model-context-protocol/codemode/
  • /agents/model-context-protocol/guides/build-codemode-openapi-mcp-server/

TypeScriptExample transpiles each block, so object-literal and route-handler
fragments failed the build. Use plain ts blocks for them.
Replace fragments in the handler API, tools, transport, authorization, and
securing pages with full modules wrapped in TypeScriptExample. The securing
guide now has a complete authorization server with a consent page, one that
signs users in with GitHub, and a resource server that checks scopes. Tool
examples declare output schemas and return structuredContent. The x402
paidTool signature becomes a parameter table. Every example type-checks against
agents 0.29, @modelcontextprotocol/server 2.3.1, and workers-oauth-provider
1.2.4, and was run under wrangler dev.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

product:access product:agent-lee Related to Agent Lee product product:agents Build and deploy AI-powered Agents on Cloudflare that can act autonomously. product:changelog product:workers Related to Workers product size/xl

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants