MCP魔改造:データベースとローカルAPIをClaudeエージェントに接続する
パワーユーザーにとってMCPが重要な理由
MCP以前は、IDEごとに独自のプラグイン形式がありました。AnthropicのModel Context Protocolは、AIクライアントが機能を発見する方法を標準化します。ツール一覧 → JSON引数でツール呼び出し → 構造化結果の返却です。つまり読み取り専用Postgresサーバーを1つ書けば、Claude Desktop・Cursor・その他のMCPホストに統合を書き直さず提供できます。
ハードコア開発者が注目する理由は次のとおりです。
- データベースを、毎回スキーマダンプを貼らずにクエリ可能なコンテキストにできる
- 社内API(課金、機能フラグ、デプロイ状態)を、コピペではなく型付きツールとして公開できる
- IDE+エージェントスタックで、Claude Code代替やOpenClawをリモートMacで動かす場合も同じツールチェーンを共有できる
公式リファレンス:Model Context Protocol 仕様およびAnthropic MCP ドキュメント。
60秒で理解するMCPアーキテクチャ
┌─────────────┐ JSON-RPC ┌──────────────────┐
│ MCP Host │ ◄──────────────► │ MCP Server │
│ (Claude / │ tools/resources │ (your custom code)│
│ Cursor) │ │ → DB / API / CLI │
└─────────────┘ └──────────────────┘
| 役割 | 例 | 責務 |
|---|---|---|
| ホスト | Claude Desktop、Cursor、Claude Code | サーバーを起動し、tools/callを送信し、結果を表示 |
| サーバー | 自作Node/Pythonバイナリ | list_tools、call_tool、任意でresources/readを実装 |
| トランスポート | stdio、SSE | ホストとサーバー間でJSON-RPCメッセージを運ぶ |
深度のルール:信頼境界ごとにサーバーを1つにします。本番書き込みアクセスと実験的シェルツールを同一バイナリに入れないでください。プロセスを分ければ、設定ブロック1つを無効化するだけで他に触れずに済みます。
トランスポート選択マトリクス
| トランスポート | レイテンシ | 最適な用途 | 設定ファイル(典型) |
|---|---|---|---|
| stdio | 最低 | ノートPC上のローカルDB、単一ユーザー | claude_desktop_config.json、Cursor mcp.json |
| SSE(HTTP) | +1ホップ | NAS、リモートMac、Dockerサイドカー上のサーバー | ホストURL http://host:port/sse |
| Streamable HTTP(新しいホスト) | SSEと同程度 | SSEと同様。ホスト版を確認 | ホストドキュメント参照 |
| シナリオ | 推奨トランスポート |
|---|---|
| Claude Desktopと同じマシンのSQLite | stdio |
| オフィスLAN上のPostgreSQL | ジャンプホスト上のSSEサーバー、またはSSHラッパー経由stdio |
| 社内RESTマイクロサービス5つ | 名前空間付きツールを公開するゲートウェイMCPサーバー1つ |
| チーム共有ツールカタログ | 常時稼働ホスト上の中央MCPサーバー(リモートMacセットアップ参照) |
パターン1 — データベースMCPサーバー
目標:モデルがPostgreSQL、MySQL、SQLiteに対して読み取り専用SQL(または定義済みクエリ)を実行できるようにします。
設計上の制約:
- 可能な限り任意SQLではなく名前付きツール(
query_sales_summary、list_tables)を公開する - 行数上限(例:最大200行)とステートメントタイムアウト(例:5秒)を強制する
- 接続文字列をモデル経由で渡さない — サーバー環境の
DATABASE_URLから読み込む
| ツール名 | 入力 | 出力 |
|---|---|---|
postgres_query_readonly | { "sql": "SELECT ..." } | JSON行+列名 |
describe_table | { "table": "orders" } | information_schemaからの列型 |
読み取り専用DBロールを使います:GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;
パターン2 — ローカルREST APIゲートウェイ
目標:既存HTTPエンドポイントをMCPツール化し、Claudeがチャット内に長寿命APIキーを保持しないようにします。
Claude → MCP tool "deploy_status" → your server → GET https://internal/api/v1/deployments
実装のヒント:
- 各ツールを1 HTTPメソッド+パステンプレートにマップする
- fetch前にスキーマ(Zod、Pydantic)で入力を検証する
- 巨大レスポンスは切り詰めJSON(先頭8 KB)と
truncated: trueフラグを返す - 相関IDはサーバー側でログ。ツール結果にシークレットをエコーしない
OpenClawワーカーがアドホックcurlの代わりにMCP経由で同じ社内APIを呼ぶ場合は、マルチエージェントオーケストレーションと相性が良いです。
パターン3 — IDEとリポジトリブリッジ
CursorとClaude CodeはすでにMCPクライアントを搭載しています。カスタムサーバーで次を公開できます。
- リポジトリツール:
git_diff_summary、run_linter(サンドボックス内) - ドキュメントリソース:
AGENTS.md、OpenAPI仕様のresources/read - ECC / プラグインフック:ECCインストール後、チームの
eccスクリプトを包むMCPツールを追加
IDEブリッジはチーム全体が1台のリモート開発ボックスを共有しない限りstdioローカルのままにしてください。
8ステップRunbook
ステップ1 — 公式SDKをインストール
Node(多くのホスト向け推奨):
mkdir mcp-company-gateway && cd mcp-company-gateway
npm init -y
npm install @modelcontextprotocol/sdk zod pg
Python代替:pip install mcp(MCP Python SDK参照)。
ステップ2 — 最小サーバーをスキャフォールド
src/index.tsを作成します:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({ name: "company-gateway", version: "1.0.0" });
server.tool("ping", {}, async () => ({
content: [{ type: "text", text: "pong" }],
}));
const transport = new StdioServerTransport();
await server.connect(transport);
一度実行:npx tsx src/index.ts — stdio待ちでブロックするのが正常です(出力なしも正常)。
ステップ3 — 読み取り専用Postgresツールを追加
export DATABASE_URL="postgresql://mcp_reader:****@127.0.0.1:5432/app"
postgres_query_readonlyを登録し、ZodでSQLを検証します。必ずSELECTで始まること、サーバー側で;とDDLキーワードを拒否します。
ステップ4 — Claude Desktopに登録
macOSでは~/Library/Application Support/Claude/claude_desktop_config.jsonを編集します:
{
"mcpServers": {
"company-gateway": {
"command": "npx",
"args": ["tsx", "/absolute/path/mcp-company-gateway/src/index.ts"],
"env": { "DATABASE_URL": "postgresql://mcp_reader@127.0.0.1:5432/app" }
}
}
}
Claude Desktopを再起動します。新しいチャットでハンマー/ツールアイコンにpingとpostgres_query_readonlyが表示されることを確認してください。
ステップ5 — Cursorに登録
プロジェクトまたはグローバルの.cursor/mcp.json:
{
"mcpServers": {
"company-gateway": {
"command": "npx",
"args": ["tsx", "/absolute/path/mcp-company-gateway/src/index.ts"]
}
}
}
Cursorウィンドウをリロードし、エージェントパネルから同じpingツールをテストしてください。
ステップ6 — リモートホスト向けSSE公開(任意)
MCPサーバーがリモートMac(チーム踏み台またはレンタルM4)で動く場合:
# Example: SDK HTTP/SSE transport on port 8787 — bind localhost only unless behind VPN
node dist/sse-server.js --port 8787 --host 127.0.0.1
SSHトンネル経由でホスト設定をurl: "http://127.0.0.1:8787/sse"に向けます:
ssh -L 8787:127.0.0.1:8787 user@remote-mac
認証なしのMCP SSEポートを公衆インターネットに晒さないでください。SSEリモート運用時は東京リージョンの常時稼働Mac miniノードも選択肢です。
ステップ7 — シークレットとサンドボックス
| ルール | 理由 |
|---|---|
シークレットはサーバーenvのみ。ツール引数に入れない | プロンプトインジェクションによる漏洩を防ぐ |
| 本番とステージングでサーバーを分離 | 環境横断クエリの誤操作を防ぐ |
サブプロセスツールにtimeoutと許可リスト | rm -rf級のミスをブロック |
ステップ8 — MCP Inspectorで検証
npx @modelcontextprotocol/inspector npx tsx src/index.ts
ホストUIを信頼する前に、手動でtools/listとtools/callを実行してください。監査のため、タイムスタンプ+OSユーザー(チャット内容ではない)でツール呼び出しをログします。
セキュリティとサンドボックスチェックリスト
- 分析ツールには読み取り専用DBロール。書き込みツールは開発マシン専用の第2サーバーに限定
- 全ツールで入力検証。32 KB超のネストオブジェクトを拒否
- 社内APIを包む場合はサーバープロセスからのネットワークegress許可リスト(iptablesまたはmacOSファイアウォール)
- SaaS向けOAuth — サーバー内でトークン更新。モデルには不透明な
tool_okのみ公開
専用MacでMCPを動かすタイミング
ノートPCのスリープでstdioサーバーが死にます。共有MCPカタログ(8人のエンジニアが同じPostgresツールを使う)を望むチームは、常時稼働のApple Silicon Mac上でサーバーを動かし、SSHトンネルまたはVPNで到達します。
これはインフラの選択であり、MCPの必須要件ではありません。16 GB M4は軽量MCPサーバープロセス3〜5個(各約80〜150 MB)とNodeツールチェーンを快適に動かせます。同一ボックスでDocker DBも動かす場合はRAMを増やしてください。
トラブルシューティング
エラー:起動直後に Connection closed
パターン:Claude Desktopログにサーバー終了コード1。
対処:同じcommand+argsをターミナルで実行。tsx欠如、絶対パス誤り、起動時例外を修正。MCPホストはUIにstderrを表示しません。
エラー:Tool not found / ツール一覧が空
パターン:設定JSONのサーバー名 typo、またはホスト未リロード。
対処:jq . claude_desktop_config.jsonでJSON検証。ウィンドウを閉じるだけでなくホストアプリを完全終了して再起動。
エラー:SSE 404 または CORS失敗
パターン:リモートURLのパス誤り(/sse vs /mcp)。
対処:SDK HTTPトランスポートのドキュメントとパスを一致。ssh -Lでトンネルし、設定では127.0.0.1を使う。
推奨パス
| 状況 | 推奨アクション |
|---|---|
| ソロ開発、DBはノートPC上 | stdio+Claude Desktop+Cursor mcp.json |
| チーム社内API | 名前空間付きツールのゲートウェイMCPサーバー1つ |
| DBはLAN、ノートは別場所 | ジャンプホスト上のMCPサーバー+SSE/stdioへのSSHトンネル |
| 同一ボックスで重いエージェント+MCP | Docker DB+OpenClaw扇出を共有するなら24 GB RAM |
| グリーンフィールド | 本番SQLの前にInspector+pingツールから開始 |
もしXならY:データが別マシンにあるなら、MCPサーバーをデータの隣に置き、ホストへトンネルする。Claudeに公衆インターネット上の生DBポートを渡さないでください。
FAQ
MCPとChatGPTプラグインの違いは何ですか?
MCPはオープンでホスト非依存のJSON-RPCプロトコルで、複数言語のSDKがあります。プラグインはプラットフォーム固有でした。MCPサーバーは自分が管理するローカルまたはリモートプロセスとして動き、ホストは起動または接続するだけです。
MySQLやSQLiteもPostgreSQLと同じ方法で接続できますか?
はい。サーバー実装(ドライバ+SQL方言)が変わるだけで、MCP表面(list_tools、call_tool)は同一です。読み取り専用接続と方言別のSELECTのみガードを使ってください。
Claude CodeはMCPカスタムサーバーをサポートしていますか?
2026年時点で、Claude CodeとCursorはClaude Desktopと同様のMCPクライアント設定をサポートしています。パスは製品ごとに異なります。AnthropicとCursorの最新ドキュメントでmcpServersの場所を確認してください。書いたサーバーコードはホスト間で再利用できます。
1つのサーバーに何個のツールを公開すべきですか?
信頼できるモデルルーティングのため、サーバーあたり約20ツール未満に留めてください。カタログが大きくなったらbilling-gateway、data-gateway、ops-gatewayのように分割します。ホスト設定ではそれぞれ別ブロックとして表示されます。
書き込みツール(DELETE、デプロイ)は安全に公開できますか?
非本番サーバーで、明示的な人間確認フローがある場合のみです。共有設定では読み取りツールを優先し、書き込みは上級開発者だけが個人設定で有効にする第2のMCPサーバーに限定してください。
MCPとリモートMacガイド
カスタムMCPサーバーを本番運用する前に、リモートMacセットアップとClaude Code代替ガイドを確認してください。