開発者がゼロから MCP Server を構築し AI クライアントと外部ツールを接続するアーキテクチャ図

ゼロから MCP Server を開発する:AI ツール呼び出し完全ガイド

大規模言語モデルはどれほど高性能でも、社内データベースの照会、内部 API の呼び出し、ローカルファイルの読み取りを直接行うことはできません。これはモデルの能力不足ではなく、標準化されたツール呼び出しチャネルが欠けているためです。Model Context Protocol(MCP) は Anthropic がオープンソース化した解決策であり、Claude、Cursor、GPT が統一プロトコルで外部能力にアクセスできるようにします。本稿を読み終えると、Tools、Resources、Prompts の三大コア能力と HTTP リモート転送を含む、本番利用可能な MCP Server を独立して開発・デバッグ・デプロイできるようになります。

1. 三大課題:AI に MCP Server が必要な理由

最初の一行を書く前に、解決すべき実際の問題を整理しましょう。

  1. ツールの孤立:Function Calling、Plugins、LangChain Tools はそれぞれ異なるフォーマットで書かれており、モデルプロバイダーを変えるたびに統合層を書き直す必要があります——典型的な N×M 問題です。
  2. データへのアクセス不可:モデルの学習データにはカットオフ日があり、リアルタイムの設定、社内ドキュメント、データベースの状態を読み取れません。
  3. アクションの実行不可:純粋な対話型 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 mcpFastMCP デコレータで簡潔に書けます。
  • 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 Desktopclaude_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/listsay_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_webread_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 五つの実用ツール実装

  1. 計算機eval の安全サブセットまたは ast.literal_eval で数式を処理します。
  2. ファイル読み書き:ホワイトリストディレクトリに限定し、パストラバーサルを防止します。
  3. HTTP リクエストhttpx で外部 API を呼び出し、JSON またはテキストを返します。
  4. データベース照会:読み取り専用 SQL + パラメータ化クエリ。DDL は禁止します。
  5. 時刻ツール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/plainapplication/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 マルチターン会話プロンプト

userassistant を含むマルチターンテンプレートを定義できます。面接シミュレーション、コードデバッグアシスタントなどのシーンに適しています。各 PromptMessagerolecontent を指定し、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 デバッグフロー

  1. 起動:npx @modelcontextprotocol/inspector python server.py
  2. UI で Tools / Resources / Prompts 一覧を確認します。
  3. 手動で tools/call をトリガーし、リクエスト/レスポンス JSON を確認します。
  4. エラーシナリオ(タイムアウト、不正パラメータ)をシミュレートし、エラー処理を検証します。

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 コアツール設計

  1. index_notes:ノートディレクトリをスキャンし、チャンク分割して埋め込み、ベクトル DB に書き込みます。
  2. search_notes:セマンティック検索で Top-K 断片 + ソースファイルパスを返します。
  3. write_note:Markdown ファイルを作成または追記します(ホワイトリストディレクトリ内)。
  4. 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 から始めれば、今日から動かせます。