本文へ移動
メニュー

学ぶ

コースロードマップお知らせ

スタアカについて

プラン受講者の声法人の方

会員の方

ログインマイページQ&A(質問と回答)ライトプランの解約クレジットカードの変更

サポート

お問い合わせ

レッスン 1 / 7

MCPとは?AIと道具をつなぐ共通の規格

所要時間 30分無料で見られます

学ぶコト

  • MCP が解決する「AIアプリ × 道具」の組み合わせの問題
  • ホスト・クライアント・サーバーと、ツール・リソース・プロンプトの役割
  • stdio と Streamable HTTP の違い
  • MCP と Function Calling の関係

このコースでは、AIに社内のデータや道具を使わせるための共通の規格「MCP(Model Context Protocol)」を学びます。できあがった MCP サーバーをつないで使うところから始めて、Python で自分のサーバーを作り、最後は売上データを集計・分析するサーバーを作って、Claude などのAIアプリから使えるようにします。

最初のレッスンでは、手を動かす前に「MCP とは何で、何がうれしいのか」をおさえます。後半では、MCP のやりとりを Python でまねして、中で何が起きているのかを見てみます。

このページの Python のコードは「▶ 実行」を押すと、ブラウザの中で動かせます。上から順に実行してください。

MCPとは

MCP は、AIアプリ(Claude・ChatGPT・Cursor など)と、外の道具やデータ(ファイル・データベース・社内のシステム・Webのサービスなど)をつなぐための、オープンな共通の規格です。2024年11月に Anthropic が公開し、2025年12月からは Linux Foundation の中の Agentic AI Foundation という中立の団体で育てられています。

公式のサイトでは、MCP を「AIアプリにとっての USB-C のようなもの」とたとえています。USB-C の口があれば、どのメーカーのパソコンにも、どのメーカーの周辺機器をつなげます。同じように、MCP に合わせて作った道具(MCP サーバー)は、MCP に対応したどのAIアプリからも使えます。

2026年10月時点で、Claude(Claude Desktop・Claude Code)・ChatGPT・Cursor・VS Code(GitHub Copilot)・Gemini CLI など、主なAIアプリの多くが MCP に対応しています。

どんな困りごとを解決するのか

「PythonでAIチャットボットを作る」のコースの「関数を呼ばせる(Function Calling)」では、注文を調べる関数をチャットボットに持たせました。関数の説明(ツールの定義)を書き、モデルが頼んできたら関数を動かして結果を返す、という仕組みでした。

この仕組みは、そのチャットボットの中だけで完結しています。同じ「注文を調べる」機能を、社員がふだん使っている Claude や Cursor からも使いたくなったら、どうなるでしょうか。アプリごとに、ツールの定義の書き方も、結果の返し方も違います。アプリの数だけ作り直しになります。

社内で使いたいAIアプリが4つ、つなぎたい道具が5つあるとしましょう。

つなぐ作業の数
アプリごとに道具をつなぐ4 × 5 = 20
MCP でつなぐ4 + 5 = 9(アプリは MCP に対応するだけ、道具は MCP サーバーを1つ作るだけ)

アプリが増えても道具が増えても、足し算で済むようになります。これが MCP のいちばんの価値です。

3つの登場人物:ホスト・クライアント・サーバー

MCP には、3つの役割が出てきます。

役割何をするか例
ホスト人が使うAIアプリ。モデルと会話し、どの MCP サーバーにつなぐかを管理するClaude Desktop、Claude Code、ChatGPT、Cursor、自分で作ったアプリ
クライアントホストの中の部品。MCP サーバー1つにつき1つ作られ、そのサーバーとやりとりする(ホストの中に入っていて、ふだんは見えない)
サーバー道具やデータを MCP の形で差し出すプログラムファイルを読むサーバー、GitHub のサーバー、このコースで作る売上分析のサーバー

サーバーには、自分のパソコンの中で動くローカルのサーバーと、インターネットの向こうで動くリモートのサーバーがあります。ローカルのサーバーは、ホストが自分でプログラムを起動して、その1つのホストだけが使います。リモートのサーバーは、サービスの会社などが動かしていて、たくさんの人のホストからつながります。

社員が Claude Desktop で「先月の売上を地域ごとにまとめて」と頼んだとき、中では次のことが起きています。

  1. Claude Desktop(ホスト)は、起動したときに、設定された MCP サーバーから「使えるツールの一覧」を受け取っておく
  2. ホストは、社員の質問と一緒に、ツールの一覧をモデルに渡す
  3. モデルが「売上分析サーバーの集計のツールを、この引数で呼びたい」と答える
  4. ホストは社員に確かめたうえで、そのサーバーのクライアントを通して、ツールを呼ぶ
  5. サーバーが集計し、結果を返す。ホストは結果をモデルに渡し、モデルが答えの文章を書く

サーバーが出せる3つのもの

MCP サーバーは、次の3種類のものを差し出せます。だれが「使う」と決めるかが違います。

種類中身使うと決めるのは例
ツール(tools)AIに呼ばせる関数モデル売上を集計する、ファイルを読む、チケットを作る
リソース(resources)AIに読ませるデータアプリ・人会社の休日の一覧、データベースの表の形、設定ファイル
プロンプト(prompts)決まった頼み方のひな形人「週報の下書き」「納期の返信メール」のひな形

いちばんよく使うのはツールです。このコースでも、ほとんどの時間をツールに使います。

逆に、サーバーからホストに頼めることもあります。代表的なのが elicitation で、サーバーが「この操作の前に、利用者にこれを聞いてほしい」と頼み、ホストが利用者に入力してもらう仕組みです。

やりとりを Python でまねしてみる

ホストとサーバーのやりとりは、JSON-RPC 2.0 という決まった形の JSON で行います。「この method を、この params で実行して」というリクエストを送ると、同じ id を付けたレスポンスが返ってきます。

本物のサーバーは次のレッスンから使います。ここでは、営業日を数えるツールを1つだけ持つサーバーを、Python の関数でまねしてみます。handle がサーバーで、リクエストの辞書を受け取り、レスポンスの辞書を返します。

import json
from datetime import date, timedelta

# サーバーが持っているツールの説明(名前・何をするか・引数の形)
TOOLS = [
    {
        "name": "count_business_days",
        "description": "start から end までの営業日(土日を除いた日)の数を返す",
        "inputSchema": {
            "type": "object",
            "properties": {
                "start": {"type": "string", "description": "数え始める日(YYYY-MM-DD)"},
                "end": {"type": "string", "description": "数え終わる日(YYYY-MM-DD)"},
            },
            "required": ["start", "end"],
        },
    }
]


def count_business_days(start, end):
    s, e = date.fromisoformat(start), date.fromisoformat(end)
    return sum((s + timedelta(days=i)).weekday() < 5 for i in range((e - s).days + 1))


def handle(request):
    """MCP サーバーのまね。JSON-RPC のリクエスト(辞書)を受け取り、レスポンスを返す"""
    method, params = request["method"], request.get("params", {})
    if method == "tools/list":
        result = {"tools": TOOLS}
    elif method == "tools/call" and params.get("name") == "count_business_days":
        try:
            days = count_business_days(**params["arguments"])
            result = {"content": [{"type": "text", "text": str(days)}], "isError": False}
        except (TypeError, ValueError) as e:
            result = {"content": [{"type": "text", "text": f"引数がおかしいです:{e}"}], "isError": True}
    else:
        return {"jsonrpc": "2.0", "id": request["id"], "error": {"code": -32601, "message": f"{method} は使えません"}}
    return {"jsonrpc": "2.0", "id": request["id"], "result": result}


request = {"jsonrpc": "2.0", "id": 1, "method": "tools/list"}
print(json.dumps(handle(request), ensure_ascii=False, indent=2))

tools/list は「使えるツールの一覧をください」というリクエストです。返ってきた inputSchema は、引数の形を表す JSON Schema で、Function Calling のツールの定義で書いた parameters と同じ書き方です。

次は、ツールを呼ぶ tools/call です。

request = {
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {"name": "count_business_days", "arguments": {"start": "2026-11-02", "end": "2026-11-13"}},
}
print(json.dumps(handle(request), ensure_ascii=False, indent=2))

結果は content の中に、文字("type": "text")として入っています。画像などを返すこともできます。日付を "11月2日" のように渡すと、isError が true の結果が返ります。この「うまくいかなかったことを、エラーで止めずに結果として返す」形は、モデルが引数を直してやり直せるようにするためのもので、レッスン4以降でくわしく扱います。

Function Calling との関係

「MCP があれば Function Calling はいらないの?」と思うかもしれません。実はその逆で、MCP は Function Calling の上に乗っています。モデルが知っているのは、これまでどおりの「関数を呼ぶ」仕組みだけです。MCP のツールを関数の形に直してモデルに渡し、モデルの頼みを tools/call に直してサーバーに届けるのは、ホストの仕事です。

ホストがしていることを、Python でまねしてみましょう。まず、tools/list の結果を、OpenAI の Responses API の関数の定義に直します。

def to_function_tools(tools):
    """tools/list の結果を、Function Calling のツールの定義(Responses API の形)に直す"""
    return [
        {"type": "function", "name": t["name"], "description": t["description"], "parameters": t["inputSchema"]}
        for t in tools
    ]


listed = handle({"jsonrpc": "2.0", "id": 3, "method": "tools/list"})["result"]["tools"]
function_tools = to_function_tools(listed)
print(json.dumps(function_tools, ensure_ascii=False, indent=2))

名前・説明・引数の形をそのまま移しただけです。この定義を tools に入れてモデルを呼ぶと、モデルは必要に応じて「この関数を呼んでほしい」と答えます。その答えを受け取ったあとの流れが、次のコードです。

# モデルから「この関数を呼んでほしい」という頼みが返ってきたとする(本当は API の答えに入っている)
call = {
    "type": "function_call",
    "call_id": "call_abc",
    "name": "count_business_days",
    "arguments": '{"start": "2026-11-02", "end": "2026-11-13"}',
}

# ホストは、頼みを tools/call のリクエストに直してサーバーに送る
response = handle({
    "jsonrpc": "2.0",
    "id": 4,
    "method": "tools/call",
    "params": {"name": call["name"], "arguments": json.loads(call["arguments"])},
})

# サーバーの結果を、モデルに返す形(function_call_output)にする
text = "".join(c["text"] for c in response["result"]["content"] if c["type"] == "text")
{"type": "function_call_output", "call_id": call["call_id"], "output": text}

Function Calling のレッスンでは、ツールの定義も、関数を動かすコードも、チャットボットの中に書きました。MCP では、その2つがサーバーに移り、ホストは「一覧をもらって渡す」「頼みを届けて結果を戻す」だけになります。だから、同じサーバーを、どのホストからでも使えるのです。

このやりとりのループ(モデルが頼む → 動かす → 結果を返す → また考える)は、「AIエージェント入門」の「エージェントのループを自分で書く」で書いたものと同じです。MCP は、エージェントが使う道具を、ほかのアプリと共有できる形にしたもの、と考えると分かりやすいでしょう。

通り道:stdio と Streamable HTTP

ホストとサーバーのあいだで JSON を運ぶ方法(トランスポート)は、2種類あります。

stdioStreamable HTTP
どこで動くか自分のパソコン(ローカル)サーバーのコンピューター(リモート)
つなぎ方ホストがサーバーのプログラムを起動し、標準入力・標準出力で JSON をやりとりするホストが URL(例:https://example.com/mcp)に HTTP で送る
使う人起動したホスト1つだけ多くの人のホスト
ログインなど要らないことが多い。APIキーなどは環境変数で渡すOAuth などでログインすることが多い
向いている場面手元のファイルやツールを使う、自作のサーバーを試す会社やサービスが提供するサーバー、チームで共有するサーバー

このコースで作るサーバーは、まず stdio で動かします。設定が簡単で、外から勝手につながれる心配も少ないからです。チームで共有する方法と、そのときの注意は最後のレッスンで扱います。

ウマたんウマたん

MCP の仕組みは「ホストがツールの一覧をもらって、モデルの頼みを届ける」だけです。この絵が頭に入っていれば、設定でつまずいたときも、どこで止まっているのかを考えやすくなりますよ。

演習:2つのサーバーのツールをまとめる

ホストは、たくさんのサーバーに同時につなぐことがあります。すると、別々のサーバーに同じ名前のツールがあって、ぶつかることがあります。そこでホストは、ツールの名前の前にサーバーの名前を付けて区別します(例えば Claude Code は、MCP のツールを mcp__サーバー名__ツール名 という名前でモデルに見せています)。

予定を管理する calendar のサーバーと、注文を管理する sales のサーバーに、どちらも search というツールがあるとします。次のコードを実行してから、演習に進んでください。

servers = {
    "calendar": [{"name": "search", "description": "予定を探す",
                  "inputSchema": {"type": "object", "properties": {"q": {"type": "string"}}}}],
    "sales": [{"name": "search", "description": "注文を探す",
               "inputSchema": {"type": "object", "properties": {"q": {"type": "string"}}}}],
}
演習サーバーの名前を付けてまとめる

上の servers は、サーバーの名前ごとに tools/list の結果を入れた辞書です。次の2つの関数を書いてください。

  • merge_tools(servers):すべてのサーバーのツールを、Function Calling の定義(type・name・description・parameters)のリストにする。name は「サーバー名__ツール名」にする
  • route(function_name):「サーバー名__ツール名」を (サーバー名, ツール名) に分ける。ツール名に __ が入っていてもよいように、最初の __ で分ける
def merge_tools(servers):
    # ここに書く
    return []


def route(function_name):
    # ここに書く("calendar__search" -> ("calendar", "search"))
    return None, None


print([t["name"] for t in merge_tools(servers)])
print(route("sales__search"))
解答を見る
def merge_tools(servers):
    result = []
    for server, tools in servers.items():
        for t in tools:
            result.append({
                "type": "function",
                "name": f"{server}__{t['name']}",
                "description": t["description"],
                "parameters": t["inputSchema"],
            })
    return result


def route(function_name):
    server, tool = function_name.split("__", 1)
    return server, tool


print([t["name"] for t in merge_tools(servers)])
print(route("sales__search"))

split("__", 1) の 1 は「最初の1か所だけで分ける」という意味です。モデルが sales__search を呼びたいと言ってきたら、ホストは route で sales のサーバーを選び、search という名前で tools/call を送ります。サーバーの名前に __ を使わないように決めておけば、この方法で迷わずに届け先を決められます。

このコースの進め方

レッスン内容
1. MCPとは?解決する困りごと、登場人物、Function Calling との関係(このレッスン)
2. できあがったMCPサーバーを使うClaude Desktop・Claude Code・ChatGPT・Cursor などへのつなぎ方、context7、信頼できるサーバーの選び方
3. PythonでMCPサーバーを作るuv と公式の Python SDK で小さなサーバーを作り、確かめて、つなぐ
4. データ分析のツールを作る①読み込み・統計量・グループ集計・期間ごとの集計・上位N件(ブラウザで動かせます)
5. データ分析のツールを作る②相関・外れ値・結合・クロス集計と、AIが読みやすい結果の返し方(ブラウザで動かせます)
6. 分析サーバーを仕上げて使う関数をまとめてサーバーにし、Claude や自分のプログラムから分析を頼む
7. MCPを安全に使う権限、秘密の情報、プロンプトインジェクション、ツールの承認、リモートのサーバーとログイン

レッスン3とレッスン6は、自分のパソコンに Python の環境を作って進めます。準備のしかたは、レッスン3で説明します。

まとめ

  • MCP は、AIアプリと外の道具・データをつなぐための共通の規格。道具を MCP サーバーとして1つ作れば、MCP に対応したどのAIアプリからも使える
  • 登場人物は、ホスト(AIアプリ)・クライアント(ホストの中でサーバーとやりとりする部品)・サーバー(道具を差し出すプログラム)
  • サーバーは、ツール(モデルが呼ぶ)・リソース(アプリや人が読ませる)・プロンプト(人が選ぶひな形)を差し出せる
  • やりとりは JSON-RPC。tools/list で一覧をもらい、tools/call で呼ぶ。通り道は stdio(ローカル)と Streamable HTTP(リモート)
  • MCP は Function Calling の代わりではなく、その上に乗る仕組み。ツールの一覧を関数の定義に直し、頼みをサーバーに届けるのはホストの仕事

次のレッスンでは、できあがった MCP サーバーを Claude Desktop や Claude Code につないで、実際に使ってみます。