🧑‍⚖️

MCPをちょっとだけ理解できるかもしれない記事

に公開

執筆日

2025/5/24

はじめに

完全攻略ガイド!みたいな感じにしたかったのですが思ったより完全攻略できなかったので、ちょっとわかったことを共有します。このブログで話すことは以下です。言語はpythonを使います。

  • MCPってたぶんこんな感じ
  • FastMCPを使ってMCPサーバーをpythonで立ててみる
  • Inspectorを使ってMCPサーバーをWeb GUIでデバッグしてみる
  • OpenAI の AgentSDK を使ってGPTとMCPサーバーのやり取りを実践してみる

概要

MCPとは

Model Context Protocol(Model Capabilities Protocolと書いてあるブログが検索上位にヒットして渋い顔になりました)の略称です。
2024年11月にClaudeの開発で知られるAnthoropic社がオープンソースで公開しました。以下の公開ドキュメントがあるのでこちらを参照すると情報の1次ソースとして適切です。
https://modelcontextprotocol.io/introduction
Introductionに、

MCP is an open protocol that standardizes how applications provide context to LLMs. Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools.

とあり、MCPってLLMとツールを繋ぐUSB-Cポートのような接続規格なんだよ、ということが言われています。スマホの充電ケーブルがinput, outputでUSB type-Aやmicro-USBやlightningやらから全部USB-Cに統一されたように、LLMとツールを接続する規格を揃えようということが言いたいんだと思います。現在ほとんどのLLMにFunction Calling(Tool)でLLMに関数を呼び出して実行させる機能が備わっていますが、各社開発しているモデル・言語・ライブラリによって呼び出し後の処理が異なっており複雑です。その規格を標準化しようというのがMCPの思想のようです。
モデル側もなんでも使えて(MCP対応モデルである必要はありますが2025年5月現在主要な大手プロバイダーのモデルはMCP対応が増えています)、ツール側も何の言語で書かれていても良いとなると開発の自由度が上がって楽しそうです。

MCPを使った一般的なアーキテクチャ

こちらも公式ドキュメントから拝借した画像です。
モデルが動作するクライアント ⇔ MCP ⇔ 外部情報ソースを取得するサーバー(MCPサーバー)⇔ 外部情報源
という形でクライアントとサーバーを接続するProtocolがMCPであるということですね。

まあなんとなくわかる……?という感じにはなりますが、やはり実際に作ってみて動かすのが一番わかりやすいだろうということで実践に行きましょう。

使用する諸々

  • モデル: Azure OpenAIからGPT-4.1を使います
  • 言語: クライアント・サーバー共にpython(せっかく色々接続しやすいのに……と思ったあなたは正しいです)
  • 外部情報源: GoogleNews

python環境構築

MCPサーバーを使うPython環境はuvで作ることが推奨されています(なんでかはわからないのでわかる人がいれば教えて欲しいです)。pipでも問題なさそうですが推奨環境で使う場合はuvをインストールしてください。(uvもpip install出来ますが自分は上手く使えなかったのでStandaloneインストーラの方が簡単でした)
https://github.com/modelcontextprotocol/python-sdk
https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-python
公式のデモはAnthoropic社のものなのでクライアントにClaude デスクトップを使っています。

実践

サーバーを立てるコード

とりあえずGoogleNewsを使って最新のニュースを検索するMCPサーバーをFastMCPで作るコードです。
Docstringの形でLLMにツールの使い方を教えることができます。

コード
news.py
from GoogleNews import GoogleNews
from mcp.server.fastmcp import FastMCP

# MCPサーバーのインスタンスを作成
mcp = FastMCP("NEWS Searcher")

RESULT_TEMPLATE = """\
タイトル: {title}
メディア: {media}
日時: {date}
概要: {text}
URL: {url}"""

@mcp.tool()
def search_news(keyword: str) -> float:
    """検索キーワードを使ってGoogle Newsで最新のニュースを検索します。
Args:
    search_target (str): 検索キーワード
Returns:
    str: 検索結果のまとめ
    """
    googlenews = GoogleNews()
    googlenews.search(key=keyword)

    # 記事の一覧を取得
    results = googlenews.results()

    ret = []
    # 上位3件を取得
    for i, article in enumerate(results[:3], start=1):
        ret.append(RESULT_TEMPLATE.format(
            title=article["title"],
            media=article["media"],
            date=article["date"],
            text=article["desc"],
            url=article["link"]
        ))

    return "\n\n".join(ret)

# サーバーを起動
if __name__ == "__main__":
    mcp.run(transport="stdio")

Inspectorを使ってMCPサーバーをデバッグ

Inspectorを使うことでMCPサーバーの動作確認ができます。
以下コマンドでサーバーとの接続テストを行うWebアプリが立ち上がります。

$ npx @modelcontextprotocol/inspector uv run news.py
---- output ----
Starting MCP inspector...
⚙️ Proxy server listening on port 6277
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀

アドレスを開くとこんな感じ。

サイドバーから[connect]をクリックするとWebアプリがMCPサーバーと接続されます。
今回はデコレーターで@mcp.toolを使ってToolsを作っているので、上部の選択から[Tools]をクリック、[List Tools]を押すと下図中央のように定義した関数が表示されます。定義している変数keywordに"生成AI"と入力して[Run Tool]を実行すると下図右下の緑文字の部分でToolが実行された結果を確認できます。

実際はLLMがこのToolを理解して質問に応じてkeywordを抽出して実行してくれるわけですが前もってToolの動作だけをテスト出来るってことですね。
実際LLMにはどんな形でToolが渡されてるのか気になる場合は、[History]のところでtools/listの結果を確認してみましょう。

function callingを使ったことがある人なら、あれこれ一緒じゃない?と思うかもしれませんがほぼほぼ中身は一緒です。(おそらくFastMCPが)関数のdocstringや引数を自動でパースしてJSONに変換してくれています。

GPTとMCPサーバーを接続

次はいよいよLLMモデルにMCPサーバーを使わせてみます。モデルはAzure OpenAIでデプロイしたGPT-4.1を使ってみます。Agent SDKを使うことでMCPサーバーと接続できます。

コード
mcp_agent.py
import asyncio
from agents import Agent, Runner, OpenAIResponsesModel, set_default_openai_client, set_tracing_disabled
from openai import AsyncAzureOpenAI
from agents.mcp import MCPServerStdio, MCPServerStdioParams

OPENAI_ENDPOINT = "https://<AOAI リソース名>.openai.azure.com/"
OPENAI_KEY = "<api key>"
OPENAI_API_VERSION = "2025-03-01-preview" # 2025-03-01-preview以降であればResponses APIが使えます
MODEL_NAME = "gpt-4.1"

async def main():
    # Azure OpenAIの設定
    client = AsyncAzureOpenAI(
        api_key=OPENAI_KEY,
        api_version=OPENAI_API_VERSION,
        azure_endpoint=OPENAI_ENDPOINT,
    )
    # Agents SDK にクライアントを設定
    set_default_openai_client(client)
    # トレース機能を無効にする(OpenAIのダッシュボードと接続しない場合オフにしないと401エラーが出る。)
    set_tracing_disabled(disabled=True)

    params = MCPServerStdioParams({
            "command": "python",
            "args": ["news.py"],
        })

    # MCPサーバーの設定
    async with MCPServerStdio(
        params=params
    ) as mcp_server:
        # MCPサーバーのチェック
        tools = await mcp_server.list_tools()
        print("mcp tools list:", tools)

        # エージェントの作成
        agent = Agent(
            name="Assistant",
            instructions="あなたはニュース検索エージェントです。最新のニュースを検索して、ユーザーに提供します。",
            mcp_servers=[mcp_server],
            model=OpenAIResponsesModel( 
                model=MODEL_NAME,
                openai_client=client,
            )
        )

        while True:
            # ユーザーからの入力を待つ
            user_input = input("user input\n>> ")
            if user_input.lower() == 'exit' or user_input.lower() == 'q':
                break

            # エージェントに入力を渡す
            result = await Runner.run(
                starting_agent=agent, 
                input=user_input,
            )
            print(result)
            # print(result.final_output) # 最終回答だけ見たい場合はこっちでいい

if __name__ == "__main__":
    asyncio.run(main())

実行してみます。

実行結果
$ python mcp_agent.py
---- output ----
mcp tools list: [Tool(name='search_news', description='検索キーワードを使ってGoogle Newsで最新のニュースを検索します。\nArgs:\n    search_target (str): 検索キーワード\nReturns:\n    str: 検索結果のま とめ\n    ', inputSchema={'properties': {'keyword': {'title': 'Keyword', 'type': 'string'}}, 'required': ['keyword'], 'title': 'search_newsArguments', 'type': 'object'}, annotations=None)]
user input
>> 生成AIについての最近のニュースを教えてください
RunResult:
- Last agent: Agent(name="Assistant", ...)
- Final output (str):
    生成AIに関する最近のニュースは以下の通りです:
    
    1. University of British Columbia Cloud Innovation Centreが、AWSを活用して生成AIのソリューションをプロトタイピング(試作開発)しています。Amazon Bedrockや基盤モデルを活用した教育やカスタマーソリューションの事例が紹介されています。(詳細はこちら)
    
    2. Google DeepMindが最新の動画生成モデル「Veo 3」を発表しました。また、「Veo 2」の新たな機能も追加されています。生成AIの映像領域での技術進化が注目されています。(詳細はこちら)

    3. Google DeepMindが「Gemma」と呼ばれる最新のオープンモデルを発表しました。これはワークステーションやノートPC、スマートフォンなど、様々なデバイスで動作するAIアプリ開発を支援するものです。(詳細は こちら)

    もっと詳しい内容や特定テーマでのニュースが必要な場合はお知らせください。
- 3 new item(s)
- 2 raw response(s)
- 0 input guardrail result(s)
- 0 output guardrail result(s)
(See `RunResult` for more details)

途中経過の見方がよくわかっていませんがとりあえずいい感じの回答が生成できましたね。
function callingと違って関数実行結果を入れてもう一回クライアントに投げなおすみたいな手間がないのがかなり好印象です。Agent SDKを使っているので、それぞれ違うMCPサーバーに接続したAgentを用意して特化エージェントを作成してA2Aシステムを作るのも簡単です。

おわり

今回紹介したのはMCPのほんの触りの部分です。様々な機能、LLMをもっと使いこなすための色々があるので是非ドキュメントを読み込んで色んな機能を試してみることをオススメします。

公開されているMCPサーバー

今回は自分でFastMCPを使って自分でサーバーを立ち上げてみましたが、MCPサーバーの真骨頂は今後様々なアプリケーションがMCPサーバーを公開してくれることでアプリケーションとLLMの接続が容易になることかもしれません。以下の記事に色々とMCPサーバーを公開しているアプリケーションなどがまとめられているのでまた触ってみたいです。
https://weel.co.jp/media/tech/mcp-server-list/

参考

https://modelcontextprotocol.io/introduction

ヘッドウォータース

Discussion