From session-orchestrator
Guides building TypeScript MCP servers for Model Context Protocol tools, through research, implementation with SDK/pnpm/Zod, testing, and evaluation.
npx claudepluginhub kanevry/session-orchestrator --plugin session-orchestratorThis skill uses the workspace's default tool permissions.
Adapted from [anthropics/skills/mcp-builder](https://github.com/anthropics/skills/tree/main/skills/mcp-builder). MCP-server quality is measured by how well it lets LLMs accomplish real-world tasks — not by endpoint count.
Guides building MCP servers in TypeScript enabling LLMs to interact with external services via tools. Covers protocol research, best practices, workflow design, and error handling.
Guides building high-quality MCP servers enabling LLMs to interact with external services via tools. Use when developing servers to integrate APIs in Python (FastMCP) or Node/TypeScript (MCP SDK).
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Adapted from anthropics/skills/mcp-builder. MCP-server quality is measured by how well it lets LLMs accomplish real-world tasks — not by endpoint count.
stdio for local tools, Streamable HTTP (stateless JSON) for remote@modelcontextprotocol/sdkAPI coverage vs. workflow tools. Balance comprehensive endpoint coverage with specialized workflow shortcuts. Default to coverage unless you have a clear reason — agents compose basic tools well; workflow tools ossify.
Tool naming & discoverability. Consistent prefix + action verb. Examples:
github_create_issue, github_list_reposgitlab_search_issues, gitlab_close_mrContext management. Return focused, paginated data. Agents suffer when a single tool call floods context.
Actionable error messages. Errors must guide the next action:
❌ "Invalid input"
✅ "Field 'project_id' is required. Call gitlab_list_projects to enumerate available IDs."
https://modelcontextprotocol.io/sitemap.xml.md to any page URL for markdown (e.g. https://modelcontextprotocol.io/specification/draft.md)Focus on: tool definitions, resource definitions, transport mechanisms.
https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/main/README.mdhttps://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.mdFetch via WebFetch only when needed — don't dump entire docs into context upfront.
mcp-server-name/
├── package.json
├── tsconfig.json
├── src/
│ ├── index.ts (server entry, transport wiring)
│ ├── tools/ (one file per tool or tool group)
│ ├── schemas.ts (shared Zod schemas)
│ └── client.ts (API client with auth + error handling)
└── README.md (setup + config)
Build once, reuse everywhere:
For each tool:
Input schema — Zod, with descriptions per field:
z.object({
projectId: z.string().describe("GitLab project ID. Call gitlab_list_projects to discover."),
state: z.enum(["opened", "closed", "all"]).default("opened"),
});
Output schema — define outputSchema where possible; use structuredContent in tool responses (TS SDK feature). This helps downstream agents parse results.
Annotations — set all four:
readOnlyHint: true/falsedestructiveHint: true/falseidempotentHint: true/falseopenWorldHint: true/falseThese inform Claude's hook decisions (destructive-guard, permission prompts).
Implementation — async/await for I/O; errors must surface with enough context for the LLM to fix them.
tsgo --noEmit or tsc --noEmit cleanpnpm build # or npm run build in non-pnpm projects
npx @modelcontextprotocol/inspector # interactive testing UI
Walk through every tool in the Inspector. If a tool can fail, trigger the failure and verify the error message is actionable.
Create 10 evaluation questions. An MCP server without evals is a guess, not a deliverable.
Each question must be:
<evaluation>
<qa_pair>
<question>Which GitLab project in group 'X' has the highest number of open issues labeled 'bug'?</question>
<answer>project-name-here</answer>
</qa_pair>
</evaluation>
Run the eval via: Claude-with-MCP-server on each question, compare output to expected answer. Any eval below 80% accuracy signals tool-design problems (usually: unclear descriptions, missing pagination, or bad error messages).
| Pitfall | Fix |
|---|---|
| Tool returns 10k rows, agent context blows up | Add pagination + default page size |
| Agent can't figure out auth failure | Error message: "Set ENV_VAR_NAME — current value is empty" |
| Tool name collision across MCP servers | Always prefix with service name |
Destructive tools without destructiveHint: true | Breaks our destructive-guard hook |
| Async errors swallowed | Wrap every handler in try/catch that returns structured error |
Upstream reference material (worth reading once, not mirroring here):