Skip to main content

working-on-mcp

MCP server and OAuth development conventions for Savecraft. Use when working on MCP tools, OAuth flows, auth middleware, or the MCP handler in worker/src/mcp/, worker/src/oauth.ts, or worker/src/auth.ts. Triggers on MCP tool implementation, OAuth provider, token validation, Clerk integration, or protected resource metadata.

インストールへ移動

ソース情報

リポジトリ
joshsymonds/savecraft.gg
ソースの最終更新活動
2026年3月28日 07:00
検出された SKILL.md の言語
英語
スター
12
フォーク
0

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
working-on-mcp
description
MCP server and OAuth development conventions for Savecraft. Use when working on MCP tools, OAuth flows, auth middleware, or the MCP handler in worker/src/mcp/, worker/src/oauth.ts, or worker/src/auth.ts. Triggers on MCP tool implementation, OAuth provider, token validation, Clerk integration, or protected resource metadata.
# Working on MCP & OAuth Read `docs/mcp.md` for tool contracts, OAuth flow, notes, and search architecture. Read `docs/mcp-design.md` for cross-platform MCP tool design best practices. ## Verification ```bash just test-worker # MCP tests are part of the Worker test suite ``` ## Architecture Rules **No SDK.** The MCP server is hand-rolled JSON-RPC 2.0 in `src/mcp/handler.ts`. The official `@modelcontextprotocol/sdk` depends on ajv/express/hono (CJS, incompatible with workerd). The Cloudflare `agents` SDK's `createMcpHandler` ignores the `env` parameter so tools can't access D1/R2 bindings. **Tool functions are pure.** Every tool in `src/mcp/tools.ts` takes `(db, snapshots, userUuid)` and returns a `ToolResult` or `ViewToolResult`. No side effects, no request objects, testable without the MCP protocol layer. **Two response formats.** `textResult(data, presentation?)` for tools without views (legacy, being migrated). `viewResult(structuredContent, narrative)` for tools with MCP Apps views — returns `{ structuredContent, content }` where the view widget renders `structuredContent` and the model uses `content` for its response. See `docs/views.md` and the `working-on-views` skill. **MCP Apps extension.** Server declares `extensions: { "io.modelcontextprotocol/ui": {} }` in the initialize response. Handler auto-wires `_meta.ui.resourceUri` on tool definitions from `views.gen.ts`. **Protocol version:** `2025-06-18`. Transport: Streamable HTTP (POST + JSON responses, not SSE). ## OAuth Architecture The Worker is itself the **OAuth 2.1 Authorization Server** via `@cloudflare/workers-oauth-provider`. Clerk is the upstream IdP only — users authenticate via Clerk, but the Worker issues its own opaque access tokens stored in `OAUTH_KV`. **Key properties:** - AI clients (Claude, ChatGPT, Gemini) never see Clerk. The entire OAuth dance happens against our origin. - Token validation is a KV lookup — no JWT signature check, no network call. - `ctx.props.userUuid` flows from Clerk's `sub` claim through to R2 prefix scoping. - Zero skip-Clerk paths in production. Authorize returns 503 if Clerk secrets are missing. - `OAUTH_ENDPOINTS` constant in `src/oauth.ts` is shared with test helpers. **Protected resource metadata gotcha:** RFC 8707 uses exact string comparison. MCP clients send `resource=https://host/` with trailing slash. The metadata `resource` URL MUST have the trailing slash or token validation silently fails. Our `index.ts` overrides the library's response to include the trailing slash. ## Auth Modes `src/auth.ts` handles two separate auth concerns: 1. **MCP OAuth** — handled by the `OAuthProvider` wrapper in `index.ts`. Token → KV lookup → `ctx.props.userUuid`. 2. **Session/daemon auth** — `src/auth.ts`. Stub mode: bearer token IS user UUID (when `CLERK_ISSUER` not set). Clerk mode: JWT validation via JWKS. These are separate concerns. Don't conflate them. ## Cloudflare Zone Gotcha `ai_bots_protection` must be `disabled` on the Cloudflare zone. Claude.ai's MCP client makes requests from Anthropic's IPs (`160.79.104-106.x`), and "Block AI Scrapers and Crawlers" silently blocks them at the edge. The OAuth flow completes but the authenticated MCP request never reaches the Worker. ## Key Paths ``` worker/src/mcp/handler.ts # JSON-RPC 2.0 routing worker/src/mcp/tools.ts # Pure tool functions worker/src/oauth.ts # OAUTH_ENDPOINTS, Clerk redirect logic worker/src/auth.ts # Session/daemon auth (stub + Clerk modes) worker/src/index.ts # OAuthProvider wrapper, protected resource metadata override ```
GitHubで見る