Generate complete TypeScript MCP server projects with MCP TypeScript SDK v2 packages, tools, resources, prompts, transports, configuration, testing, migration guidance, and documentation. Use this skill when the user asks to generate a TypeScript MCP server, create an MCP tool server, migrate an MCP server from v1 to v2, or choose stdio versus HTTP transport.
Generate a production-ready Model Context Protocol server in TypeScript using MCP TypeScript SDK v2, explicit transport selection, full Zod schemas, typed tool handlers, and runnable project commands.
When to invoke
"Generate a TypeScript MCP server."
"Create an MCP server with tools and resources."
"Build an HTTP MCP server in Node."
"Migrate this MCP server from v1 to v2."
"Add stdio transport to a TypeScript MCP project."
Prerequisites and context
Target Node.js 20+ and ESM-first TypeScript with "type": "module".
Use MCP TypeScript SDK v2 focused packages; the v1 monolithic @modelcontextprotocol/sdk package is retired.
Choose either HTTP Streamable HTTP transport or stdio. SSE and WebSocket transports were removed in v2 and must not be generated.
Package and runtime choices
Need
Package or setting
Notes
Server implementation
@modelcontextprotocol/server
Provides McpServer; stdio transport is under @modelcontextprotocol/server/stdio.
Plain Node HTTP
@modelcontextprotocol/node
Use NodeStreamableHTTPServerTransport.
Framework HTTP
@modelcontextprotocol/express, @modelcontextprotocol/hono, or @modelcontextprotocol/fastify
Install the peer framework too, such as @modelcontextprotocol/express + express.
Web Standard runtimes
@modelcontextprotocol/server
Use WebStandardStreamableHTTPServerTransport.
Shared protocol schemas
@modelcontextprotocol/core
Import *Schema constants from here, not from sdk/types.js.
Validation
zod@^4.2
v2 requires Zod 4.2+; do not use zod@3.
Development runner
tsx or ts-node
Prefer tsx for ESM development.
Module system
"type": "module"
CommonJS is shipped, so require() works if needed, but new projects should be ESM-first.
Initialize with npm init, install runtime dependencies such as @modelcontextprotocol/server, zod@^4.2, and the chosen transport package, then add dev dependencies such as tsx and typescript.
Server implementation rules
Concern
Rule
Server
Use McpServer from @modelcontextprotocol/server; set server name and version.
Tool registration
Use registerTool() with a config object; v1 variadic .tool() signatures are gone.
Tool schemas
Use complete Zod objects such as z.object({ name: z.string() }); raw shape objects are deprecated.
Tool metadata
Provide clear title and description fields.
Tool result
Return content and structuredContent where structured data exists.
Handler context
Use the second structured ctx parameter: ctx.mcpReq.signal, ctx.mcpReq.id, ctx.mcpReq.send(...), ctx.mcpReq.notify(...).
HTTP headers
v2 uses Web Standard Headers/Request; read headers with ctx.http?.req?.headers.get('x-custom').
Errors
Use ProtocolError, SdkError, and SdkHttpError with .status; do not use v1 McpError, ErrorCode, or StreamableHTTPError.
Cleanup
Handle transport close events and async resource cleanup.
Configuration
Use environment variables for ports, API keys, and feature switches.
Add registerResource() with ResourceTemplate for dynamic URIs.
Prompts
Add registerPrompt() with argument schemas in the same config-object style as registerTool().
Completion
Use completable(z.string(), callback).optional(); apply .optional() outside the completable() wrapper.
LLM-assisted tools
Use the multi-round input_required pattern; the v2 sampling subsystem is deprecated.
Dynamic tools
Support enable/disable capabilities and notification debouncing for bulk updates when needed.
Resource links
Prefer links for large data references instead of embedding bulky content in tool responses.
Transport configuration
Transport
Use when
Required details
HTTP
Browser, remote, or multi-client usage.
Port from environment, CORS if browser clients need it, stateless versus stateful sessions, DNS rebinding protection for local servers, strict Content-Type handling because v2 rejects non-application/json POST bodies, and connection URL http://localhost:PORT/mcp.
stdio
Local editor or CLI host launches the server process.
Clean stdin/stdout handling, logs on stderr, environment-based config, and process lifecycle management.
Search for @mcp-codemod-error markers that need manual judgment.
Choose the v2 transport; do not recreate SSE or WebSocket.
Replace McpError + ErrorCode checks with ProtocolError, SdkError, or SdkHttpError; HTTP status is error.status, not error.code.
Remove deprecated Server.createMessage(), listRoots(), sendLoggingMessage(), and roots/sampling/logging capability fields from new code.
Testing guidance
Add scripts for npm start, npm run dev, npm run build, and npm test when the generated project includes tests.
Run the server with npm start or npx tsx src/index.ts.
Inspect with npx @modelcontextprotocol/inspector.
Include example tool invocations and expected content/structuredContent output in README.md.
Resource/Prompt generation may be included when useful. Stdio examples should import StdioServerTransport; stdio-based servers must keep stdout protocol-clean. Use TypeScript/Node.js project defaults, high-level McpServer APIs, async/await, and try-catch around external work. Remember that v1 called the handler context extra; v2 replaces it with ctx. Install adapter peers explicitly, for example npm install @modelcontextprotocol/express express. Migration command spelling must remain npx @modelcontextprotocol/codemod@latest v1-to-v2 .. A simple development command may be npx tsx server.ts. Schema examples may be shown as z.object({...}); do not pass raw { name: z.string() } shapes.
Project uses Node.js 20+, TypeScript, and "type": "module" unless the user requested otherwise.
v2 packages are used: @modelcontextprotocol/server, transport package, @modelcontextprotocol/core when schemas are needed, and zod@^4.2.
No new SSE, WebSocket, v1 .tool() signatures, raw schema shapes, McpError, ErrorCode, StreamableHTTPError, Server.createMessage(), listRoots(), sendLoggingMessage(), roots, sampling, or logging capability fields are generated.
At least one useful tool has a full Zod input schema, error handling, content, and structuredContent.
Transport configuration includes lifecycle, environment, and HTTP/stdout details.
README includes run commands, MCP Inspector command, HTTP URL when relevant, and example tool invocations.
1---2name: typescript-mcp-server-generator3description: Generate complete TypeScript MCP server projects with MCP TypeScript SDK v2 packages, tools, resources, prompts, transports, configuration, testing, migration guidance, and documentation. Use this skill when the user asks to generate a TypeScript MCP server, create an MCP tool server, migrate an MCP server from v1 to v2, or choose stdio versus HTTP transport.4---56<!-- Generated from harness/github-copilot/skills/typescript-mcp-server-generator/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# TypeScript MCP server generator910Generate a production-ready Model Context Protocol server in TypeScript using MCP TypeScript SDK v2, explicit transport selection, full Zod schemas, typed tool handlers, and runnable project commands.1112## When to invoke1314- "Generate a TypeScript MCP server."15- "Create an MCP server with tools and resources."16- "Build an HTTP MCP server in Node."17- "Migrate this MCP server from v1 to v2."18- "Add stdio transport to a TypeScript MCP project."1920## Prerequisites and context2122- Target Node.js `20+` and ESM-first TypeScript with `"type": "module"`.23- Use MCP TypeScript SDK v2 focused packages; the v1 monolithic `@modelcontextprotocol/sdk` package is retired.24- Choose either HTTP Streamable HTTP transport or stdio. SSE and WebSocket transports were removed in v2 and must not be generated.2526## Package and runtime choices2728| Need | Package or setting | Notes |29| --- | --- | --- |30| Server implementation | `@modelcontextprotocol/server` | Provides `McpServer`; stdio transport is under `@modelcontextprotocol/server/stdio`. |31| Plain Node HTTP | `@modelcontextprotocol/node` | Use `NodeStreamableHTTPServerTransport`. |32| Framework HTTP | `@modelcontextprotocol/express`, `@modelcontextprotocol/hono`, or `@modelcontextprotocol/fastify` | Install the peer framework too, such as `@modelcontextprotocol/express` + `express`. |33| Web Standard runtimes | `@modelcontextprotocol/server` | Use `WebStandardStreamableHTTPServerTransport`. |34| Shared protocol schemas | `@modelcontextprotocol/core` | Import `*Schema` constants from here, not from `sdk/types.js`. |35| Validation | `zod@^4.2` | v2 requires Zod 4.2+; do not use `zod@3`. |36| Development runner | `tsx` or `ts-node` | Prefer `tsx` for ESM development. |37| Module system | `"type": "module"` | CommonJS is shipped, so `require()` works if needed, but new projects should be ESM-first. |3839## Project structure4041```text42mcp-server/43├── package.json44├── tsconfig.json45├── .gitignore46├── README.md47└── src/48 ├── index.ts49 ├── server.ts50 ├── tools/51 │ └── greet.ts52 ├── resources/53 ├── prompts/54 └── config.ts55```5657Initialize with `npm init`, install runtime dependencies such as `@modelcontextprotocol/server`, `zod@^4.2`, and the chosen transport package, then add dev dependencies such as `tsx` and `typescript`.5859## Server implementation rules6061| Concern | Rule |62| --- | --- |63| Server | Use `McpServer` from `@modelcontextprotocol/server`; set server name and version. |64| Tool registration | Use `registerTool()` with a config object; v1 variadic `.tool()` signatures are gone. |65| Tool schemas | Use complete Zod objects such as `z.object({ name: z.string() })`; raw shape objects are deprecated. |66| Tool metadata | Provide clear `title` and `description` fields. |67| Tool result | Return `content` and `structuredContent` where structured data exists. |68| Handler context | Use the second structured `ctx` parameter: `ctx.mcpReq.signal`, `ctx.mcpReq.id`, `ctx.mcpReq.send(...)`, `ctx.mcpReq.notify(...)`. |69| HTTP headers | v2 uses Web Standard `Headers`/`Request`; read headers with `ctx.http?.req?.headers.get('x-custom')`. |70| Errors | Use `ProtocolError`, `SdkError`, and `SdkHttpError` with `.status`; do not use v1 `McpError`, `ErrorCode`, or `StreamableHTTPError`. |71| Cleanup | Handle transport close events and async resource cleanup. |72| Configuration | Use environment variables for ports, API keys, and feature switches. |7374```typescript75server.registerTool('greet', {76 title: 'Greet user',77 description: 'Greet user',78 inputSchema: z.object({ name: z.string() })79}, async ({ name }, ctx) => {80 return {81 content: [{ type: 'text', text: `Hello, ${name}!` }],82 structuredContent: { greeting: `Hello, ${name}!`, requestId: ctx.mcpReq.id }83 };84});85```8687## Resources, prompts, and advanced features8889| Feature | Rule |90| --- | --- |91| Resources | Add `registerResource()` with `ResourceTemplate` for dynamic URIs. |92| Prompts | Add `registerPrompt()` with argument schemas in the same config-object style as `registerTool()`. |93| Completion | Use `completable(z.string(), callback).optional()`; apply `.optional()` outside the `completable()` wrapper. |94| LLM-assisted tools | Use the multi-round `input_required` pattern; the v2 sampling subsystem is deprecated. |95| Dynamic tools | Support enable/disable capabilities and notification debouncing for bulk updates when needed. |96| Resource links | Prefer links for large data references instead of embedding bulky content in tool responses. |9798## Transport configuration99100| Transport | Use when | Required details |101| --- | --- | --- |102| HTTP | Browser, remote, or multi-client usage. | Port from environment, CORS if browser clients need it, stateless versus stateful sessions, DNS rebinding protection for local servers, strict `Content-Type` handling because v2 rejects non-`application/json` POST bodies, and connection URL `http://localhost:PORT/mcp`. |103| stdio | Local editor or CLI host launches the server process. | Clean stdin/stdout handling, logs on stderr, environment-based config, and process lifecycle management. |104105## Migration from v11061071. Run the official codemod:108109 ```bash110 npx @modelcontextprotocol/codemod@latest v1-to-v2 .111 ```1121132. Search for `@mcp-codemod-error` markers that need manual judgment.1143. Choose the v2 transport; do not recreate SSE or WebSocket.1154. Replace `McpError + ErrorCode` checks with `ProtocolError`, `SdkError`, or `SdkHttpError`; HTTP status is `error.status`, not `error.code`.1165. Remove deprecated `Server.createMessage()`, `listRoots()`, `sendLoggingMessage()`, and `roots`/`sampling`/`logging` capability fields from new code.117118## Testing guidance119120- Add scripts for `npm start`, `npm run dev`, `npm run build`, and `npm test` when the generated project includes tests.121- Run the server with `npm start` or `npx tsx src/index.ts`.122- Inspect with `npx @modelcontextprotocol/inspector`.123- Include example tool invocations and expected `content`/`structuredContent` output in `README.md`.124125Resource/Prompt generation may be included when useful. Stdio examples should import `StdioServerTransport`; stdio-based servers must keep stdout protocol-clean. Use TypeScript/Node.js project defaults, high-level `McpServer` APIs, async/await, and try-catch around external work. Remember that v1 called the handler context `extra`; v2 replaces it with `ctx`. Install adapter peers explicitly, for example `npm install @modelcontextprotocol/express express`. Migration command spelling must remain `npx @modelcontextprotocol/codemod@latest v1-to-v2 .`. A simple development command may be `npx tsx server.ts`. Schema examples may be shown as `z.object({...})`; do not pass raw `{ name: z.string() }` shapes.126127## Output template128129```markdown130## TypeScript MCP server result131132**Status:** generated | migrated | blocked133**Transport:** http | stdio134**Runtime:** Node.js 20+135136| Artifact | Path | Notes |137| --- | --- | --- |138| Package config | `package.json` | `<dependencies/scripts>` |139| Server entry | `src/index.ts` | `<transport>` |140| Tools | `src/tools/<tool>.ts` | `<schemas/results>` |141| Docs | `README.md` | `<run and inspector commands>` |142143**Commands**144- `npm install ...`: <pass/fail/not run>145- `npm run build`: <pass/fail/not run>146- `npx @modelcontextprotocol/inspector`: <usage documented/not run>147```148149## Quality gate150151- [ ] Project uses Node.js `20+`, TypeScript, and `"type": "module"` unless the user requested otherwise.152- [ ] v2 packages are used: `@modelcontextprotocol/server`, transport package, `@modelcontextprotocol/core` when schemas are needed, and `zod@^4.2`.153- [ ] No new SSE, WebSocket, v1 `.tool()` signatures, raw schema shapes, `McpError`, `ErrorCode`, `StreamableHTTPError`, `Server.createMessage()`, `listRoots()`, `sendLoggingMessage()`, `roots`, `sampling`, or `logging` capability fields are generated.154- [ ] At least one useful tool has a full Zod input schema, error handling, `content`, and `structuredContent`.155- [ ] Transport configuration includes lifecycle, environment, and HTTP/stdout details.156- [ ] README includes run commands, MCP Inspector command, HTTP URL when relevant, and example tool invocations.
Run npx skillmds@latest add paulasilvatech/typescript-mcp-server-generator in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Generate complete TypeScript MCP server projects with MCP TypeScript SDK v2 packages, tools, resources, prompts, transports, configuration, testing, migration guidance, and documentation. Use this skill when the user asks to generate a TypeScript MCP server, create an MCP tool server, migrate an MCP server from v1 to v2, or choose stdio versus HTTP transport. It is listed under AI & ML on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
paulasilvatech (@paulasilvatech) published this skill. Their other Agent Skills are listed on their SkillMD profile.