Claude Codeの仕組み講座(講師のためのエンジニア水準)

区分5 自分で作る(エンジニア水準)★★

No.17 MCPサーバーを作る

自分でMCPサーバーを1つ作って、Claude Code につなぎます。コードを書くのはAIに任せてよく、あなたの役は「何を道具にするか」「どう確かめるか」を判断することです。作ってみると、No.11 で学んだ約束事の中身が実物として見えます。
目次
  1. 第0章 前提知識
  2. 第1章 最小のサーバーを作る
  3. 第2章 Claude Code につないで確かめる
  4. 第3章 うまく動かない時の見方
  5. 確認問題

第0章 前提知識

① MCPサーバー :AIに「道具」を貸し出す、小さなプログラム

MCP(Model Context Protocol)は、AIアプリと外の道具をつなぐための約束事です。登場人物は No.11 と同じ3者です。ホストは Claude Code 本体、クライアントはホストの中にある接続用の部品、サーバーは道具を出す側のプログラムです。この単元で作るのは、サーバーです。

たとえるなら、サーバーは取引先の専用窓口です。窓口は「見積もりを出して」「在庫を調べて」のような決まった依頼だけを受け付け、AIは窓口の依頼票の書き方を見て、必要な時に依頼を出します。

サーバーが出せるものは、公式の説明で3種類あります。

この単元で作るのは、いちばん使う道具1つだけです。

② つなぎ方は2通り

サーバーとホストのやり取りには、大きく2つの方法があります。

方法 どう動くか 向いている物
stdio(標準入出力) Claude Code が、自分のMac上でサーバーのプログラムを子プロセス(別のプログラムから起動された小さなプログラム)として起動し、文字のやり取りで会話する 自分のMac上だけで使う小さな道具
HTTP ネット上のURLにあるサーバーに接続する 離れた場所に置いて、複数人で使う物

この単元では、いちばん手軽な stdio で作ります。stdio では、Claude Code がサーバーを起動し、プログラムの出入り口(標準入力と標準出力)で文字をやり取りします。この性質が、第1章の大事な注意につながります。

第1章 最小のサーバーを作る

① 作る流れ 必ず覚える

作るのは「2つの整数を足す道具」です。道具としては地味ですが、サーバーの作りは本物と同じです。流れは6つです。

  1. 何を道具にするかを決める(ここだけがあなたの判断)
  2. 作業用のフォルダを作り、公式の部品(SDK。開発用の部品セット)を入れる
  3. 道具を1つ書く(AIに書かせる)
  4. 単体で動かして、中身を確かめる(第2章)
  5. Claude Code につなぐ(第2章)
  6. AIに実際に呼ばせて、結果が返ることを確かめる(第2章)

準備は、公式のチュートリアルにならって、ターミナル(命令を文字で打つ画面)で次のように行います。

uv init hello
cd hello
uv add "mcp[cli]"

uv は Python の部品とその置き場(仮想環境)をまとめて管理する道具で、入っていない時はAIに頼めば用意してくれます。uv init hello は hello フォルダを作り、見本の main.py を置きます。uv add は、そのフォルダの中に .venv(このフォルダ専用の Python と部品の置き場)を作って、mcp を入れます。つまり hello/.venv/bin/python は、mcp が入った専用の Python です。

サーバーのコードは、同じ hello フォルダの中に server.py という名前で新しく作ります。main.py は使いません(消してもそのままでも構いません)。

② 道具1つのコード 必ず覚える

公式チュートリアルの形に沿った、最小のサーバーです。mcp 2.3.0・Python 3.11 の手元の Mac で動かして確かめました。

from mcp.server import MCPServer

mcp = MCPServer("hello")

@mcp.tool()
def add(a: int, b: int) -> int:
    """2つの整数を足して返す。"""
    return a + b

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

読み方は3か所です。

説明文は、AIが「この道具をいつ使うか」を判断する主な手がかりになります。道具の名前や引数の形と並んで、AIが読む材料です。人間向けのコメントではなく、AI向けの仕様書として書きます。

コードを書くのはAIに任せてよい。頼み方の例:「MCPサーバーを Python で作って。公式チュートリアルの形で、道具は『2つの整数を足す add』1つだけ。stdio で動かす。入れた mcp のバージョンの公式の書き方に合わせて、1行ずつ何をしているか説明して」

○ 深追いしない 公式チュートリアルは、Python のSDKが 2.0.0 以上であることを前提に書かれています。クラス名や書き方は版で変わるので、古い解説記事のコードがそのまま動かないことがあります。AIには「入れた版の公式の例に合わせて」と頼みます
○ TypeScript で作る場合の公式の部品は @modelcontextprotocol/server です(公式チュートリアルに別の手順があります)

③ 必ず守る約束:標準出力に文字を出さない 必ず覚える

stdio では、標準出力(プログラムが文字を出す出口)が、JSON-RPC というメッセージ形式のやり取りの通り道になっています。JSON は、機械が読み書きしやすい決まった書式の文字列です。通り道に関係ない文字が混ざると、受け取る側が読めなくなって壊れうる、というのが公式の根拠です。

窓口の電話線に、関係ない独り言を流してはいけない、という約束です。

○ 手元の確認:わざと print() を入れたサーバーを、最新のSDK(mcp 2.3.0)で動かしたところ、Claude Code にも Inspector にもつながり、道具の呼び出しも成功しました。壊れなかったのはこの版の作りによるもので、公式が禁止している書き方であることは変わりません。他の版や言語、つなぎ方では壊れる可能性があるので、動いたからと破っていい約束ではありません
○ 画面に出したい確認は、標準エラーに出す。AIに作らせる時に「ログは標準エラーへ」と頼む

第2章 Claude Code につないで確かめる

① 単体で動かして確かめる(Inspector) 必ず覚える

Claude Code につなぐ前に、サーバーだけを単体で確かめます。MCP Inspector は、MCPの公式の確認用道具で、npx(Node.js の部品を、入れずに1回だけ動かす命令)で起動できます。次の命令は、hello フォルダの中で打ちます。

npx @modelcontextprotocol/inspector --cli ./.venv/bin/python server.py --method tools/list

./.venv/bin/python は、第1章で uv add が作った専用の Python です。./ は「今いるフォルダの中」の意味です。これで add という道具と、その引数(a と b、どちらも整数)の書式が返りました。「AIから見えているサーバーの中身」です。

道具を実際に呼ぶ確認も、同じ道具でできます。

npx @modelcontextprotocol/inspector --cli ./.venv/bin/python server.py \
  --method tools/call --tool-name add --tool-arg a=2 --tool-arg b=3

結果の中に "text": "5" が返れば、道具は正しく動いています。--cli を付けずに起動すると、ブラウザで操作できる画面版になります。ここで動かなければ、Claude Code につないでも動きません。単体で確かめておくと、サーバーの故障か、AIとの連携の故障かを分けられます。

② Claude Code につなぐ 必ず覚える

つなぐ命令は、公式で次の形です。

claude mcp add --transport stdio hello -- /絶対パス/.venv/bin/python /絶対パス/server.py

どこに設定を残すかを、範囲(有効にする範囲。公式の呼び名は「スコープ」)で選べます。

範囲 効く範囲 保存先
local(標準) 今の作業場だけ。自分だけ ~/.claude.json
project 今の作業場。チームで共有 作業場の .mcp.json
user 自分の全部の作業場 ~/.claude.json

まず local で試して、動いたら必要に応じて広げるのが安全です。つないだ後の確認は、命令かアプリ内の画面で行います。

claude mcp list          # 全部のサーバーとつながり具合
claude mcp get hello     # 1つのサーバーの詳細
claude mcp remove hello  # 外す

アプリ内では /mcp で、サーバーごとの接続状態と道具の数が見えます(公式)。

手元では、本物の設定を触らないよう、環境変数(命令に渡す設定値)の CLAUDE_CONFIG_DIR に一時フォルダを指定して試しました。設定の保存先がその一時フォルダに変わるので、試し終わったらフォルダごと消せます。claude mcp add のあと claude mcp list で ✔ Connected(つながった)と出て、claude mcp get でスコープ・種類・起動命令が表示されました。

③ AIに実際に呼ばせる 必ず覚える

AIから見ると、サーバーの道具は mcp__サーバー名__道具名 という名前になります。今回なら mcp__hello__add です。

claude -p "helloサーバーのadd道具で 2 と 3 を足して、答えだけ言って" \
  --mcp-config m.json --strict-mcp-config \
  --allowedTools "mcp__hello__add" --output-format json

結果の result が 5 で返りました。AIがサーバーに依頼票を出し、答えが戻り、AIがそれを使って返事をした。この一連の流れが実物で確かめられたことになります。

m.json の中身は、公式の .mcp.json と同じ形です。

{
  "mcpServers": {
    "hello": {
      "command": "/絶対パス/.venv/bin/python",
      "args": ["/絶対パス/server.py"]
    }
  }
}

第3章 うまく動かない時の見方

① 切り分けの順番 必ず覚える

どこが悪いかを、外側から順に切ります。

順番 見る物 分かること
1 claude mcp list / claude mcp get 名前 つながっているか。つながらない時は、get に原因の行(HTTPの番号やエラー)が出る(公式)
2 /mcp(アプリ内) 接続状態・道具の数・認証が必要かどうか
3 Inspector(単体で動かす) サーバーそのものが正しく道具を返せるか
4 claude --debug-file ログの場所 Claude Code 側の詳しいログ(公式のオプション)

1と2で問題がなければ、サーバーはつながっています。道具が呼ばれない時は、道具の説明文が、AIにとって「いつ使うか」の手がかりになっているかを疑います。

② 起動が間に合わない・結果が大きすぎる さらっと

公式の環境変数で、次のような上限が決まっています。数字は2026年10月時点の公式です。

環境変数 何のための上限か
MCP_TIMEOUT サーバーの起動を待つ時間(ミリ秒)。例:MCP_TIMEOUT=10000 claude
MCP_TOOL_TIMEOUT 道具1回の実行にかけられる時間
MAX_MCP_OUTPUT_TOKENS 道具の結果の最大の大きさ(標準は25,000トークン。トークンはAIが文章を数える単位)

結果が大きすぎる道具は、AIの作業机(コンテキスト)を圧迫します(No.05)。道具が返す結果は、必要な部分に絞って返すのが、サーバーを作る側の腕の見せどころです。

③ 講師として判断する所 必ず覚える

コードはAIが書きます。あなたが判断するのは、次の4つです。

道具の許可・サーバーの設定・説明文が効く強さの順番は、機能ごとに違います。機能ごとの比較は No.15 にあります。

○ 受講生によく聞かれる質問 1:「MCPサーバーを作るのに、プログラミングは必須ですか?」
答え方:書くのはAIに任せられます。ただし「何を道具にするか」「説明文」「許可」は人が決める所です。公式の最小の例は、型と説明文付きの関数1つなので、読める量です
○ 受講生によく聞かれる質問 2:「stdio と HTTP、どちらで作るべき?」
答え方:自分のMac上で、自分だけが使う物は stdio が手軽です。離れた場所に置いて複数人で使うなら HTTP です(第0章②)
○ 受講生によく聞かれる質問 3:「作ったのに、AIが道具を使ってくれません」
答え方:まず claude mcp list でつながりを見て、次に Inspector でサーバーが道具を返しているか確かめます。両方問題なければ、説明文が手がかりとして足りているかを見直します
○ 関係する単元:No.11 MCP/No.13 許可/No.15 設定の強さ/No.16 -p と SDK

MCPサーバー = 道具を貸し出す窓口。型付きの関数1つで作れる。stdio では標準出力に関係ない文字を書かない。単体(Inspector)で確かめてから、claude mcp add でつなぎ、mcp__名前__道具名 で呼ばせる。

確認問題

問1 自作のMCPサーバー(stdio)を作りました。ログを見たくて、サーバーのコードに print() で状況を書き足そうとしています。本文の約束から、どう扱うのが正しい?

問2 claude mcp add でつないだのに、AIが道具を使いません。最初にやる順番として合うのは?

問3 hello という名前のサーバーに、add という道具があります。AIから見える道具の名前は?

問4 道具の説明文("""..."""の部分)は、何のために書く?

出典:Claude Code 公式ドキュメント「Connect Claude Code to tools via MCP」(https://code.claude.com/docs/en/mcp)「CLI reference」(https://code.claude.com/docs/en/cli-reference)、Model Context Protocol 公式「Build an MCP server」(https://modelcontextprotocol.io/docs/develop/build-server)「stdio」(https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio)「MCP Inspector」(https://modelcontextprotocol.io/docs/tools/inspector)/手元のMacで、Python の最小サーバーを作り、Inspector(tools/list・tools/call)、claude mcp add / list / get / remove、claude -p --mcp-config での呼び出しを実際に動かして確認(2026-10-13)