build-mcp-server-sdk-v2
Use if building MCP servers on @modelcontextprotocol/server v2 alpha — split packages, registerTool.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use if building MCP servers on @modelcontextprotocol/server v2 alpha — split packages, registerTool.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use skill if you are exhaustively testing or release-gating martool CLI commands in a source checkout or deployed Coolify container over SSH, without local Docker or provider spend.
Use if driving agent-browser for Chrome/CDP automation, @ref snapshots, tabs, or verification.
Use if testing or debugging an iOS app via agent-device CLI — simulator flows, evidence, bug triage.
Use if supervising Jean agents through MCP and Computer Use for monitoring, recovery, or closure.
Use if auditing or designing a CLI for agent/LLM use — JSON output, exit codes, non-interactive.
Use if auditing or designing an MCP server for agent-readiness — framework, security, context.
| name | build-mcp-server-sdk-v2 |
| description | Use if building MCP servers on @modelcontextprotocol/server v2 alpha — split packages, registerTool. |
Build and maintain MCP servers on the v2 alpha split-package SDK: @modelcontextprotocol/server, @modelcontextprotocol/client, @modelcontextprotocol/core, plus /node, /express, /hono adapters. ESM-only, Node 20+, Zod v4. Status as of 2026-05-09: latest npm tag is 2.0.0-alpha.2 — pin exact, plan rollback.
Trigger this skill if any of these are true:
package.json already depends on @modelcontextprotocol/server, @modelcontextprotocol/client, or @modelcontextprotocol/core.new McpServer(...) from @modelcontextprotocol/server and server.registerTool(...) with the high-level API.(args, ctx) with ctx.mcpReq.signal, ctx.mcpReq.log(), ctx.mcpReq.notify(), or ctx.http?.authInfo.NodeStreamableHTTPServerTransport from @modelcontextprotocol/node, or createMcpExpressApp() / createMcpHonoApp() from the official adapters.z.object({...}) from zod/v4, not raw-shape shorthand.Do NOT use this skill if any of these are true:
package.json depends on the single-package @modelcontextprotocol/sdk (v1) — use build-mcp-server-sdk-v1 instead.(args, extra) with extra.sendNotification, extra.authInfo, or extra.signal — that is v1; use build-mcp-server-sdk-v1.convert-mcp-sdk-v1-to-v2 (covers package split, import rewrite, extra → ctx mapping, OAuth replacement, staging strategy).mcp-use wrapper or @hono/mcp community middleware — use build-mcp-use-server, or migrate before applying official adapter patterns.build-mcp-* reference for protocol patterns.Run tree -L 3 and read package.json. v2 fingerprints (any one is sufficient):
| Signal | Where | Means |
|---|---|---|
@modelcontextprotocol/server (or /client, /core, /node, /express, /hono) | package.json dependencies | v2 split package |
import { McpServer, StdioServerTransport } from "@modelcontextprotocol/server" | source | v2 server entrypoint |
Handler signature (args, ctx) => … and ctx.mcpReq.* | source | v2 ServerContext |
import * as z from "zod/v4" | source | v2 Zod v4 path |
"type": "module" + Node 20+ | package.json / engines | v2 ESM-only target |
v1 anti-fingerprints (treat as wrong skill, redirect):
@modelcontextprotocol/sdk single package → build-mcp-server-sdk-v1extra.sendNotification, extra.authInfo, extra.signal → build-mcp-server-sdk-v1SSEServerTransport → v1 only; v2 removed itMcpServer from @modelcontextprotocol/server. The low-level Server class is deprecated for direct use.registerTool / registerResource / registerPrompt. Positional overloads were removed in v2.z.object({...})). Raw shapes are a v1 pattern; if a current alpha still accepts them, treat that as a migration shim, not the target.@modelcontextprotocol/node (e.g. NodeStreamableHTTPServerTransport). SSEServerTransport is removed.@modelcontextprotocol/express (createMcpExpressApp()). For Hono, use @modelcontextprotocol/hono. Do not silently substitute the community @hono/mcp package.jose) and forward auth into ctx.http?.authInfo. Treat any @modelcontextprotocol/server-auth-legacy as planned/open until npm publish is confirmed.--save-exact); never use ^ ranges across alphas.Inspect package.json and src/. Decide: existing v2 server (go to 2A), new v2 server (go to 2B), or wrong skill (redirect per When to use and stop).
Read the implementation. Verify:
ctx.mcpReq.signal, ctx.mcpReq.log(), ctx.mcpReq.notify(), ctx.http?.authInfo. Flag any extra.* access — that is v1 leakage.z.object() (not raw shapes) for new code. outputSchema present whenever the tool returns structuredContent.NodeStreamableHTTPServerTransport from @modelcontextprotocol/node for HTTP; StdioServerTransport from @modelcontextprotocol/server for stdio.createMcpExpressApp() or createMcpHonoApp() for HTTP framework wiring (DNS rebinding protection lives in the adapter).readOnlyHint, destructiveHint, idempotentHint, openWorldHint set deliberately for tools with side effects.Then make the requested change (add tool, fix bug, add auth middleware, etc.).
Decide:
stdio for local; Streamable HTTP for remote/multi-client.| Scenario | Read |
|---|---|
| New stdio server | references/guides/quick-start.md |
| New HTTP server (Express) | references/guides/transports.md + references/guides/framework-adapters.md |
| New HTTP server (Hono) | references/guides/transports.md + references/guides/framework-adapters.md |
| Add tools | references/guides/tools-and-schemas.md |
| Add resources or prompts | references/guides/resources-and-prompts.md |
| Add auth middleware | references/guides/authentication.md |
| Build an MCP client | references/guides/client-api.md |
| Sampling, elicitation, sessions, shutdown | references/guides/context-and-lifecycle.md |
| Working server examples | references/examples/server-recipes.md |
| Production hardening | references/patterns/production-patterns.md |
| Deploy (Docker, serverless, Workers) | references/patterns/deployment.md |
| Avoid common mistakes / v1 leakage | references/patterns/anti-patterns.md |
bash scripts/check-mcp-server-v2-version.sh from the project root (see scripts/check-mcp-server-v2-version.sh.md); unsafe alpha ranges must failnpm install --save-exact @modelcontextprotocol/server@2.0.0-alpha.2npm install zod@^4npm install --save-exact @modelcontextprotocol/node@2.0.0-alpha.2npm install --save-exact @modelcontextprotocol/express@2.0.0-alpha.2 expressnpm install --save-exact @modelcontextprotocol/hono@2.0.0-alpha.2 hono"type": "module" in package.json"module": "Node16", "moduleResolution": "Node16"Default sequence:
McpServer with { name, version } and optional { instructions, capabilities }.z.object({ field: z.string() }) (full schemas, not raw shapes).server.registerTool(name, config, handler) — inputSchema, annotations, handler (args, ctx) => CallToolResult.server.registerResource() if exposing data.server.registerPrompt() if providing templates.await server.connect(transport).SIGINT/SIGTERM → await server.close()).npm run build, focused tests if present.npx @anthropic-ai/mcp-inspector npx tsx src/index.ts.curl or Inspector.mcpc is installed, hand off to test-by-mcpc-cli. Minimum sequence: initialize → tools/list → one successful call → one invalid-arg call returning isError: true.isError: true), not a thrown protocol error.ctx.mcpReq is the access path, never extra.import { McpServer, StdioServerTransport } from "@modelcontextprotocol/server";
import * as z from "zod/v4";
const server = new McpServer(
{ name: "my-server", version: "1.0.0" },
{ instructions: "A helpful server" }
);
server.registerTool("greet", {
title: "Greet User",
description: "Greet a user by name",
inputSchema: z.object({ name: z.string().describe("The user's name") }),
annotations: { readOnlyHint: true, destructiveHint: false },
}, async ({ name }, ctx) => {
await ctx.mcpReq.log("info", `Greeting ${name}`);
return { content: [{ type: "text" as const, text: `Hello, ${name}!` }] };
});
const transport = new StdioServerTransport();
await server.connect(transport);
new McpServer(
{ name: string, version: string, description?: string, icons?: Icon[] },
{ capabilities?: ServerCapabilities, instructions?: string }
)
server.connect(transport: Transport): Promise<void>
server.close(): Promise<void>
server.registerTool(name, config, handler): RegisteredTool
server.registerResource(name, uri | template, config, handler): RegisteredResource
server.registerPrompt(name, config, handler): RegisteredPrompt
server.sendToolListChanged(): void
server.sendResourceListChanged(): void
server.sendPromptListChanged(): void
server.sendLoggingMessage(params): Promise<void>
server.isConnected(): boolean
server.experimental.tasks // ExperimentalMcpServerTasks
{
title?: string,
description?: string,
inputSchema?: AnySchema, // z.object({...}) — full Zod v4 schema
outputSchema?: AnySchema, // enables structuredContent validation
annotations?: ToolAnnotations,
_meta?: Record<string, unknown>,
}
// Tool handler: (args, ctx) => CallToolResult
// No-arg tool: (ctx) => CallToolResult
ctx.sessionId?: string
ctx.mcpReq.id: RequestId
ctx.mcpReq.method: string
ctx.mcpReq.signal: AbortSignal
ctx.mcpReq._meta?: RequestMeta
ctx.mcpReq.send(request, schema, options?): Promise<Result>
ctx.mcpReq.notify(notification): Promise<void>
ctx.mcpReq.log(level, data, logger?): Promise<void>
ctx.mcpReq.elicitInput(params): Promise<ElicitResult>
ctx.mcpReq.requestSampling(params): Promise<CreateMessageResult>
ctx.http?.authInfo?: AuthInfo
ctx.http?.req?: RequestInfo
ctx.http?.closeSSE?(): void
ctx.http?.closeStandaloneSSE?(): void
ctx.task?.id?: string
ctx.task?.store?: RequestTaskStore
import { ProtocolError, ProtocolErrorCode } from "@modelcontextprotocol/core";
// Hard protocol errors:
throw new ProtocolError(ProtocolErrorCode.InvalidParams, "Bad input");
// Soft tool errors (LLM can self-correct):
return { content: [{ type: "text", text: "Error: not found" }], isError: true };
z.object({...}) for every new tool schema. Raw shapes are v1 style; even if accepted, do not target them.isError: true for recoverable failures — the LLM self-corrects from soft errors.ctx.mcpReq.log() over console.error() so logs reach the client.ctx.mcpReq.elicitInput() over hand-rolled ctx.mcpReq.send() for user input requests.createMcpExpressApp() / createMcpHonoApp() instead of raw Express/Hono setup — DNS rebinding is handled inside.annotations field deliberately; fill all four when safety or side-effects matter.z.object().extra.sendNotification / extra.authInfo / extra.signal — those are v1; the v2 access path is ctx.mcpReq.* and ctx.http?.authInfo.@modelcontextprotocol/sdk — that is the v1 single package; in v2 you import from /server, /client, /core, /node, /express, /hono.SSEServerTransport — removed in v2; use Streamable HTTP.^ ranges for alpha packages — pin exact and plan rollback.v2 is pre-release alpha as of 2026-05-09. The latest npm split packages are at 2.0.0-alpha.2; main-branch PRs labeled v2.0.0-bc may not yet be published. Most production servers should remain on v1.x until v2 cuts a non-alpha stable release.
In practice:
^); alphas can break between patches.@modelcontextprotocol/sdk meta-package remains v1 on npm unless fresh npm view proves otherwise.@modelcontextprotocol/server-auth-legacy is planned/open; treat it as unpublished until npm view succeeds.Report v2 server work with: