Claude Code × MCP実践ガイド — 自作MCPサーバー構築から双方向活用まで
MCPの月間ダウンロード数が97Mを突破し、AIツール連携の事実上の標準プロトコルとなった2026年。Claude Codeは「MCPクライアント」として外部ツールに接続するだけでなく、claude mcp serveで自身をMCPサーバーとして公開できる稀有なAIツールだ。
本記事では、TypeScriptでカスタムMCPサーバーを構築してClaude Codeに統合する手順と、Claude Code自体を他のAIエディタに公開するパターンを、動くコード付きで一気通貫で解説する。
MCPとClaude Codeの現在地
MCPが業界標準になるまでの経緯
Model Context Protocol(MCP)は、Anthropicが2024年末にオープンソースで公開したAIツール連携のための標準プロトコルだ。公開からわずか16ヶ月で月間97Mダウンロードに到達し、4,750%という異常な成長率を記録した。現在ではChatGPT、Cursor、Gemini CLI、Windsurfなど主要AIツールが軒並み対応しており、もはや「Anthropic発のプロトコル」ではなく業界共通のインフラになっている。
MCP仕様の最新バージョンは「2025-03-26」だ。このバージョンでOAuth 2.1認証、Streamable HTTP、オーディオデータ対応等が追加された。2026年はWorking Group方式に移行し、Spec番号ベースのリリースは廃止されている。トランスポート層は、ローカル接続にはstdioが標準、リモート接続にはStreamable HTTPが現行標準となっている(SSEは非推奨)。
Claude Codeが持つ2つの顔 — クライアントとサーバー
Claude CodeのMCP対応には、他のAIツールにはない特徴がある。2つの方向でMCPエコシステムに参加できる点だ。
- MCPクライアント: 外部MCPサーバー(GitHub、DB、独自ツール等)に接続し、その機能をClaude Codeの中から呼び出す
- MCPサーバー:
claude mcp serveで自身のBash、Read、Write、Edit等のツールを公開し、CursorやWindsurfなど他のAIエディタから利用させる
この双方向性を活かすことで、Claude Codeを起点にしたAIツール連携の幅が大きく広がる。
パート1:Claude CodeをMCPクライアントとして使う
claude mcp addで既存MCPサーバーを接続する
既存のMCPサーバーを接続する最も手軽な方法はclaude mcp addコマンドだ。
# GitHub MCPサーバーを追加
claude mcp add github -- npx -y @modelcontextprotocol/server-github
# 環境変数でAPIキーを渡す場合
claude mcp add github \
-e GITHUB_TOKEN=ghp_xxxxxxxxxxxx \
-- npx -y @modelcontextprotocol/server-github
このコマンドを実行すると、settings.jsonに以下のような設定が追加される。
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_xxxxxxxxxxxx"
}
}
}
}
スコープの使い分け — local / project / user
claude mcp addには3つのスコープがある。
| スコープ | フラグ | 設定ファイル | 用途 |
|---|---|---|---|
| local | -s local(デフォルト) | .claude/settings.local.json | 個人的な実験 |
| project | -s project | .mcp.json | チームで共有 |
| user | -s user | ~/.claude/settings.json | 全プロジェクト共通 |
チーム開発ではprojectスコープで.mcp.jsonをリポジトリにコミットするのがおすすめだ。チーム全員が同じMCPツールを使える構成になる。
接続トラブルの定番パターンと対処法
正直、最初のMCP接続で一発で通る方が珍しい。よくあるハマりどころを先に押さえておこう。
- Node.jsパス問題:
npxが見つからないエラーが出る場合、フルパスで指定する(例:/usr/local/bin/npx)。特にlaunchdやデーモン環境で頻出する - 権限エラー: Claude Codeが新しいMCPツールを検出すると許可を求めてくる。
allowedToolsへの追加が必要 - 起動が遅い: v2.1.89以降では環境変数
MCP_CONNECTION_NONBLOCKING=trueを設定すると、MCPサーバーの起動を待たずにClaude Codeが立ち上がる
パート2:TypeScriptでカスタムMCPサーバーを作る
プロジェクトセットアップとSDK導入
既存のMCPサーバーだけでは物足りなくなったら、自作MCPサーバーの出番だ。@modelcontextprotocol/sdk(v1.29.0)を使えば、驚くほど少ないコードで動くサーバーが作れる。
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
npx tsc --init --module nodenext --moduleResolution nodenext --outDir dist
package.jsonに以下を追加する。
{
"type": "module",
"bin": {
"my-mcp-server": "./dist/index.js"
}
}
ツール定義 — Zodスキーマとハンドラ実装
サイコロを振るだけの例では味気ないので、プロジェクト内のTODOコメントを収集・分類するツールを実装する。開発中に散らばったTODOを一覧化するのは地味に便利だ。
#!/usr/bin/env node
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readdir, readFile } from "fs/promises";
import { join, relative } from "path";
const server = new McpServer({
name: "todo-collector",
version: "1.0.0",
});
async function findFiles(dir: string, ext: string[]): Promise<string[]> {
const files: string[] = [];
for (const entry of await readdir(dir, { withFileTypes: true, recursive: true })) {
if (entry.isFile() && ext.some(e => entry.name.endsWith(e))) {
files.push(join(entry.parentPath, entry.name));
}
}
return files;
}
server.tool(
"collect-todos",
"プロジェクト内のTODO/FIXME/HACKコメントを収集して分類する",
{
directory: z.string().describe("スキャン対象ディレクトリの絶対パス"),
extensions: z.array(z.string()).default([".ts", ".js", ".tsx", ".jsx"]),
},
async ({ directory, extensions }) => {
const files = await findFiles(directory, extensions);
const todos: { file: string; line: number; type: string; text: string }[] = [];
for (const file of files) {
const content = await readFile(file, "utf-8");
content.split("\n").forEach((ln, i) => {
const match = ln.match(/\/\/\s*(TODO|FIXME|HACK)[:\s]*(.*)/i);
if (match) {
todos.push({
file: relative(directory, file),
line: i + 1,
type: match[1].toUpperCase(),
text: match[2].trim(),
});
}
});
}
const summary = Object.groupBy(todos, t => t.type);
return {
content: [{ type: "text", text: JSON.stringify({ total: todos.length, byType: summary }, null, 2) }],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
Claude Codeに統合して動作確認
ビルドしてClaude Codeに登録する。
npx tsc
chmod +x dist/index.js
claude mcp add todo-collector -- node /path/to/my-mcp-server/dist/index.js
Claude Codeを起動し、/mcpコマンドで接続状態を確認する。todo-collectorがconnectedと表示されれば成功だ。あとは会話の中で「このプロジェクトのTODOを一覧にして」と頼めば、MCPツールが自動的に呼ばれる。
パート3:Claude Code自体をMCPサーバーとして公開する
claude mcp serveの仕組みと公開されるツール一覧
claude mcp serveを実行すると、Claude Codeがstdioトランスポートで以下のツールを公開する。
- Bash — シェルコマンド実行
- Read — ファイル読み取り
- Write — ファイル書き込み
- Edit — ファイル編集
- MultiEdit — 複数箇所の一括編集
- LS — ディレクトリ一覧
- Glob — パターンマッチ検索
- Grep — コンテンツ検索
- Agent — サブエージェント起動
- NotebookEdit — Jupyterノートブック編集
- NotebookRead — Jupyterノートブック読み取り
- TodoRead — タスク読み取り
- TodoWrite — タスク書き込み
- WebFetch — Web取得
- WebSearch — Web検索
注意すべき制約として、Claude Codeに接続中のMCPサーバーのツールはパススルーされない。つまり、Claude Codeにgithub MCPサーバーを接続していても、claude mcp serve経由でそのGitHubツールが使えるわけではない。
CursorからClaude Codeに接続する設定例
Cursorからの接続は.cursor/mcp.jsonに以下を記述する。
{
"mcpServers": {
"claude-code": {
"command": "claude",
"args": [
"mcp", "serve",
"--dangerously-skip-permissions",
"--allowedDirectories", "/Users/me/projects/my-app"
]
}
}
}
Windsurfの場合も同様に、MCP設定ファイルに上記と同じcommand/args構成を記述すればよい。
制約とセキュリティ上の注意点
--dangerously-skip-permissionsフラグは必須だ。このフラグなしではclaude mcp serveは動作しない。名前の通り、すべての権限チェックをバイパスする。
これはBashツール経由で任意のコマンドが実行可能であることを意味する。信頼できないクライアントからのアクセスは絶対に許可してはならない。--allowedDirectoriesでスコープを制限し、ローカル開発環境限定で使うことを強く推奨する。
実践Tips:MCP活用を安定運用するために
MCPサーバーのデバッグ手法
MCPサーバーの開発中は、Claude Codeに接続する前にスタンドアロンでテストするのが効率的だ。
# MCP Inspectorで単体テスト
npx @modelcontextprotocol/inspector node ./dist/index.js
MCP InspectorはブラウザベースのUIで、ツールの入出力を対話的に確認できる。Claude Codeに統合した後の接続確認にはclaude mcp listと/mcpコマンドを使う。
チーム開発での設定共有パターン
チームで同じMCPツールを使いたい場合、.mcp.jsonをリポジトリにコミットするのが最もシンプルだ。APIキーは.mcp.jsonに直接書かず、環境変数を参照する形にしておく。
{
"mcpServers": {
"internal-api": {
"command": "node",
"args": ["./tools/mcp-server/dist/index.js"],
"env": {
"API_KEY": "${INTERNAL_API_KEY}"
}
}
}
}
なお、v2.1.91以降ではtool result persistence overrideが導入され、MCPサーバーからの大きなレスポンス(最大500,000文字)をコンテキストに保持できるようになった。データ量の多いツールを使う場合は覚えておくとよい。
まとめ
Claude Codeは、MCPエコシステムにおいて3つのパターンで参加できる。
- MCPクライアントとして外部ツールの能力を借りる
- 自作MCPサーバーで独自のツールを追加する
- MCPサーバーとして自身の能力を他のAIツールに貸し出す
97Mダウンロードを超えたMCPは、もはや特定ツールのプラグイン機構ではなく、AIツール間の共通インフラだ。まずはclaude mcp addで既存サーバーを1つ接続するところから始め、自作MCPサーバーで自分のワークフローに最適化していこう。
