From a78a3e0037a09c82f2529da4153c56c7a6590a69 Mon Sep 17 00:00:00 2001 From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com> Date: Tue, 18 Aug 2026 12:17:04 -0700 Subject: [PATCH] Clarify MCP channel setup and authentication (#2254) Signed-off-by: Allen Zhou <46854522+allenzhou101@users.noreply.github.com> --- docs/channels/mcp.mdx | 52 +++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/docs/channels/mcp.mdx b/docs/channels/mcp.mdx index 4f49e25c7..7b4f98669 100644 --- a/docs/channels/mcp.mdx +++ b/docs/channels/mcp.mdx @@ -1,6 +1,6 @@ --- -title: "MCP" -description: "Publish an eve agent as a durable MCP invocation service with route authentication and OAuth discovery." +title: "MCP Channel" +description: "Publish an eve agent as an MCP server with auth support." --- The MCP channel lets clients such as Claude Code delegate durable work to an eve agent through four tools: `agent_start`, `agent_get`, `agent_update`, and `agent_cancel`. @@ -12,31 +12,31 @@ Use an [MCP connection](../connections/mcp) instead when your eve agent needs to Create `agent/channels/mcp.ts`. Authentication is required explicitly, even during development. ```ts title="agent/channels/mcp.ts" -import { localDev, vercelOidc } from "eve/channels/auth"; +import { localDev } from "eve/channels/auth"; import { mcpChannel } from "eve/channels/mcp"; export default mcpChannel({ - auth: [vercelOidc(), localDev()], + auth: localDev(), }); ``` -This accepts Vercel-issued bearer tokens in a deployment and admits a synthetic local principal under `eve dev` or `vercel dev`. `localDev()` checks the running environment, not the request hostname: accessing an `eve start` production process through localhost does not activate it. +This accepts a synthetic local principal under `eve dev` or `vercel dev` and rejects all requests in production. Before deploying, replace it with one of the production authentication modes below. `localDev()` checks the running environment, not the request hostname: accessing an `eve start` production process through localhost does not activate it. ### Routes The default Streamable HTTP endpoint is `/eve/v1/mcp`. Set `route` when the application should publish it somewhere else: ```ts title="agent/channels/mcp.ts" -import { none } from "eve/channels/auth"; +import { localDev } from "eve/channels/auth"; import { mcpChannel } from "eve/channels/mcp"; export default mcpChannel({ - auth: none(), + auth: localDev(), route: "/mcp", }); ``` -`none()` makes the endpoint public; use it only when anonymous access is intentional. The channel registers `GET`, `POST`, and `DELETE` at the selected route. +The channel registers `GET`, `POST`, and `DELETE` at the selected route. ## Interactive OAuth @@ -49,18 +49,17 @@ import { mcpChannel } from "eve/channels/mcp"; const issuer = "https://auth.example.com"; const resource = "https://agent.example.com/eve/v1/mcp"; +const authenticateRequest = oidc({ + issuer, + audiences: [resource], +}); + export default mcpChannel({ - auth: oauthResource( - oidc({ - audiences: [resource], - issuer, - }), - { - issuer, - resource, - scopes: ["agent:invoke"], - }, - ), + auth: oauthResource(authenticateRequest, { + issuer, + resource, + scopes: ["agent:invoke"], + }), }); ``` @@ -132,6 +131,21 @@ When a protected request has no accepted credentials, eve returns a Bearer chall For the complete strategy and auth-walk model, see [Authentication](../guides/auth-and-route-protection). +### Public access + +To intentionally expose the MCP endpoint without authentication, use `none()`: + +```ts title="agent/channels/mcp.ts" +import { none } from "eve/channels/auth"; +import { mcpChannel } from "eve/channels/mcp"; + +export default mcpChannel({ + auth: none(), +}); +``` + +This allows anyone to invoke the agent. Every caller shares the anonymous principal, so invocation IDs become bearer capabilities until workflow retention expires. Use public access only when anonymous invocation is intentional. + ## HTTP security The MCP transport validates the request before authentication: