MCP Server 学習資料 計画

Claude Code・Codex・Antigravity CLI 向けの MCP Server を、いちから作れるようになるための資料をどう組み立てるか

📅 作成: 2026-09-07 / 更新: 2026-09-07

目次

  1. この資料で何を作るか
  2. 前提の実測と仕様の現状
  3. 参考資料から引き継ぐ方針
  4. 資料の構成案
  5. 決めたこと
  6. 作業の進め方

この資料で何を作るか

目的

MCP(Model Context Protocol)Server を いちから自分で書けるようになるための学習資料を作る。読んで終わりではなく、手元で動く MCP Server を持ち帰り、Claude Code・Codex・Antigravity CLI から実際に呼び出せる状態にする。

対象読者

項目内容
MCP の知識まったく無いことを前提にする。「MCP という言葉は聞いたことがある」程度から始める
JavaScript文法は十分に知っている。asyncawait・モジュール・クラスの説明は不要
AI コーディング CLIClaude Code・Codex を「とりあえず使える」水準。設定ファイルの場所や MCP の登録方法は知らない前提
サーバー開発HTTP・プロセス・標準入出力の概念は分かるが、JSON-RPC は知らないかもしれない前提

ゴール

想定時間

120 分。読み物として通読するのではなく、手を動かしながら進む前提で時間を配分する。配分案は第 4 章に置く。

当初は 90 分・本編 8 章で見積もっていたが、Tasks 拡張(論点 6-B)と stdio ブリッジ(論点 7-B)まで扱うと決めたため、本編 11 章・120 分に改めた。章を 2 部に割らず、通しの 1 本として構成する。

この資料が扱わないもの:MCP Client(ホスト側)の実装、LLM そのものの仕組み、TypeScript の型システム(別資料に譲る)。

前提の実測と仕様の現状

実行環境(2026-09-07 時点の実測値)

対象バージョン確認方法
Node.jsv26.8.1node --version
npm11.19.0npm --version
@modelcontextprotocol/sdk1.30.0npm view @modelcontextprotocol/sdk version
MCP 仕様(最新)2026-07-28仕様サイトの最新リビジョン
MCP 仕様(資料の基準2025-11-25Claude Code が実際に喋る版。次節で実測した
Claude Code2.1.263claude --version
Codex0.153.4codex --version
Antigravity1.107.0antigravity --version

ステップ 0 の実測結果(資料の前提が決まった)

3 つの CLI に接続させて、届いた initialize を記録した。最新の 2026-07-28 を喋る CLI は無かった。

ホスト名乗った能力tasks
Claude Code 2.1.2632025-11-25rootselicitation非対応
Codex 0.153.42025-06-18elicitation(form ・ url)未確認
Antigravity 1.107.0未確認

この結果を受けて、資料は 2025-11-25 を基準にした(論点 2 の A)。2025-11-25 は 2026-07-28 とは作りが違い、接続ごとの状態を持ち、サーバーからクライアントへリクエストを送れる(sampling・roots・elicitation)。タスクもコア仕様に入っている。以下に残した 2026-07-28 の記述は将来の変更点として読むこと。

Tasks は Claude Code では使われなかった。サーバー側で capabilities.tasks を名乗り、ツールに taskSupport: 'optional' を付けても、task を付けずに普通に呼んでくる。仕様どおりの動きであり、09 章にはこの実測をそのまま書いた。

仕様 2026-07-28 で押さえるべき点(将来の変更)

標準トランスポートは 2 つ

トランスポート内容位置づけ
stdioクライアントが起動した子プロセスの標準入出力に、改行区切りの JSON-RPC を流す標準
Streamable HTTP1 つのエンドポイントへの HTTP POST。応答は JSON か、そのリクエスト専用の SSE ストリーム標準
HTTP+SSE(旧)旧リビジョンの方式。後方互換として扱われ、標準の一覧からは外れている互換のみ
カスタムTCP・Unix ドメインソケット・名前付きパイプなど。stdio と同じ改行区切りのフレーミングを再利用することが推奨任意
ホスト(AI CLI) Claude Code / Codex / Antigravity MCP クライアント A サーバー 1 本につき 1 つ MCP クライアント B サーバー 1 本につき 1 つ stdio 子プロセスの標準入出力・改行区切り JSON-RPC Streamable HTTP 単一エンドポイントへの POST・応答は JSON か SSE MCP サーバー(子プロセス) ホストごとに 1 本ずつ起動される MCP サーバー(常駐) 複数のホストから 1 本を共有できる サーバーが提供するもの: Tools(実行する関数) / Resources(読ませるデータ) / Prompts(定型の指示)
ホスト・クライアント・サーバーの関係。プロセスを共有できるかどうかはトランスポートの選択で決まる。

サーバーからクライアントへ「リクエスト」は送れない

2026-07-28 では、運べるメッセージの向きが次の 4 つに限定されている。

向きリクエスト通知レスポンス
クライアント → サーバー不可
サーバー → クライアント不可

「push 通知を送りたい」はここに直撃する。旧リビジョンではサーバーがクライアントへリクエストを投げられたが、現行仕様では Servers MUST NOT initiate JSON-RPC requests と明記され、通知とレスポンスだけになった。何をどこまで実現できるかは第 5 章の論点 6 に表でまとめている。

通知はクライアントが張ったストリームに流れる

サーバーが勝手に送りつけるのではなく、通知には必ず流し込む先が要る。先は 2 通りある。

流し先作られ方送れる通知
処理中のリクエストクライアントのリクエストを処理している間だけ開いているnotifications/progressnotifications/message
購読ストリームクライアントが subscriptions/listen を送ると、その応答が長寿命の通知ストリームになる一覧の変化・資源の更新・notifications/tasks など

どちらも起点はクライアントである。接続が無い相手へサーバーから届ける経路は無い。

問いかけは「入力が要る」という結果で表す

サーバーが利用者に尋ねたいとき(確認・選択・sampling)は、リクエストを送るのではなく InputRequiredResult結果として返す。クライアントは答えを inputResponses に添えて同じリクエストを送り直す。これを Multi Round-Trip Requests(MRTR)と呼ぶ。Tasks 拡張では、これがタスクの input_required 状態と tasks/update に対応する。

ステートレスになった

旧リビジョンは initialize ハンドシェイクで接続ごとのセッションを張っていたが、現行仕様ではリクエスト 1 本が自己完結し、プロトコルバージョンとクライアント能力は毎回 _meta.io.modelcontextprotocol/* に載る。これはプロセス共有と相性がよい(論点 7 で扱う)。

各 CLI が実際に喋るリビジョンは未確認。Claude Code・Codex・Antigravity CLI が 2026-07-28 に追随しているとは限らない。これは資料の内容を左右するため、執筆前に実測する(第 6 章 ステップ 0)。

参考資料から引き継ぐ方針

既存の TypeScript 学習資料PowerShell 学習資料 と同じ作りにする。読み手が同じシリーズとして読めることを優先する。

踏襲する形

項目内容
ファイル構成docs/ に本編 01-〜.html、付録 A1-〜.html、構成案 ZZ-構成.html。root に README.html
番号体系「資料番号.章番号」(資料 03 の章は 03.103.2…)
ナビゲーション本文先頭とフッターの両方に 前へ・次へ・目次 のバッジ。付録は目次のみ
資料ごとに通し色相(280°→0°)。章見出しは資料内で虹色
公開GitHub Pages(public)。index.html から README.html へリダイレクト
MarkdownHTML を正とし、html2md で生成。SVG は images/ へ切り出す

執筆原則(この資料向けに読み替えたもの)

TypeScript 資料は「同じ処理の JavaScript を並べる」「理由を先に説明する」「短い実行例で終わる」を原則にしていた。MCP は言語ではなくプロトコルなので、次のように置き換える。

  1. 生の JSON-RPC を先に見せ、SDK は後から出す。SDK から入ると「何が起きているか分からないまま動く」状態になり、詰まったときに調べられない
  2. 理由を先に説明する。「なぜ stdout にログを書いてはいけないのか」を、規約ではなく壊れ方で示す
  3. 各節は動かして終わる。節の終わりに必ず実行結果を貼る。出力は実測を貼り、書き起こさない
  4. ホストごとの差はバッジで示す。Claude CodeCodexAntigravity の 3 つで登録方法が違うため、設定ファイルの話は必ずバッジを添える
  5. エラーメッセージは実際に出るものを載せる。英語なら英語のまま載せ、訳を添える

資料の構成案

本編 11 章+付録 3 本(TypeScript 版の A4 は本編を書き終えてから)。120 分で本編を通せる分量にする。ハンズオンを 2 つに割り、前半で作ったサーバーを後半で育てる形にする。

本編

番号タイトル扱う内容目安
01背景MCP が無かった頃は何をしていたか。なぜ規約が要ったか。ホスト・クライアント・サーバーの関係。LSP との類似8 分
02最小のサーバーJSON-RPC を手で書いて標準入出力に流す。SDK を使わず、初期化とツール 1 個の応答だけを返す。ここで中身を見せておく15 分
03SDK で書き直す02 と同じものを @modelcontextprotocol/sdk で書く。何が省けたかを対比する10 分
04ホストに登録するClaude Code・Codex・Antigravity CLI それぞれの登録方法。設定ファイルの場所と書式。動かないときの切り分け12 分
05Tools・Resources・Prompts3 種類の提供物の違いと使い分け。入力スキーマの書き方。エラーの返し方13 分
06ハンズオン① メモサーバーお題 A。メモを検索・追記するサーバーを 01〜05 の内容で作りきる。以降の章はこれを育てる12 分
07Streamable HTTP06 のサーバーを HTTP に載せ替える。stdio との違い、いつどちらを選ぶか12 分
08通知で結果を伝える進捗通知とログ通知。subscriptions/listen の仕組み。サーバー起点でできること・できないことの線。OS のトースト通知という枠外の手10 分
09Tasks 拡張長い処理を投げて後から結果を取る。tasks/get によるポーリングと notifications/tasks による push。拡張の合意が要ること10 分
10プロセス共有同一 PC で 1 本のサーバーを共有する 3 方式の比較。localhost HTTP と stdio ブリッジを実装する8 分
11ハンズオン② ビルド実行サーバーお題 B。開発コマンドを実行し、終わったら知らせ、複数のホストで共有する。07〜10 の総仕上げ10 分

付録

番号タイトル扱う内容
A1逆引き「〜したい」から引く。ツールを増やす/ログを見る/登録を消す/バージョンを確かめる
A2詰まったとき症状から原因へ。サーバーが起動しない・ツールが見えない・応答が返らない・stdout 汚染
A3C# で書くcsc.exe で単一 exe にする構成。Node.js を入れられない相手へ配るときの選択肢
A4TypeScript で書く本編のサーバーを TypeScript に置き換える。本編を書き終えた後に着手する(論点 1 の C)

02 章を SDK より先に置くのがこの構成の肝。SDK から入ると server.tool(...) を書けば動いてしまい、登録が効かないときに「どこまで届いているか」を確かめる手段が無くなる。手で JSON-RPC を 1 往復させておくと、以降すべての章で切り分けができる。

決めたこと

資料を書き始める前に決めた項目。採った案を見出しのバッジで示し、案とその理由は残す。後から「なぜこうしたか」を辿れるようにするため。

決定の一覧

論点採用内容
1. 実装言語A + C本編は JavaScript(ESM・.mjs)。TypeScript 版は本編を書き終えてから付録 A4 として足す
2. 仕様リビジョンA3 つの CLI が実際に喋るリビジョンに合わせる。各章を書きながら CLI で検証する
3. C#A付録 A3 に 1 本。本編は Node.js のみ
4. ハンズオンA + B2 題とも扱う。06 章でメモサーバー(A)、11 章でビルド実行サーバー(B)
5. 実測範囲AClaude Code で全章を実測。Codex・Antigravity は登録方法と疎通のみ
6. push 通知A + Bできること・できないことを示し、進捗通知と OS トースト通知を実装(08 章)。Tasks 拡張も実装まで踏み込む(09 章)
7. プロセス共有A + B3 方式を図で比較し、localhost HTTP と stdio ブリッジの両方を実装(10 章)
8. リポジトリA20260907-ai-mcp-servers-learn・public・Pages は develop/
9. サンプル置き場Adocs/samples/
構成B本編 11 章・120 分。2 部に割らず通しの 1 本にする

6 と 7 で B を足したことで、当初の 90 分・8 章には収まらなくなった。Tasks 拡張と stdio ブリッジがそれぞれ 1 章分の分量になるため、本編を 11 章・120 分に改めている。

1. 実装言語 A + C

AJavaScript(ESM・.mjsで本編を書き、TypeScript 版は付録にしない
ビルド手順が 1 つも要らず、90 分でハンズオンまで届く。TypeScript の型は別資料に譲れる。読者の JS 知識は十分にある
BTypeScriptで本編を書く
SDK の型定義がそのまま効き、ツールの入力スキーマを型から起こせる。ただし tsconfig と実行方法の説明で 10 分以上取られる
C本編は JavaScript、付録に TypeScript 版を置く
両方に届くが、付録 1 本分の執筆と保守が増える

2. 対象とする仕様リビジョン A

A3 つの CLI が実際に喋るリビジョンに合わせる(ステップ 0 で実測して決める)
読者が手元で動かせることを最優先する。動かない資料は価値が無い
B2026-07-28(最新)に合わせ、旧リビジョンとの差分を付録に置く
仕様として正しいが、CLI 側が追随していない場合ハンズオンが動かない

3. C#(csc.exe)の扱い A

A付録 A3 に 1 本置く。本編は Node.js のみ
90 分の本編に入れると 2 言語分の説明で膨らむ。配布形態の選択肢として付録が適所
B扱わない
最も軽いが、「Node.js を入れられない環境へ配る」という実務の要求に答えられない
C本編に対比として入れる
stdio の本質が言語に依らないことを示せるが、90 分には収まらない

4. ハンズオンのお題 A + B

Aプロジェクト内のメモを検索・追記するサーバー(Tools 2 個+Resources 1 個)
外部サービスに依存せず、Tools と Resources の違いを 1 つの題材で見せられる。ネットワークが無くても動く
Bローカルの開発コマンドを実行するサーバー(ビルド・テストの起動)
実務に直結するが、コマンド実行は権限と安全性の話が必要になり脱線する
C公開 API を叩くサーバー(天気・為替など)
分かりやすいが、API キーやネットワークの有無で勉強会が止まる

5. 動作確認をどこまで実測するか A

AClaude Code で全章を実測し、Codex・Antigravity は登録方法と疎通のみ実測
確認の手間と資料の信頼性が釣り合う。差が出るのは主に登録方法なので、そこを押さえれば足りる
B3 つとも全章で実測
最も確実だが、章ごとに 3 回確認することになり作業量が 3 倍近くなる
CClaude Code のみ実測し、他は仕様の記述に留める
最も軽いが、「3 つの CLI 向け」という目的から外れる

6. push 通知で何を実現するか A + B

実現したいことは「処理が終わった結果を伝える」と決まった。現行仕様ではサーバーからリクエストを送れないため(第 2 章参照)、目的の側から手段を並べ直す。

やりたいこと現行仕様での実現手段可否
進捗を伝えたいnotifications/progress を送る。そのリクエストを処理している間だけ
ログを出したいnotifications/message を送る。同じく処理中だけ
一覧や資源の変化を伝えたいクライアントが subscriptions/listen で張ったストリームへ通知を流す
処理の途中で利用者に尋ねたいInputRequiredResult を返し、クライアントが答えを添えて再送する(MRTR)
長い処理を投げて後で結果を取りたいTasks 拡張。tasks/get でポーリングする拡張
長い処理の完了を push したいTasks 拡張 + subscriptions/listennotifications/tasks を受ける拡張
人に確実に気づかせたいサーバープロセスが OS のトースト通知・音・メールを直接出す。MCP の枠外
何も呼ばれていないのに会話へ割り込みたい—。通知が届いてもホストが会話に出すかは実装次第で、仕様は保証しない不可
A「できること・できないこと」を 07 章で示すに留め、実装は進捗通知の 1 例だけ
未経験者向けの 90 分にはこれが上限。不可の線を知ることが最も価値がある
BTasks 拡張まで踏み込む
「長い処理を投げて後で取る」に答えられるが、CLI 側の対応状況に左右され、未経験者には重い
C07 章から外し、付録に回す
本編が軽くなるが、検討中の主題が資料に載らない

08 章と 09 章に分けて扱う。08 章で表の前半(進捗通知・subscriptions/listen・OS トースト)と「できないことの線」を示し、09 章で Tasks 拡張を実装する。subscriptions/listen はコア仕様のパターンで、クライアントのリクエストへの応答が長寿命の通知ストリームになるのが要点。これが MCP における push の実体になる。

Tasks への対応状況は実測が要る。公式のクライアント対応表には Tasks の列がまだ無く(MCP Apps・OAuth 系のみ)、Claude Code も表に載っていない。09 章の実装が 3 つの CLI で動くかはステップ 0 で確かめる。動かない場合も、動かないことを実測として書く

7. プロセス共有をどう扱うか A + B

stdio はホストが子プロセスを起動するため、ホストの数だけサーバーが立つ。同一 PC で 1 本を共有したい場合の構成。

方式内容難所
localhost の HTTP常駐サーバーを 1 本立て、各ホストは Streamable HTTP で繋ぐ常駐の起動・終了と、待ち受けポートの扱い
stdio ブリッジ各ホストには軽い stdio のプロセスを起こさせ、それが常駐本体へ中継するブリッジ自身の実装。ただしホスト側の設定は stdio のまま済む
名前付きパイプstdio と同じフレーミングをパイプで運ぶ(仕様が推奨する再利用の形)Windows 固有。SDK の既製品が無い
A07 章で 3 方式を図で比較し、実装は localhost HTTP のみ
06 章の Streamable HTTP がそのまま使えるため、新しい説明がほとんど要らない
Bstdio ブリッジまで実装する
ホスト側の設定を変えずに共有できる実用的な形だが、章 1 本分の分量になる
C付録に回す
本編が 90 分に収まりやすくなるが、検討中の主題が本編から外れる

8. リポジトリと公開 A

Aリポジトリ名はフォルダ名と同じ 20260907-ai-mcp-servers-learn、public、GitHub Pages を develop ブランチの / で公開
既存の学習資料と同じ形。lightspeedc.com/20260907-ai-mcp-servers-learn/ に並ぶ
BMCP と分かる名前に変える(20260907-mcp-server-learn 等)
検索で見つけやすいが、既にフォルダを作った後なので付け替えが要る

9. サンプルコードの置き場 A

Adocs/samples/ に置く(資料と同じ側)
共通ルールどおり。読者が資料からの相対パスで辿れる
Broot の samples/ に置く
実行はしやすいが、資料と離れる

作業の進め方

手順

ステップ内容成果物
03 つの CLI の実測 。結果は第 2 章に記載。資料の基準は 2025-11-25 に決まった第 2 章
1構成案を読者向けに書くdocs/ZZ-構成.html
2サンプルコードを先に書いて動かす。資料の本文は動いたものから起こすdocs/samples/
3本編 11 章を書くdocs/01-〜11-
4付録 3 本を書くdocs/A1-〜A3-
5README とナビゲーションを整えるREADME.html
6コントラスト比の実測、Markdown 生成と検査検査結果
7GitHub リポジトリ作成・push・Pages 公開公開 URL
8TypeScript 版の付録を足す(論点 1 の C)。公開の後でよいdocs/A4-

この計画で守ること