ゼロから MCP Server を開発する:AI ツール呼び出し完全ガイド
大規模言語モデルはどれほど高性能でも、社内データベースの照会、内部 API の呼び出し、ローカルファイルの読み取りを直接行うことはできません。これはモデルの能力不足ではなく、標準化されたツール呼び出しチャネルが欠けているためです。Model Context Protocol(MCP) は Anthropic がオープンソース化した解決策であり、Claude、Cursor、GPT が統一プロトコルで外部能力にアクセスできるようにします。本稿を読み終えると、Tools、Resources、Prompts の三大コア能力と HTTP リモート転送を含む、本番利用可能な MCP Server を独立して開発・デバッグ・デプロイできるようになります。
1. 三大課題:AI に MCP Server が必要な理由
最初の一行を書く前に、解決すべき実際の問題を整理しましょう。
- ツールの孤立:Function Calling、Plugins、LangChain Tools はそれぞれ異なるフォーマットで書かれており、モデルプロバイダーを変えるたびに統合層を書き直す必要があります——典型的な N×M 問題です。
- データへのアクセス不可:モデルの学習データにはカットオフ日があり、リアルタイムの設定、社内ドキュメント、データベースの状態を読み取れません。
- アクションの実行不可:純粋な対話型 AI は HTTP リクエストの送信、ファイルの書き込み、SQL の実行を代行できません——標準化されたツール層を通じてこれらの能力を公開する必要があります。
《MCP はなぜ AI 時代の HTTP 規格なのか》を既にお読みの方は、本稿ではプロトコル選定の議論を繰り返さず、コード実装に直接入ります。対象読者は Python または TypeScript の基礎を持つバックエンド/AI 開発者です。
2. MCP とは何か:プロトコル原理とアーキテクチャ概観
2.1 MCP の誕生背景
大規模言語モデルのツール呼び出し能力は三代にわたって進化してきました:Function Calling(OpenAI 独自フォーマット)→ Plugins(ChatGPT エコシステムの閉鎖型)→ MCP(2024 年 11 月 Anthropic がオープンソース化した開放プロトコル)。MCP が解決する核心問題は、AI と外部ツール間の通信を標準化すること——一度実装すれば複数クライアントで再利用できます。
2.2 プロトコルアーキテクチャ:Client ↔ Server ↔ 三大能力
┌────────────────────┐ ┌─────────────────────┐
│ MCP Client │ ◄─────► │ MCP Server │
│ (Claude / Cursor) │ JSON │ (あなたが開発する) │
│ │ -RPC │ │
└────────────────────┘ └─────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Tools Resources Prompts
(ツール呼出) (リソース読取) (プロンプト)
- Client:AI モデル側——Claude Desktop、Cursor、VS Code、カスタム Agent。
- Server:あなたが開発する能力提供側。Tools / Resources / Prompts を公開します。
- Tools:AI が呼び出せる関数(検索、計算、DB 照会、ファイル書き込み)。
- Resources:AI が読み取れるリソース(ファイル、URL、設定ストリーム)。URI でアドレス指定します。
- Prompts:事前定義されたプロンプトテンプレート。動的パラメータ注入に対応します。
2.3 通信メカニズム
MCP は JSON-RPC 2.0 を基盤としています。転送方式は二種類あります。
- stdio:ローカル子プロセス。Client が Server を起動し、標準入出力で通信します。遅延は極めて低いです。
- HTTP + SSE / Streamable HTTP:リモートサービス。複数クライアントの同時接続に対応します。
ライフサイクルは 初期化ハンドシェイク → 能力ネゴシエーション(tools/list、resources/list)→ リクエスト/レスポンス(tools/call)→ クローズ です。
2.4 MCP と他ソリューションの比較
| 比較軸 | MCP | OpenAI Function Calling | LangChain Tools |
|---|---|---|---|
| 標準化度 | オープンプロトコル標準 | ベンダー独自 | フレームワーク依存 |
| 転送方式 | stdio / HTTP | HTTP | HTTP |
| クロスモデル対応 | 対応(Claude、GPT、Gemini 等) | 非対応 | 一部対応 |
| Resources / Prompts | ネイティブ対応 | 非対応 | 非対応 |
| エコ規模(2026) | 10,000+ Server、AAIF ガバナンス | 成熟だが閉鎖的 | 成熟だが Python 依存 |
3. 開発環境の準備とプロジェクト構成
3.1 開発言語の選択
- Python(本稿の主言語):公式 SDK
mcp、FastMCPデコレータで簡潔に書けます。 - TypeScript(対照):公式 SDK
@modelcontextprotocol/sdk。Node/フルスタック開発者向きです。
3.2 環境構築手順
# Python 環境
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install mcp httpx pydantic
# TypeScript 環境(対照)
npm init -y
npm install @modelcontextprotocol/sdk
3.3 推奨プロジェクト構成
my-mcp-server/
├── server.py # メインサービスエントリ
├── tools/
│ ├── __init__.py
│ ├── calculator.py
│ └── web_search.py
├── resources/
│ └── file_reader.py
├── prompts/
│ └── templates.py
├── tests/
│ └── test_tools.py
├── pyproject.toml
└── README.md
3.4 デバッグツール
- MCP Inspector:公式デバッグ UI。Tools / Resources / Prompts を可視化してテストできます。
- Claude Desktop:
claude_desktop_config.jsonを編集して連携します。 - Cursor:Settings → MCP、またはプロジェクトの
.cursor/mcp.jsonで設定します。
4. 最初の MCP Server:Hello World
4.1 最小構成の Server コード
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-first-server")
@mcp.tool()
def say_hello(name: str) -> str:
"""指定した相手に挨拶します"""
return f"Hello, {name}! これはあなたの最初の MCP ツールです。"
if __name__ == "__main__":
mcp.run()
4.2 起動と検証手順
python server.py
# MCP Inspector でデバッグする場合
npx @modelcontextprotocol/inspector python server.py
Inspector 起動後、ブラウザで tools/list に say_hello が返ることを確認し、tools/call で {"name": "開発者"} を渡して応答を検証してください。
4.3 Cursor / Claude Desktop への接続
Cursor(.cursor/mcp.json):
{
"mcpServers": {
"my-first-server": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}
Claude Desktop(macOS ~/Library/Application Support/Claude/claude_desktop_config.json):構造は同じです。クライアントを再起動すると、Agent 対話で say_hello ツールがコンテキストに表示されます。
5. Tools:AI が呼び出せるツールの開発
5.1 ツールの基本構造
関数シグネチャがそのままドキュメントになります。パラメータ型、戻り値型、docstring が自動的に JSON Schema に変換され、AI が理解します。命名は snake_case、動詞始まり(search_web、read_file)を推奨します。
5.2 入力パラメータ型(Pydantic)
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="検索キーワード")
max_results: int = Field(default=5, description="最大返却件数")
language: str = Field(default="ja", description="結果の言語")
@mcp.tool()
def web_search(input: SearchInput) -> list[dict]:
"""ネットワーク検索を実行し、関連結果のリストを返します"""
...
5.3 五つの実用ツール実装
- 計算機:
evalの安全サブセットまたはast.literal_evalで数式を処理します。 - ファイル読み書き:ホワイトリストディレクトリに限定し、パストラバーサルを防止します。
- HTTP リクエスト:
httpxで外部 API を呼び出し、JSON またはテキストを返します。 - データベース照会:読み取り専用 SQL + パラメータ化クエリ。DDL は禁止します。
- 時刻ツール:
datetime.now(timezone.utc)とタイムゾーン変換を提供します。
5.4 非同期ツール
import httpx
@mcp.tool()
async def fetch_url(url: str) -> str:
"""指定 URL のコンテンツを取得します"""
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url)
response.raise_for_status()
return response.text
5.5 エラー処理のベストプラクティス
- ビジネスエラーは構造化 JSON(
{"error": "...", "code": 404})で返し、裸の例外を投げないようにします。 - すべての外部呼び出しにタイムアウトを設定します(30 秒以内を推奨します)。
- ファイル/DB 操作は権限チェックを行い、最小権限の原則を守ります。
6. Resources:動的コンテンツの読み取り
6.1 Resource と Tool の違い
Resource はデータ提供者、Tool はアクション実行者です。 AI は URI を通じて Resource の内容を読み取りますが、副作用は発生しません。
6.2 静的リソースと動的リソース
import json
@mcp.resource("config://app-settings")
def get_app_settings() -> str:
"""アプリケーション設定を返します"""
return json.dumps({"version": "1.0", "env": "production"})
@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
"""ユーザー ID に基づきプロファイルを返します"""
user = db.query_user(user_id)
return json.dumps(user)
URI スキームは file://、http://、custom:// などカスタムプレフィックスに対応します。
6.3 リソースタイプ
- テキスト:
text/plain、application/json - バイナリ:画像、PDF(Base64 または Blob URI)
- ストリーミング:リアルタイムデータ配信(SSE サブスクリプション)
6.4 ファイルシステムリソースサーバー
実践パターン:ディレクトリ一覧 → ファイル内容読み取り → オプションでファイル変更監視(watchfiles)によるリソース更新通知。アクセス許可ルートディレクトリのホワイトリストを必ず設定し、AI が機密パスを読み取らないようにします。
7. Prompts:再利用可能なプロンプトテンプレート
7.1 MCP Prompt とは
事前定義されたプロンプト断片であり、AI クライアントが直接再利用できます。動的パラメータ注入に対応し、チームの一貫性と保守性を高めます。
7.2 プロンプトテンプレートの作成
from mcp.types import PromptMessage, TextContent
@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[PromptMessage]:
"""コードレビュー用プロンプトテンプレート"""
return [
PromptMessage(
role="user",
content=TextContent(
type="text",
text=f"""以下の {language} コードをレビューしてください。重点項目:
1. コード品質と可読性
2. 潜在的なバグとセキュリティリスク
3. パフォーマンス最適化の提案
コード:
```{language}
{code}
```"""
)
)
]
7.3 マルチターン会話プロンプト
user と assistant を含むマルチターンテンプレートを定義できます。面接シミュレーション、コードデバッグアシスタントなどのシーンに適しています。各 PromptMessage に role と content を指定し、Client が順序どおりに対話コンテキストへ注入します。
8. HTTP 転送モード:リモート MCP Server
8.1 stdio と HTTP + SSE の比較
| 特性 | stdio | HTTP + SSE |
|---|---|---|
| デプロイ方式 | ローカル子プロセス | リモートサーバー |
| 遅延 | 極低(<1ms) | ネットワーク依存(10–200ms) |
| 複数クライアント | 非対応 | 対応 |
| 適用シーン | ローカル開発、個人ツール | SaaS、チーム共有、7×24 サービス |
8.2 HTTP 転送の実装
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("remote-server", transport="streamable-http")
if __name__ == "__main__":
mcp.run(host="0.0.0.0", port=8000)
8.3 認証とセキュリティ
- Bearer Token:Client のリクエストヘッダに
Authorization: Bearer <token>を付与します。 - API Key ミドルウェア:キー検証 + IP ホワイトリストを組み合わせます。
- CORS:信頼できる Origin のみ許可します。
- レート制限:ツール乱用を防止します(例:毎秒 10 回の tools/call)。
9. デバッグ、テスト、よくあるエラー
9.1 MCP Inspector デバッグフロー
- 起動:
npx @modelcontextprotocol/inspector python server.py - UI で Tools / Resources / Prompts 一覧を確認します。
- 手動で
tools/callをトリガーし、リクエスト/レスポンス JSON を確認します。 - エラーシナリオ(タイムアウト、不正パラメータ)をシミュレートし、エラー処理を検証します。
9.2 ユニットテスト例
import pytest
from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client
@pytest.mark.asyncio
async def test_calculator_tool():
server_params = StdioServerParameters(
command="python",
args=["server.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("calculate", {"expression": "2 + 2"})
assert result.content[0].text == "4"
9.3 よくあるエラーと対処法
| エラー現象 | よくある原因 | 解決策 |
|---|---|---|
| ツールが AI に表示されない | 設定パス誤り、Client 未再起動 | config.json の絶対パスを確認し、Cursor/Claude を再起動します |
| JSON シリアライズ失敗 | 非対応の戻り値型(datetime オブジェクト等) | 文字列または dict に変換します |
| タイムアウト切断 | ツール実行が Client デフォルトタイムアウトを超過 | async + timeout 設定、または長タスクの分割を行います |
| 権限拒否 | ファイルパスがホワイトリスト外 | アクセス許可ディレクトリのルートパスを設定します |
10. 本番デプロイ:Docker、クラウド、監視
10.1 Docker コンテナ化
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]
10.2 クラウドサービス選定(2026 年参考)
- Railway / Render:ワンクリックデプロイ。個人プロジェクト向き(月額約 $5–20)。
- AWS Lambda / Google Cloud Run:サーバーレス。呼び出し課金です。
- 自前 VPS / リモート Mac:Nginx リバースプロキシ + launchd デーモン。Apple エコシステムや長期 7×24 Agent ツールチェーンに適しています。
10.3 監視と可観測性
- 構造化ログ:各 tools/call でツール名、所要時間、ステータスコードを記録します。
- Prometheus メトリクス:呼び出し回数、P99 遅延、エラー率を追跡します。
- Sentry:未捕捉例外のアラートを設定します。
- ヘルスチェック:
GET /healthが 200 + プロトコルバージョンを返すことを確認します。
10.4 バージョン管理と互換性
初期化ハンドシェイク時に MCP プロトコルバージョンを宣言します。ツールのアップグレードは後方互換戦略を採用し——必須フィールドを削除せず、オプションパラメータを追加します。重大な変更時は v1/v2 Server を並行稼働させ、Client が能力ネゴシエーションで選択します。
11. 実践プロジェクト:個人ナレッジベース MCP Server
11.1 プロジェクト要件
- AI がローカルの Markdown ノートを検索できるようにします。
- セマンティック検索(ベクトル検索、純粋なキーワード検索ではない)に対応します。
- ノートの作成と更新をサポートします。
11.2 技術選定
- ベクトルデータベース:ChromaDB または Qdrant(ローカル組み込み、運用コストゼロ)。
- 埋め込みモデル:
text-embedding-3-small(OpenAI)またはローカルnomic-embed-text。 - ファイル監視:
watchfilesでインデックスを自動再構築します。
11.3 コアツール設計
- index_notes:ノートディレクトリをスキャンし、チャンク分割して埋め込み、ベクトル DB に書き込みます。
- search_notes:セマンティック検索で Top-K 断片 + ソースファイルパスを返します。
- write_note:Markdown ファイルを作成または追記します(ホワイトリストディレクトリ内)。
- notes://{path} Resource:指定ノートの全文を直接読み取ります。
11.4 効果デモ
Cursor で「先週 MCP について記録したノートは何ですか?」と質問すると、AI が search_notes ツールを呼び出し、関連断片とソースファイルを返します。全ノートを Context Window に詰め込むより 90% 以上の Token を節約でき、リアルタイム更新にも対応します。
12. MCP エコシステムと今後の展望
12.1 おすすめ MCP Server
- mcp-server-filesystem:ファイルシステムの読み書きとディレクトリ一覧。
- mcp-server-github:GitHub リポジトリ操作、Issue、PR。
- mcp-server-brave-search:ネットワーク検索。
- mcp-server-postgres:PostgreSQL 読み取り専用照会。
- mcp-server-slack:Slack メッセージの送受信。
公式ドキュメント:modelcontextprotocol.io。Python SDK:github.com/modelcontextprotocol/python-sdk。TypeScript SDK:github.com/modelcontextprotocol/typescript-sdk。
12.2 2026 年エコシステムのトレンド
- 主要 AI クライアント(Cursor、Claude Desktop、VS Code Copilot、Gemini CLI)が MCP をネイティブサポートしています。
- MCP Marketplace と AAIF ガバナンスが Server 品質認証を推進しています。
- エンタープライズセキュリティ標準:OAuth 2.1、細粒度 Tool 権限、監査ログ。
12.3 次の学習ステップ
- MCP プロトコル仕様全文を深く学びます。
- 最初の公開 MCP Server を開発し GitHub に公開します。
- MCP + Agent の組み合わせを探索します(《Cursor Agent Skill》と OpenClaw MCP 連携を参照)。
- オープンソースエコシステムに Tools または Resources 実装を貢献します。
13. まとめ:ローカル実験から 7×24 本番ノードへの判断
本稿では MCP Server 開発の完全なチェーンをカバーしました:プロトコル原理 → 環境構築 → Hello World → Tools / Resources / Prompts → HTTP リモート転送 → Inspector デバッグ → Docker デプロイ → 個人ナレッジベース実践。MCP は AI ツール化の標準プロトコルであり、2026 年の AI エンジニアにとって必須スキルの一つです。
ただし、ローカル stdio モードには明確な限界があります。ノート PC の蓋を閉じると接続が切れ、ベクトル DB と埋め込みモデルがローカルメモリを占有し、複数 Server の同時稼働で CPU が競合します。個人ナレッジベース MCP、HTTP リモート Server、ChromaDB + 埋め込み API を必要とする長時間セッションは、常時オンラインの Apple Silicon ノード上で動かす方が安定します——統合メモリアーキテクチャはベクトル検索に有利で、macOS は launchd デーモンと Cursor/Claude 同型ツールチェーンをネイティブサポートします。
SFTPMAC リモート Mac レンタルは MCP Server と AI Agent ワークフロー向けの 7×24 Apple Silicon 環境を提供します。低遅延 HTTP+SSE コールバック、ネイティブ Python/Node ランタイム、SFTP/rsync によるノートディレクトリと設定の同期が可能です。「自宅 PC を MCP ホスト兼用」より、個人ナレッジベースやチームツール層を本番入口として運用するのに適しています。MCP でどんなツールを開発しますか?Hello World から始めれば、今日から動かせます。