スキル一覧に戻る

scaffold-mcp-server

pjt222
更新日 Yesterday
1 閲覧
17
2
17
GitHubで表示
テストaitestingmcp

について

このClaudeスキルは、公式TypeScriptまたはPython SDKを使用して、ツール仕様から完全に実行可能なMCPサーバープロジェクトを生成します。適切な構造(トランスポート設定、ツールハンドラー、テストハーネスを含む)を作成します。新しいMCPサーバーの開始、既存統合の移行、またはテスト用ツールサーフェスのプロトタイピングを行う際にご利用ください。

クイックインストール

Claude Code

推奨
メイン
npx skills add pjt222/agent-almanac -a claude-code
プラグインコマンド代替
/plugin add https://github.com/pjt222/agent-almanac
Git クローン代替
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/scaffold-mcp-server

このコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします

ドキュメント

Scaffold MCP Server

Generate complete, runnable MCP server project from tool spec. Use official MCP SDK for TypeScript or Python.

When Use

  • Have tool spec (from analyze-codebase-for-mcp or written) and need working server
  • Start new MCP server project, want correct structure from start
  • Migrate existing tool integration to MCP protocol
  • Prototype tool surface to test with Claude Code before full impl
  • Need both server scaffold + test harness for CI

Inputs

  • Required: Tool spec doc (YAML or JSON with tool names, params, return types)
  • Required: Target language (typescript or python)
  • Required: Transport type (stdio or sse)
  • Optional: Output dir (default: current)
  • Optional: Package name + version
  • Optional: Auth method (none, bearer-token, api-key)
  • Optional: Docker packaging (true or false, default: false)

Steps

Step 1: Select SDK Language and Transport

1.1. Choose language by project context.

  • TypeScript: Best for Node.js, web tools, JSON-heavy
  • Python: Best for data science, ML, scientific computing

1.2. Choose transport.

  • stdio: Default for local. Claude Code launches server as subprocess.
  • SSE (Server-Sent Events): For remote/shared. Needs HTTP hosting.

1.3. Determine auth.

  • none: Local stdio (process-level trust)
  • bearer-token: Remote SSE with static tokens
  • api-key: Remote with per-client keys

Got: Clear language, transport, auth choices documented.

If fail: Requirements ambiguous? Default TypeScript + stdio + no auth for fastest time-to-working-server.

Step 2: Initialize Project Structure

2.1. Create project dir + init.

TypeScript:

mkdir -p $PROJECT_NAME && cd $PROJECT_NAME
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
npx tsc --init --target ES2022 --module nodenext --moduleResolution nodenext --outDir dist

Python:

mkdir -p $PROJECT_NAME && cd $PROJECT_NAME
python -m venv .venv
source .venv/bin/activate
pip install mcp pydantic

2.2. Standard dir structure.

$PROJECT_NAME/
├── src/
│   ├── index.ts|main.py      # Server entry point
│   ├── tools/                 # One file per tool category
│   │   ├── index.ts|__init__.py
│   │   └── [category].ts|.py
│   └── utils/                 # Shared utilities
│       └── validation.ts|.py
├── test/
│   ├── harness.ts|.py         # MCP test harness
│   └── tools/
│       └── [category].test.ts|.py
├── package.json|pyproject.toml
├── tsconfig.json              # TypeScript only
├── Dockerfile                 # If Docker requested
└── README.md

2.3. Add bin entry for npm (TS) or entry point for Python.

TypeScript package.json:

{
  "name": "$PACKAGE_NAME",
  "version": "1.0.0",
  "type": "module",
  "bin": { "$PACKAGE_NAME": "./dist/index.js" },
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsx src/index.ts",
    "test": "tsx test/harness.ts"
  }
}

Got: Buildable project skeleton with all deps installed.

If fail: npm/pip install fails? Check network + registry access. TS: ensure Node.js >= 18. Python: ensure Python >= 3.10.

Step 3: Implement Tool Handlers from Spec

3.1. Parse tool spec doc, generate handler per tool.

TypeScript handler template:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export function registerTools(server: McpServer): void {
  server.tool(
    "tool_name",
    "Tool description from spec",
    {
      param1: z.string().describe("Parameter description"),
      param2: z.number().optional().default(10).describe("Optional param"),
    },
    async ({ param1, param2 }) => {
      try {
        // TODO: Implement tool logic
        const result = await performAction(param1, param2);
        return {
          content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
        };
      } catch (error) {
        return {
          content: [{ type: "text", text: `Error: ${(error as Error).message}` }],
          isError: true,
        };
      }
    }
  );
}

Python handler template:

from mcp.server import Server
from mcp.types import Tool, TextContent
from pydantic import BaseModel

class ToolNameParams(BaseModel):
    param1: str
    param2: int = 10

async def handle_tool_name(params: ToolNameParams) -> list[TextContent]:
    try:
        result = await perform_action(params.param1, params.param2)
        return [TextContent(type="text", text=json.dumps(result, indent=2))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

3.2. Generate one handler file per tool category from spec.

3.3. Add input validation beyond type check.

  • String length limits
  • Numeric range bounds
  • Enum value constraints
  • Required field enforcement

3.4. Add structured error responses for all anticipated failures.

Got: Handler file per category with typed params + error handling.

If fail: Spec contains ambiguous types? Default to string, add TODO for manual refinement.

Step 4: Configure Transport

4.1. Make server entry with chosen transport.

stdio (TypeScript):

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { registerTools } from "./tools/index.js";

const server = new McpServer({
  name: "$PACKAGE_NAME",
  version: "1.0.0",
});

registerTools(server);

const transport = new StdioServerTransport();
await server.connect(transport);

SSE (TypeScript):

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { registerTools } from "./tools/index.js";

const server = new McpServer({
  name: "$PACKAGE_NAME",
  version: "1.0.0",
});

registerTools(server);

const transport = new SSEServerTransport("/messages", response);
await server.connect(transport);

4.2. If auth needed, add middleware.

  • Bearer token: validate Authorization header
  • API key: validate X-API-Key header

4.3. Add shebang for stdio servers to enable direct exec.

#!/usr/bin/env node

Got: Working entry that starts MCP server on configured transport.

If fail: SDK version does not match import paths? Check @modelcontextprotocol/sdk version, adjust imports. SDK restructured paths between versions.

Step 5: Create Test Harness

5.1. Build harness that validates every tool.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

async function runTests(): Promise<void> {
  const server = createServer();
  const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();

  await server.connect(serverTransport);
  const client = new Client({ name: "test-client", version: "1.0.0" });
  await client.connect(clientTransport);

  // Test: tools/list returns all expected tools
  const tools = await client.listTools();
  console.assert(tools.tools.length === EXPECTED_TOOL_COUNT);

  // Test: each tool with valid input
  for (const tool of tools.tools) {
    const result = await client.callTool({
      name: tool.name,
      arguments: getTestInput(tool.name),
    });
    console.assert(!result.isError, `${tool.name} failed`);
  }

  // Test: each tool with invalid input returns isError
  for (const tool of tools.tools) {
    const result = await client.callTool({
      name: tool.name,
      arguments: getInvalidInput(tool.name),
    });
    console.assert(result.isError, `${tool.name} should reject invalid input`);
  }

  console.log("All tests passed");
}

5.2. Make test fixtures per tool: valid, invalid, edge cases.

5.3. Add test script to package.json or pyproject.toml.

Got: Test harness exercises every tool with valid + invalid inputs.

If fail: InMemoryTransport not in SDK version? Fall back to spawning server as subprocess, communicate via stdio pipes.

Step 6: Generate Documentation and Configuration

6.1. Generate README.md with.

  • Project description
  • Install instructions
  • Claude Code config command
  • Claude Desktop JSON snippet
  • Tool listing with descriptions, param schemas
  • Dev + testing instructions

6.2. Generate Claude Code registration command.

# stdio transport
claude mcp add $PACKAGE_NAME stdio "node" "dist/index.js"

# SSE transport
claude mcp add $PACKAGE_NAME -e API_KEY=your_key -- mcp-remote http://localhost:3000/mcp

6.3. Generate Claude Desktop config snippet.

{
  "mcpServers": {
    "$PACKAGE_NAME": {
      "command": "node",
      "args": ["path/to/dist/index.js"]
    }
  }
}

6.4. If Docker requested, generate Dockerfile.

FROM node:20-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-slim
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json .
ENTRYPOINT ["node", "dist/index.js"]

Got: Complete docs + config files for immediate use.

If fail: README has placeholder values? Search project for actual values to substitute. Docker build fails? Verify base image matches Node.js/Python version used.

Checks

  • Project builds without errors (npm run build or equiv)
  • Server starts, responds to tools/list JSON-RPC request
  • Every tool from spec registered, discoverable
  • Test harness passes for all tools with valid inputs
  • Test harness confirms error responses for invalid inputs
  • Claude Code can connect via claude mcp add command
  • README has working install + config instructions
  • All generated code passes linting (if configured)

Pitfalls

  • SDK import path changes: @modelcontextprotocol/sdk package restructured exports between versions. Always check installed version's actual export paths.
  • Forget shebang: stdio servers invoked direct need #!/usr/bin/env node as first line to be executable.
  • Block event loop: Tool handlers in TS must be async. Sync ops block all other tool calls on server.
  • Missing type: "module" in package.json: MCP SDK uses ESM imports. Without it, Node.js treats files as CommonJS, imports fail.
  • Zod schema drift: Tool spec evolves but Zod schemas not updated = validation mismatches = silent failures. Generate schemas from single source of truth.
  • stdout pollution: stdio transport uses stdout for JSON-RPC. Any console.log in tool handlers corrupts protocol stream. Use console.error or file logger.

See Also

  • analyze-codebase-for-mcp - generate tool spec this skill consumes
  • build-custom-mcp-server - manual server impl for complex cases
  • configure-mcp-server - connect scaffolded server to Claude Code/Desktop
  • troubleshoot-mcp-connection - debug connectivity issues after deployment
  • containerize-mcp-server - package server in Docker for distribution

GitHub リポジトリ

pjt222/agent-almanac
パス: i18n/caveman/skills/scaffold-mcp-server
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

関連スキル

evaluating-llms-harness

テスト

このClaudeスキルは、lm-evaluation-harnessを実行し、MMLUやGSM8Kなど60以上の標準化学術タスクでLLMをベンチマークします。開発者がモデルの品質を比較し、トレーニングの進捗を追跡し、学術的な結果を報告するために設計されています。このツールはHuggingFaceやvLLMモデルを含む様々なバックエンドをサポートしています。

スキルを見る

cloudflare-cron-triggers

テスト

このスキルは、cron式を使用してWorkersをスケジュールするためのCloudflare Cron Triggersの実装に関する包括的な知識を提供します。定期的なタスクの設定、メンテナンスジョブ、自動化されたワークフローの構築を網羅し、無効なcron式やタイムゾーン問題といった一般的な課題への対処法も含みます。開発者はこれを使用して、スケジュールされたハンドラーの設定、cronトリガーのテスト、WorkflowsやGreen Computeとの連携を構成できます。

スキルを見る

webapp-testing

テスト

このClaude Skillは、Playwrightベースのツールキットを提供し、Pythonスクリプトを通じてローカルWebアプリケーションのテストを可能にします。フロントエンドの検証、UIデバッグ、スクリーンショット撮影、ログ表示を実現し、サーバーライフサイクルを管理します。ブラウザ自動化タスクにご利用いただけますが、コンテキストの汚染を避けるため、スクリプトのソースコードを読むのではなく直接実行してください。

スキルを見る

finishing-a-development-branch

テスト

このスキルは、開発者がテストの合格を確認し、構造化された統合オプションを提示することで、完成した作業を仕上げることを支援します。実装が完了した後のマージ、PR作成、ブランチの整理といったワークフローを案内します。コードが準備できてテスト済みの際に使用し、開発プロセスを体系的に完了させましょう。

スキルを見る