カスタム stdio MCP サーバ(Node.js の例)
自作の stdio MCP サーバを node と絶対パスで mcpServers に追加するパターン。MCP プロトコルを話すどんなローカルスクリプトにも適用できます。
詳細な説明
カスタム stdio サーバの組み込み
stdio は MCP のデフォルトトランスポートです。クライアントがバイナリを spawn し、その stdin に JSON-RPC フレームを書き込み、stdout から読みます。stderr に書いたものはクライアントの MCP デバッグログにキャプチャされます。
設定
{
"mcpServers": {
"my-tools": {
"command": "node",
"args": ["/Users/me/code/my-mcp-server/dist/index.js"],
"env": {
"LOG_LEVEL": "info",
"API_BASE": "https://api.internal.example.com"
}
}
}
}
なぜ絶対パスか
相対パスは クライアントの作業ディレクトリ から解決されます。ターミナルからではありません。macOS の Claude Desktop の場合は通常 / から解決されるため、./dist/index.js は失敗します。プロジェクトで pwd を実行して絶対パスを取り、args に貼ってください。
最小サーバの実装
公式 SDK を使うと数行で書けます:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({ name: "my-tools", version: "0.1.0" }, {
capabilities: { tools: {} },
});
server.setRequestHandler(/* ... */);
await server.connect(new StdioServerTransport());
tsc で dist/ にコンパイルし、エントリファイルを設定で指す形です。
env を安全に渡す
env の値は子プロセスに環境変数として設定されます。マシン依存の設定(LOG_LEVEL、API_BASE)やシークレット(API_TOKEN、DATABASE_URL)に使います。env に空でない値があるとジェネレーターのシークレット警告バナーが表示されます。
デバッグ
サーバから process.stderr に書き、Claude Desktop のログ ~/Library/Logs/Claude/mcp*.log を確認します — 詳細は デバッグログ を参照。
ユースケース
社内 API(認証、チケット、デプロイ Bot 等)を MCP サーバとしてラップし、curl コマンドを貼り付けずにモデルから呼ばせる用途です。カスタムサーバが認証トークンを保持し、モデルからは高レベルツールしか見えません。