3行でいうと

  • サーバーが出せるのは3種類。ツール(モデルが呼ぶ)、リソース(アプリが読む)、プロンプト(利用者が選ぶ)です。
  • 通信はstdio(手元のプロセス)かStreamable HTTP(遠くのサーバー)。認証の仕様はHTTP向けで、stdioでは環境から資格情報を取ります。
  • 公式文書の最新版は2026-07-28版で、接続の手順が前の版から変わっています。古い解説の流用に注意です。

この記事は、実際に使って確かめた記録ではありません。この記事は公式の文書や論文を読んでまとめたものです。

先に結論

前提:用語を先にそろえる

作る前に決める:3つの出し物

公式の「Understanding MCP servers」は、サーバーの機能を3つに分け、「誰が動かすか」を明記しています。

種類 中身 誰が動かすか 例(公式文書より)
ツール モデルが呼べる関数。DBへの書き込みや外部API、ファイル変更もできる モデル 航空券を探す、メッセージを送る
リソース 読み取り専用の情報源。ファイルの中身、DBのスキーマなど。URIで指す アプリ 文書の取得、予定の読み取り
プロンプト あらかじめ作った指示の型。引数を取れる 利用者 休暇を計画する、会議を要約する

要は、副作用のある操作はツール、読ませたい資料はリソース、「いつもの頼み方」はプロンプトに置く、という分け方です。リソースは固定のURIのほかに、weather://forecast/{city}/{date}のようなURIテンプレートで、条件を差し込める形でも出せます。

ツールの定義は、名前、説明、入力のJSON Schema(引数の形を決める書式)が基本です。仕様は、ツール名を1〜128文字、使える文字を英数字と_、-、.に絞るよう(SHOULD)勧めています。

作る:公式の手引きの流れ

公式の「Build an MCP server」は、天気を返すサーバーを例に、get_alertsとget_forecastの2つのツールを作る内容です。公式SDKは、TypeScript、Python、C#、Go、Rust、Ruby(以上Tier 1)、Java(Tier 2)、Swift、PHP、Kotlin(Tier 3)が並んでいます。Tierは機能の充実度と保守の約束による区分で、公式のSDKページがそう説明しています。

Pythonの手引きでは、Python 3.10以上と、Python MCP SDKの2.0.0以上が条件です。インストールはuv add "mcp[cli]"。TypeScriptの手引きは、Node.js 20以上と@modelcontextprotocol/server、zod(入力の形を検査するライブラリ)を入れます。

Pythonの核は、型ヒントと説明文(docstring)から、ツールの定義が自動で作られる点です。

# 公式文書の例の抜粋です。この記事では、実行していません。
from mcp.server import MCPServer

mcp = MCPServer("weather")

@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)
    """
    ...

if __name__ == "__main__":
    mcp.run(transport="stdio")

つまずきやすい点を、手引きは最初に挙げています。stdioで動かすサーバーは、標準出力(stdout)に何も書いてはいけません。書くとJSON-RPCの通信が壊れる、と書かれています。Pythonのprint()が既定でstdoutに出るので、ログは標準ライブラリのlogging(stderrに出る)を使う、という例が載っています。TypeScriptではconsole.log()ではなくconsole.error()です。HTTPで動かす場合は、標準出力のログは問題ない、とも書かれています。

通信方式:stdioかStreamable HTTPか

仕様は標準の通信方式を2つ定めています。

方式 中身 向く場面(公式文書の説明から)
stdio クライアントが起動した子プロセスと、標準入出力で改行区切りのメッセージをやりとりする 同じ機械の中。ネットワークの負荷がない。通常は1つのクライアントに仕える
Streamable HTTP 1つのHTTPの入口にPOSTで送る。返事は1つのJSON、または、その要求専用のSSE(サーバーから流して送る形式)の流れ 遠隔のサーバー。多数のクライアントに仕える

見立てです。自分の手元だけで使う道具ならstdio、チームや公開で使うならStreamable HTTP、と分けるのが素直だと思います。stdioは認証の面倒がほぼ要らず、HTTPは認証・入口の保護・運用が加わります。

2026-07-28版で変わった点(接続の手順)

最新の公式仕様は「2026-07-28」版です。公式のアーキテクチャ概要と通信方式のページから読み取れる変更点を並べます。

  • 通信はステートレス(状態を持たない)になりました。すべての要求が、プロトコルの版と、クライアントの機能(capabilities)を_meta欄に載せて送ります。前の版にあった初期化の握手(initialize)と、接続ごとのセッションはありません。
  • サーバーはserver/discoverという要求に答える必要があり、版と機能を伝えます。クライアントは任意で事前に呼べます。
  • Streamable HTTPでは、サーバーからの独立した要求や、GETで開く常時の流れ、Mcp-Session-Id、再開用のLast-Event-IDが仕様から外れました。サーバーがクライアントに頼みたいこと(利用者への入力要求など)は、結果の中に「入力が必要」と返し、クライアントが再送する形(Multi Round-Trip Requests)になりました。
  • 変更通知(ツール一覧の更新など)は、クライアントがsubscriptions/listenで開く長い流れの上で、希望した種類だけが届きます。
  • HTTPでは、各POSTにMCP-Protocol-VersionとMcp-Methodのヘッダーが必須になり、本文の値と一致しなければ400とHeaderMismatchで拒否します。
  • サンプリング(サーバーがクライアント側のモデルに文章生成を頼む機能)と、サーバー発のログ送信は、この版で「非推奨」とされました。新しい実装では、サンプリングの代わりにモデル提供元のAPIを直接使うこと、ログはstderrかOpenTelemetryにすることが勧められています。
  • 古い版の相手と話す必要がある場合の互換規則(stdioではserver/discoverを先に試し、失敗したらinitializeへ戻る等)が書かれています。

つまり、2025年までの解説記事にある「初期化してセッションIDを持つ」流れは、最新版では前提になっていません。どの版を実装するのか、先に決めてください。

認証の入口

公式の認可仕様(2026-07-28版)の要点です。

見立てです。ここまでを自前で作るのは重く、既存の認可サーバー(IdP)や、SDKの認可支援を使うのが現実的だと思います。ただし、SDKが認可のどこまでを代行するかは、僕らは各SDKの文書を読んでいないので、確認できていません。

作ったあとに守ること

仕様は、サーバー側に次のことをMUSTと書いています。ツールの入力を検証する、アクセス制御を実装する、ツール呼び出しに速度制限をかける、ツールの出力を無害化する。

HTTPで出す場合の注意も、仕様にあります。

クライアント側の推奨として、機微な操作は利用者に確認を取る、ツールの入力を呼ぶ前に利用者へ見せる、結果をモデルに渡す前に検証する、が書かれています。ツールの注釈(annotations)は、信頼できるサーバーからのものでない限り信頼してはいけない、ともあります。

状態を持たせたいときは、新しい版では、作成用のツールが「ハンドル」(購入かごIDのような識別子)を返し、以後の呼び出しでそれを引数に渡す形が案内されています。ハンドルは名前であって権限ではないので、呼び出しのたびに呼び出し元の権限を確かめる、と書かれています。

よくある失敗・つまずき

見立てです。公式の注意書きから、起きやすいと思う点を挙げます。

気をつけること

出典

更新履歴