MCPサーバーの作り方を徹底解説|Python・TypeScriptの実装例と公式SDKの使い方

AI

※

※本記事にはアフィリエイトリンク(PR・広告)が含まれる場合があります。

 

Model Context Protocol(MCP)のアーキテクチャ概要図——ホスト・クライアント・MCPサーバーの関係
出典:dida Blog「A practical introduction to the Model-Context-Protocol (MCP)」

この記事の要点(30秒でわかるまとめ)

MCPサーバーとは「AIホスト(Claude Desktop・Cursorなど)が呼び出せるツール・リソース・プロンプトを公開するプログラム」のこと。実装は公式SDK(Python / TypeScript)を使うのが標準で、Pythonなら型ヒントとdocstringからスキーマが自動生成されるため、最小構成なら10行程度で動作します。

  • MCPの3プリミティブ=Tools(実行)・Resources(参照)・Prompts(定型指示)
  • 通信方式はローカルなら stdio、リモートなら Streamable HTTP が推奨
  • まず公式リファレンスサーバー(Everything / Fetch / Filesystem など)で動作を体感するのが近道

MCPサーバーとは?仕組みと役割をわかりやすく解説

MCP(Model Context Protocol)は、Anthropicが提唱した「AIモデルと外部データ・ツールを標準的に接続するためのオープンプロトコル」です。USB-Cがあらゆる機器を1つの規格で接続するように、MCPはAIアプリケーションと外部システムの接続を1つの規格に統一します。

その中でMCPサーバーが担うのは、AIホスト(Claude Desktop、Cursor、各種AIエージェント)に対して次の3つの機能(プリミティブ)を提供することです。

プリミティブ 役割 具体例
Tools(ツール) AIが「実行」できる関数。副作用を伴う操作も可能 天気取得、ファイル作成、API呼び出し
Resources(リソース) AIが「参照」できる読み取りデータ ドキュメント、DBレコード、設定ファイル
Prompts(プロンプト) 再利用可能な定型指示テンプレート 「要約して」「レビューして」等の定型文
MCPサーバーとAIホスト間の通信フロー——Tools・Resources・Promptsの3プリミティブ
出典:Humanloop「Model Context Protocol (MCP) Explained」

「MCPサーバー とは」「MCP 仕組み わかりやすく」で検索する方が最初に押さえるべきなのは、MCPサーバー自体はAIを含まないという点です。あくまで「AIから呼び出される側の部品」であり、判断するのはホスト側のLLMです。この分担を理解すると、設計がぐっとシンプルになります。

参考:通信方式の違いはこちら | 公式仕様:modelcontextprotocol.io/specification

【Python】MCPサーバーの最小構成の作り方

「MCPサーバー Python 作り方」「MCPサーバー 構築 初心者」で調べている方に最初におすすめしたいのが、Python SDK v2 による最小構成です。型ヒントとdocstringからスキーマが自動生成されるため、JSONスキーマを手書きする必要がありません。

from mcp.server import MCPServer

mcp = MCPServer("Demo")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

@mcp.prompt()
def summarize(text: str) -> str:
    """Summarize a piece of text in one sentence."""
    return f"Summarize the following text in one sentence:\n\n{text}"

インストールと動作確認は次の2コマンドだけです。

uv add "mcp[cli]"          # または pip install "mcp[cli]"
uv run mcp dev server.py   # MCP Inspector で試す
💡 ポイント:mcp dev で起動する MCP Inspector は、ブラウザ上で tools/list → tools/call を対話的に試せる公式デバッグツールです。サーバー開発ではまず Inspector で動作確認するのが定石です。

これだけで Tools / Resources / Prompts の3プリミティブが一通り公開されます。docstring("""Add two numbers.""" の部分)はAIがツールの用途を判断する材料になるため、何をする関数かを具体的に書くことが品質を左右します。

関連:実際の外部APIを叩く実装例(天気サーバー) | Python SDK 公式リポジトリ:github.com/modelcontextprotocol/python-sdk

【実践】天気APIを叩くMCPサーバー(公式チュートリアル)

公式チュートリアル「Build an MCP server」では、米国気象局(NWS)APIを呼び出す get_alerts / get_forecast ツールを実装します。「MCPサーバー API連携 方法」の具体例として最も引用される定番のサンプルです。

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP  # または MCPServer

mcp = FastMCP("weather")

NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"

async def make_nws_request(url: str) -> dict[str, Any] | None:
    headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
    async with httpx.AsyncClient() as client:
        r = await client.get(url, headers=headers, timeout=30.0)
        r.raise_for_status()
        return r.json()

@mcp.tool()
async def get_alerts(state: str) -> str:
    """Get weather alerts for a US state.

    Args:
        state: Two-letter US state code (e.g. CA, NY)
    """
    url = f"{NWS_API_BASE}/alerts/active/area/{state}"
    data = await make_nws_request(url)
    # ... 整形して返す

ここでの実装ポイントは3つあります。

  1. HTTP通信はツール関数の外側に切り出す(make_nws_request)——テストと再利用が容易になります。
  2. docstring の Args: セクションがAIへの引数説明になる——「Two-letter US state code」のように形式まで明記するのがコツです。
  3. タイムアウト(30秒)を必ず設定——外部APIの応答遅延でAIホスト全体が待たされるのを防ぎます。

同じ内容の実装が TypeScript / Go / Rust / Ruby でも公式の quickstart-resources リポジトリに用意されています。

【TypeScript】Zodでスキーマを定義する実装例

「MCPサーバー TypeScript 実装」の場合、Pythonと異なりZodで入力スキーマを明示的に定義するのが標準スタイルです。以下は通貨換算ツールの例です。

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "mcp-server",
  version: "1.0.0",
});

server.tool(
  "currency-converter",
  "Convert currency between EUR and USD",
  {
    amount: z.number(),
    from: z.enum(["EUR", "USD"]),
    to: z.enum(["EUR", "USD"]),
  },
  async ({ amount, from, to }) => {
    const rate =
      from === "EUR" && to === "USD" ? 1.1 :
      from === "USD" && to === "EUR" ? 0.91 : 1;
    const converted = amount * rate;
    return {
      content: [
        {
          type: "text",
          text: `${amount} ${from} is ${converted.toFixed(2)} ${to}`,
        },
      ],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

戻り値は { content: [{ type: "text", text: ... }] } というMCPのコンテント形式で返す点がPythonとの大きな違いです。なお、新しいSDKでは registerTool 形式も使われています。詳細は TypeScript SDK 公式リポジトリ を参照してください。

公式リファレンスサーバー一覧と試し方

いきなり自前で書く前に、公式の modelcontextprotocol/servers リポジトリにあるリファレンス実装を動かしてみるのが「MCPサーバー 使い方 入門」の最短ルートです。

サーバー 役割
Everything Tools / Resources / Prompts を一通り持つテスト用
Fetch Web取得・LLM向け変換
Filesystem 許可パス配下の安全なファイル操作
Git リポジトリの status / diff / log など
Memory 知識グラフ型の永続メモリ
Sequential Thinking 段階的な思考用ツール
Time 時刻・タイムゾーン変換

すぐ試すコマンド例:

# Memory
npx -y @modelcontextprotocol/server-memory

# Filesystem(許可するディレクトリを指定)
npx -y @modelcontextprotocol/server-filesystem /path/to/allowed

# Git(Python)
uvx mcp-server-git --repository /path/to/repo

Claude Desktop への登録は設定ファイル(claude_desktop_config.json)に次のように記述します。

{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"]
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed"]
    }
  }
}
MCPサーバーをClaude DesktopなどのAIホストに接続する構成イメージ
出典:Descope「What Is the Model Context Protocol (MCP) and How It Works」

通信方式(Transport)の選び方:stdio vs Streamable HTTP

「MCP stdio HTTP 違い」は開発者が必ず直面する論点です。MCPの通信方式(Transport)は用途に応じて次のように選びます。

方式 用途
stdio ローカル。ホストが子プロセスとして起動(Claude Desktop / Cursor など)
Streamable HTTP リモート向けの推奨。セッション・通知に対応
SSE(旧) 互換用。新規は Streamable HTTP が推奨

PythonでHTTP起動する例:

uv run mcp run server.py --transport streamable-http
⚠️ 注意:リモート公開する場合は、認証(OAuth / Bearerトークン)と権限設計を必ず別途実装してください。MCPサーバーはAIに任意の操作を委譲する性質上、無認証の公開は重大なセキュリティリスクになります。

実務でMCPサーバーを開発する5つのステップ

社内APIのラップや業務ツール連携など、実務でMCPサーバーを作る際の推奨手順は次の通りです。

  1. 最小ツール1つから始める——上記の add や時刻を返す get_time のような単純な関数で通信用配線を確認します。
  2. MCP Inspector で tools/list → tools/call を確認——スキーマが意図通り生成されているか、戻り値の形式は正しいかを対話的に検証します。
  3. Resources と Prompts を必要に応じて追加——読み取り専用データはResources、定型指示はPromptsに分離すると設計が整理されます。
  4. 既存REST APIをラップするならOpenAPIの操作を1つずつtoolにする——1ツール1操作の原則を守ると、AIがツールを選択しやすくなります。
  5. リモート公開時は認証・権限を別途設計——OAuth / Bearer 認証と、ツールごとの実行権限を必ず実装します。

関連:最小構成のコードに戻る | 公開時のTransport選定

よくある質問(FAQ)

Q. MCPサーバーの開発に必要なものは?

A. 公式SDK(Python または TypeScript)とランタイム(uv / Node.js)だけで始められます。Pythonなら uv add "mcp[cli]" で環境構築が完了し、MCP Inspector でブラウザ上の動作確認まで行えます。

Q. MCPサーバーは無料で作れる?

A. はい。MCPの仕様とSDKはすべてオープンソースで無料です。ローカル(stdio)で動かす分には追加費用もかかりません。リモート公開する場合のみ、サーバー費用と認証基盤のコストが発生します。

Q. PythonとTypeScript、どちらで作るべき?

A. 連携したいシステムの言語に合わせるのが基本です。データ処理や機械学習系のAPIならPython、WebサービスやNode.js資産があるならTypeScriptが適しています。学習目的なら、スキーマ自動生成で記述量が少ないPythonが手軽です。

Q. 公開されているMCPサーバーはどこで探せる?

A. 公式レジストリ registry.modelcontextprotocol.io で公開サーバーを検索できます。自作前に類似サーバーがないか確認すると開発工数を削減できます。

Q. MCPサーバーと通常のREST APIの違いは?

A. REST APIが「人間の開発者向け」なのに対し、MCPサーバーは「AI(LLM)が自律的に発見・選択・呼び出す」ことを前提に設計されています。ツール名・説明文・引数スキーマがAI向けのメタデータとして機能する点が最大の違いです。

まとめ:まず最小構成を動かし、Inspectorで確認しよう

MCPサーバーは「AIホストが呼べるツール・リソース・プロンプトを出すプログラム」であり、公式SDKを使えばPythonなら10行程度で動作します。本記事の手順を振り返ると——

  • Python SDK v2 では型ヒントとdocstringからスキーマが自動生成される
  • 公式チュートリアルの天気サーバーがAPI連携の最良の教科書
  • TypeScriptではZodで入力スキーマを明示する
  • 通信はローカル=stdio、リモート=Streamable HTTP
  • 公開前に公式レジストリとリファレンスサーバーを確認する

特定の言語(Go / Rust / Rubyなど)や、「ファイル操作だけに絞りたい」「社内APIをラップしたい」といった用途が決まっている場合は、公式クイックスタートの該当テンプレートから始めるのが効率的です。

コメント

タイトルとURLをコピーしました