ゼロから MCP Server を開発する: AI ツール呼び出し完全ガイド
大規模言語モデルがどれほど賢くても、データベースの照会、API 呼び出し、ファイルの読み書きは直接できません——AI ツール呼び出し能力が、Agent が現実世界に触れられるかどうかを決めます。MCP(Model Context Protocol) は Anthropic がオープンソース化した標準プロトコルで、Claude や Cursor などのクライアントが、あなたが書いた Server を統一的な方法で発見・呼び出せます。本文は Python または TypeScript の基礎を持つバックエンド / AI 開発者向けに、プロトコル原理、環境構築、Tools / Resources / Prompts 三大機能、リモート HTTP デプロイ、デバッグ・テストから本番稼働までの全工程をゼロから解説します。
読み終えると、次の三つに答えられるようになります:① MCP と Function Calling、LangChain Tools の本質的な違い;② 公式 SDK でツール、リソース、プロンプトテンプレートを登録する方法;③ 個人ナレッジベースを本番利用可能な MCP Server としてカプセル化し、Cursor で「先週 MCP について書いたメモは何?」と直接質問する方法。
01 MCP とは?プロトコル原理、通信メカニズムと方式比較
ツール呼び出し能力は三代の進化を経てきました:Function Calling(ベンダー私有フォーマット)→ Plugins(プラットフォーム依存)→ MCP(オープンプロトコル標準)。Anthropic が MCP を設計した核心動機は、JSON-RPC 仕様で「AI クライアントが外部能力をどう発見・記述・呼び出すか」を統一し、N モデル × M ツールのカスタム統合地獄を終わらせることです。
- 痛点の切り口:モデルは外部ツールとリアルタイムデータへのアクセス能力を欠き、DB 照会、API 呼び出し、ファイル操作ができません。
- シナリオ:Claude / GPT にデータベース照会、REST API 呼び出し、ローカル Markdown の読み書きをさせたい——これこそ MCP Server が公開すべき能力です。
- 価値の約束:本文を読めば、本番利用可能な MCP Server を独立して開発・デプロイできます。
アーキテクチャ上、MCP Client(Claude Desktop、Cursor など)と MCP Server(あなたが開発する部分)が JSON-RPC で双方向通信し、Server が外部システムと接続します:
- Tools:AI が呼び出せる関数(検索、計算、DB クエリ)
- Resources:AI が読み取れるリソース(ファイル、URL、データストリーム)
- Prompts:パラメータ注入をサポートする事前定義プロンプトテンプレート
通信は JSON-RPC 2.0 ベースで、転送方式は二種類です:stdio(ローカル子プロセス、超低レイテンシ)と HTTP + SSE / Streamable HTTP(リモートサービス、マルチクライアント対応)。ライフサイクルは:初期化ハンドシェイク → 能力ネゴシエーション → リクエスト/レスポンス → クローズ。
| 比較軸 | MCP | OpenAI Function Calling | LangChain Tools |
|---|---|---|---|
| 標準化度 | オープンプロトコル標準 | ベンダー私有 | フレームワーク依存 |
| 転送方式 | stdio / HTTP | HTTP | HTTP |
| クロスモデル対応 | はい | いいえ | 一部 |
| リソース / プロンプト | ネイティブサポート | 非対応 | 非対応 |
| エコシステム | 急成長(10,000+ Server) | 成熟 | 成熟 |
関連記事:MCP が AI 時代の HTTP プロトコルとなる理由;公式仕様は modelcontextprotocol.io をご覧ください。
02 開発環境の準備:言語選定、依存関係インストールとプロジェクト構成
Python(初心者向け):公式 SDK mcp、FastMCP デコレータで簡潔に始められます。TypeScript(フロントエンド / フルスタック向け):公式 SDK @modelcontextprotocol/sdk。本文は Python を主軸に、TypeScript は対照として説明します。
# Python 環境
python -m venv .venv
source .venv/bin/activate
pip install mcp
# TypeScript 環境(対照)
npm init -y
npm install @modelcontextprotocol/sdk
推奨プロジェクト構成:
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
デバッグツール三種:
- MCP Inspector:公式デバッグ UI、Tools / Resources / Prompts を可視化テスト
- Claude Desktop:
claude_desktop_config.jsonを編集してローカル連携 - Cursor MCP 設定:Settings → MCP → stdio コマンドライン起動項目を追加
03 Hello World:最もシンプルな MCP Server と Cursor 接続
FastMCP なら 10 行のコードで最初の 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()
実行と検証:
python server.py
# または MCP Inspector でデバッグ
npx @modelcontextprotocol/inspector python server.py
Cursor 接続六段階:
- Python パスの確認:仮想環境で
which pythonを実行し、絶対パスをメモします。 - Cursor MCP 設定を開く:Settings → Features → MCP Servers。
- stdio Server を追加:command に Python パス、args に
server.pyの絶対パス。 - Cursor を再起動:MCP 設定を反映させます。
- ツール一覧を確認:Agent モードで
say_helloが表示されるか確認します。 - 呼び出しをトリガー:会話で AI に「say_hello で JEXCLOUD に挨拶して」と依頼し、正しい応答を確認します。
Claude Desktop も同様です:~/Library/Application Support/Claude/claude_desktop_config.json を編集し、mcpServers ノードに同名設定を登録します。
04 Tools 開発:パラメータ型、五大実践ツールと非同期モード
ツールの基本契約:関数シグネチャがそのままドキュメント——パラメータ型、戻り値型、docstring が MCP により JSON Schema に変換され、AI が理解します。命名は snake_case、エラーは裸の例外より構造化情報を優先して返します。
複雑なパラメータは 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]:
"""ウェブ検索を実行し、関連結果リストを返す"""
...
五大実用ツールを練習リストとしておすすめします:
- 計算機:数式を安全に評価(
ast.literal_evalでインジェクション防止) - ファイル読み書き:ホワイトリストディレクトリ内の read / write に限定
- HTTP リクエスト:GET / POST をラップ、タイムアウトとリトライを統一
- データベースクエリ:読み取り専用 SQL + パラメータ化でインジェクション防止
- 時刻ツール:現在時刻、タイムゾーン変換、ISO 8601 フォーマット
IO 集約型ツールは非同期で:
import httpx
@mcp.tool()
async def fetch_url(url: str) -> str:
"""指定 URL のコンテンツを取得する"""
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=30.0)
return response.text
エラー処理のベストプラクティス:タイムアウト設定、権限チェック(パスホワイトリスト / API Key)、{"error": "...", "code": "..."} 構造体を返して AI の自己修正を助けます。
05 Resources:URI アドレッシング、静的・動的リソース、ファイルシステム実践
Resource と Tool の違い:Resource はデータ提供者(読み取り専用)、Tool はアクション実行者(書き込み可、副作用あり)。アドレッシングは URI スキーム:file://、http://、custom://。
# 静的リソース
@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:
user = db.query_user(user_id)
return json.dumps(user)
リソースタイプのカバー範囲:
- テキスト:
text/plain、application/json - バイナリ:画像、PDF(Base64 または blob URI)
- ストリーミング:リアルタイムログ、相場配信(リソース購読)
ファイルシステムリソースサーバーの実践:ディレクトリ一覧 → パスでファイル読み取り → オプションで watchfiles による変更監視とリソース更新通知のプッシュ。
06 Prompts:再利用可能なプロンプトテンプレートと多ターン会話シナリオ
MCP Prompt は事前定義されたプロンプト断片で、AI クライアントが直接再利用でき、動的パラメータ注入をサポートし、チームのプロンプト一貫性と保守性を高めます。
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} コードをレビューしてください..."
)
)
]
多ターン会話テンプレートは user と assistant ロールを混在できます。典型シナリオ:面接シミュレーション(まず assistant が質問、次に user が回答)、コードデバッグアシスタント(assistant がトラブルシュート手順を誘導)。
07 HTTP 転送モード:リモート MCP Server とセキュリティ強化
| 特性 | stdio | HTTP + SSE |
|---|---|---|
| デプロイ方式 | ローカルプロセス | リモートサーバー |
| レイテンシ | 極低 | ネットワーク依存 |
| マルチクライアント | 非対応 | 対応 |
| 適用シナリオ | ローカルツール | SaaS / チーム共有 |
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)
本番環境では以下を重ねます:Bearer Token 認証、API Key ミドルウェア、CORS ホワイトリスト、リクエストレート制限(slowapi など)。リモート Server はチーム共有の DB クエリ、内部 API ゲートウェイなどに適しています。
08 デバッグとテスト:MCP Inspector、ユニットテストとよくあるエラー
MCP Inspector ワークフロー:Inspector 起動 → stdio コマンド接続 → UI で tools/call をテスト → JSON-RPC リクエスト/レスポンスログ確認 → タイムアウトと権限拒否シナリオをシミュレート。
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"
| エラー | 原因 | 解決策 |
|---|---|---|
| ツールが AI に表示されない | 設定パス誤り | config.json の command / args 絶対パスを確認 |
| JSON シリアライズ失敗 | 戻り値型が非対応 | 文字列または dict に変換 |
| タイムアウト切断 | ツール実行が遅い | 非同期化 + タイムアウト制御 |
| 権限拒否 | ファイルパス制限 | アクセス許可ディレクトリのホワイトリストを設定 |
09 本番デプロイ:Docker、クラウドサービスと可観測性
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]
デプロイ選定:
- Railway / Render:ワンクリックデプロイ、個人プロジェクト向け
- AWS Lambda / Google Cloud Run:Serverless、呼び出し課金
- 自前 VPS:Nginx リバースプロキシ + TLS、Bearer Token と併用
可観測性三種:構造化リクエストログ、Prometheus ツール呼び出しメトリクス、Sentry エラーアラート;/health ヘルスチェックを公開。バージョン管理では MCP プロトコルバージョンを宣言し、ツールアップグレードは後方互換を維持、能力ネゴシエーションでクライアントクラッシュを回避します。
- MCP Python SDK:github.com/modelcontextprotocol/python-sdk
- MCP TypeScript SDK:github.com/modelcontextprotocol/typescript-sdk
- MCP Inspector:github.com/modelcontextprotocol/inspector
10 実践プロジェクト:個人ナレッジベース MCP Server の構築
要件:AI がローカル Markdown メモの検索、セマンティック検索、メモの作成・更新をできるようにする。
技術選定:
- ベクトル DB:ChromaDB または Qdrant(ローカル軽量)
- 埋め込みモデル:
text-embedding-3-small(OpenAI)またはローカルnomic-embed-text - ファイル監視:
watchfilesでインデックスを増分再構築
コアモジュール:
index_notesツール:メモディレクトリをスキャン、チャンク分割してベクトル DB に書き込みsemantic_searchツール:query → top-k 関連断片write_noteツール:Markdown ファイルの作成 / 追記notes://{path}リソース:URI で単一メモ全文を読み取り
デモ効果:Cursor で「先週 MCP について何を記録した?」と質問 → AI が semantic_search を呼び出し → 関連断片を返して総合回答。これがプライベートナレッジを Agent ワークフローに接続する最短経路です。
11 MCP エコシステム展望、学習パスと本番ホスト選定
おすすめコミュニティ Server:
mcp-server-filesystem:ファイルシステム操作mcp-server-github:GitHub リポジトリ操作mcp-server-brave-search:ウェブ検索mcp-server-postgres:データベースクエリmcp-server-slack:Slack メッセージ
2026 エコシステムトレンド:Cursor、Claude Desktop、VS Code、OpenAI、Google Gemini がすでに MCP をネイティブまたは計画でサポート;MCP Marketplace が Server 配布を加速;エンタープライズセキュリティ標準(OAuth 2.1、監査ログ)がロードマップに。
次の学習パス:MCP プロトコル仕様を精読 → 最初の公開 Server をリリース → MCP + Agent オーケストレーションを探索 → オープンソースエコシステムへ PR 貢献。
- プロトコルバージョン:2024-11-05 初版、2025 年から Streamable HTTP が純 SSE に代わりリモート転送の推奨方式に
- エコシステム規模:2026 年時点でコミュニティ MCP Server は 10,000 を超える
- SDK 保守:Anthropic オープンソース + Linux Foundation AAIF ガバナンス、Python / TypeScript 公式 SDK 週次更新
MCP は AI ツール化の標準プロトコル——Server 開発をマスターすれば、任意の LLM にあなたのビジネスシステムを呼び出させる能力を手に入れます。MCP で何をカプセル化する予定ですか?コメント欄でシナリオをぜひ共有してください。
本番級 MCP Server の隠れたコストはホスト安定性にあります:ノート PC を閉じると STDIO 子プロセスが即死、家庭用回線の揺らぎで HTTP 長時間接続が切断、共有 VPS には macOS サンドボックスと TCC 権限がありません。7×24 でナレッジベースインデックス、リモート HTTP MCP、Cursor Agent 連携 CI が必要なら、JEXCLOUD マルチリージョン ベアメタル Mac が専有 Apple Silicon、固定グローバル IP、120 秒デプロイ、月単位の弾性レンタルを提供——「ローカルで凌ぐ + 頻繁リトライ」より本番 Agent ワークフローに適しています。ノードと価格は JEXCLOUD 料金ページ、デプロイの質問は ヘルプセンターをご覧ください。