機能を学ぶ · COURSE
MCP サーバを 1 個自作する 90 分
TypeScript で stdio MCP の最小実装 → Claude Code に接続して動かす。
audience
Web エンジニア(TS 経験者)
duration
90分
lessons
6 章
reviewed
2026.05
2 分でコース概要を見る
先に読むとよい
このコースで作るもの
- 01動作する stdio MCP サーバ 1 個(TypeScript)
- 02Claude Code 接続済み .mcp.json
- 03チーム配布用 README + バージョン管理
達成目安
全 6 レッスンを読み、コース完了マークを付ける
未完了
クイズ 6 問に挑戦し、正答率 80% 以上
未挑戦
成果物 3 個を実際に手元に作る
自己チェック
コース構成
このコースで学ぶこと
- 01
なぜ自作する必要があるか
既製の MCP(GitHub / Slack / Postgres)で足りないとき、自社固有の API や内部 DB に Claude を繋ぐには自作が必要。
MCP は『Claude のツールを増やす』ための共通プロトコル。GitHub や Slack のような有名どころは公式実装が出回っていますが、社内 API・固有の業務システム・特殊な検索エンジンには既製品がありません。
自作するハードルは意外と低く、TypeScript なら 100 行未満で動く MCP が書けます。1 回作れば、社内で配布して『弊社専用ツール』として動かせる。
- 社内 API(在庫・顧客・予約システム等)に接続
- 特殊な業務ロジック(例:弊社の独自計算式)をツール化
- セキュリティ要件で SaaS 連携できない場合の代替
理解度チェック
Q1.MCP を自作する“最も自然な動機”はどれ?
- 02
TypeScript 環境の準備
Node.js + pnpm(or npm)+ @modelcontextprotocol/sdk が必要。プロジェクト初期化から。
bash# プロジェクト初期化 mkdir my-company-mcp && cd my-company-mcp pnpm init -y pnpm add @modelcontextprotocol/sdk pnpm add -D typescript @types/node tsx # tsconfig 最小 cat > tsconfig.json <<EOF { "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "esModuleInterop": true, "outDir": "dist" }, "include": ["src/**/*"] } EOF理解度チェック
Q1.TypeScript で自作 MCP を書くときに必要な公式 SDK は?
- 03
最小の stdio MCP(30 行)
「在庫数を返す」だけのシンプルな MCP。これが動けばあとは応用。
typescriptimport { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; const server = new Server({ name: "inventory", version: "0.1.0" }, { capabilities: { tools: {} }, }); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [{ name: "get_stock", description: "商品 SKU の在庫数を返す", inputSchema: { type: "object", properties: { sku: { type: "string" } }, required: ["sku"], }, }], })); server.setRequestHandler(CallToolRequestSchema, async (req) => { if (req.params.name === "get_stock") { const sku = (req.params.arguments as { sku: string }).sku; // ここで本物の在庫 DB を叩く const stock = await fetchStockFromCompanyAPI(sku); return { content: [{ type: "text", text: `${sku}: ${stock} 個` }] }; } throw new Error("Unknown tool"); }); async function fetchStockFromCompanyAPI(sku: string): Promise<number> { // 実装は省略:fetch で社内 API を叩く return 42; } const transport = new StdioServerTransport(); await server.connect(transport);src/index.ts 理解度チェック
Q1.MCP の `inputSchema` を JSON Schema 形式で書く意義は?
- 04
Claude Code に接続する
`.mcp.json` に登録するだけで、Claude が自社 MCP のツールを使えるようになる。
json{ "mcpServers": { "inventory": { "command": "node", "args": ["/absolute/path/to/my-company-mcp/dist/index.js"], "env": { "COMPANY_API_KEY": "${COMPANY_API_KEY}" } } } }.mcp.json — project スコープに置く 手を動かす
0 / 5
理解度チェック
Q1.自作 MCP を Claude Code に認識させる仕組みは?
- 05
ツールを増やす:3 つの定石パターン
1 つ動いたら、次は応用。読み取り・書き込み・検索の 3 パターンを覚えれば大抵カバー。
- **Read 系**:`get_<entity>` — ID や名前で取得
- **Search 系**:`search_<entity>` — クエリで複数件取得(ページング)
- **Write 系**:`create_<entity>` / `update_<entity>` — 必ず確認プロンプトを介在
理解度チェック
Q1.MCP ツールの命名で「読み取り / 検索 / 書き込み」の役割を識別しやすい組合せは?
- 06
チームに配布する
1 人で作って終わりはもったいない。GitHub に上げて、社内で `claude plugin install` できる形に。
Plugin 化すれば `.mcp.json` を社内で配布する代わりに、各自が 1 コマンドでインストールできるようになります。Marketplace を社内に立てれば、`claude plugin marketplace add` で社内全部の MCP が見えるように。
MCP 完全版手を動かす
0 / 4
理解度チェック
Q1.自作 MCP の Write 系ツール(create / update)を安全に配布するには?


