0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

mcp-use で複数MCPサーバーを1つのエージェントに束ねる — PythonでLLM非依存のツール実行を実装する

0
Last updated at Posted at 2026-06-21

はじめに

Model Context Protocol(MCP) は、LLM に外部ツールやデータソースを接続するための標準プロトコルです。サーバーは急速に増えましたが、いざ自前のエージェントから使おうとすると「どの LLM プロバイダーからどのサーバーへどう接続するか」を毎回書く手間が残ります。

mcp-use は、この接続部分を肩代わりする OSS(MIT ライセンス)の Python フレームワークです。任意の LLM を任意の MCP サーバーにつなぎ、数行で自律エージェントを組める のが特徴です。本記事では pip install から、複数サーバーの束ね方・効率化・ストリーミングまでを、そのまま動かせるコードで解説します。

この記事で学べること

  • mcp-use で MCP サーバーのツールを直接呼ぶ方法(MCPClient
  • 自然言語の指示からツールを自動実行するエージェントの作り方(MCPAgent
  • 複数の MCP サーバーを 1 つのエージェントに束ね、Server Manager で効率化する方法
  • 実行過程をリアルタイムに受け取るストリーミング

対象読者

  • MCP サーバーを自前のエージェントから使いたいエンジニア
  • 特定の LLM プロバイダーにロックインされないツール実行基盤を作りたい方

前提環境

  • Python 3.11 以上
  • Node.js(サンプルの MCP サーバーを npx で起動するため)
  • 利用する LLM プロバイダーの API キー(例: OPENAI_API_KEY / ANTHROPIC_API_KEY

TL;DR

  • mcp-use は「任意の LLM × 任意の MCP サーバー」をつなぐ OSS フレームワーク(MIT・本記事執筆時点 v1.32.1)
  • MCPClient でツールを直接叩け、MCPAgent なら自然言語の指示からツールを自動選択・実行できる
  • use_server_manager=True で複数サーバーのツール混在による混乱を抑え、必要なサーバーにだけ接続する
  • agent.stream() で中間ステップ(どのツールを何の引数で呼んだか)を逐次受け取れる

mcp-use が解決する課題

MCP サーバーは「ファイルシステム」「データベース」「Web 検索」などツールごとに分かれて提供されます。これを複数の LLM プロバイダーから使おうとすると、プロバイダーごと・サーバーごとに接続コードが増え、組み合わせの数(M×N)だけ実装が膨らみます。

mcp-use は LangChain のチャットモデルを LLM として受け取り、MCP サーバーへの接続・セッション管理・ツール一覧の取得を共通化します。結果として、LLM プロバイダーを差し替えても、MCP サーバーを足しても、エージェント側のコードはほぼ変わりません。

セットアップ

pip install mcp-use
# 使う LLM プロバイダーの LangChain 連携も入れる
pip install langchain-openai langchain-anthropic

API キーは環境変数で渡します。

export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."

ステップ1: MCPClient でツールを直接呼ぶ

まずは LLM を挟まず、MCP サーバーのツールを直接呼んでみます。サーバーは公式の server-everything(動作確認用のサンプルサーバー)を npx で起動します。

import asyncio
from mcp_use import MCPClient

async def main():
    config = {
        "mcpServers": {
            "calculator": {
                "command": "npx",
                "args": ["-y", "@modelcontextprotocol/server-everything"],
            }
        }
    }
    client = MCPClient.from_dict(config)
    await client.create_all_sessions()

    session = client.get_session("calculator")
    result = await session.call_tool(name="add", arguments={"a": 5, "b": 3})
    print(f"Result: {result.content[0].text}")  # => Result: 8

    await client.close_all_sessions()

asyncio.run(main())

configmcpServers に「サーバー名」と「起動コマンド」を書くだけで、mcp-use がプロセス起動とセッション確立まで面倒を見ます。ツールの戻り値は result.content[0].text で取り出せます。

ステップ2: MCPAgent で自然言語からツールを実行する

次に LLM を挟み、「やりたいこと」を自然言語で渡してツールを自動選択・実行させます。ここがエージェントの本体です。

import asyncio
from langchain_openai import ChatOpenAI
from mcp_use import MCPAgent, MCPClient

async def main():
    config = {
        "mcpServers": {
            "filesystem": {
                "command": "npx",
                "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
            }
        }
    }
    client = MCPClient.from_dict(config)
    llm = ChatOpenAI(model="gpt-4o")
    agent = MCPAgent(llm=llm, client=client)

    result = await agent.run("List all files in the directory")
    print(result)

asyncio.run(main())

MCPAgentclient が公開する全ツールを LLM に提示し、指示に応じて適切なツールを呼び出します。

LLM プロバイダーを差し替える

mcp-use は LangChain のチャットモデルを受け取るだけなので、LLM 部分を入れ替えてもエージェントのコードは変わりません。 Anthropic の Claude を使う場合は、llm の生成だけを差し替えます。

from langchain_anthropic import ChatAnthropic

# model はアカウントで利用可能なモデル ID に置き換える
llm = ChatAnthropic(model="claude-sonnet-4-6")
agent = MCPAgent(llm=llm, client=client)

このプロバイダー非依存性が、特定ベンダーへのロックインを避けたいケースで効いてきます。

ステップ3: 複数サーバーを束ねて Server Manager で効率化する

複数の MCP サーバーを 1 つのエージェントに束ねられます。ただしサーバーが増えるとツール数も増え、LLM がツール選択で混乱しやすくなります。これを抑えるのが Server Manager です。

import asyncio
from langchain_openai import ChatOpenAI
from mcp_use import MCPAgent, MCPClient

async def main():
    config = {
        "mcpServers": {
            "filesystem": {
                "command": "npx",
                "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
            },
            "everything": {
                "command": "npx",
                "args": ["-y", "@modelcontextprotocol/server-everything"],
            },
        }
    }
    client = MCPClient.from_dict(config)
    llm = ChatOpenAI(model="gpt-4o")

    agent = MCPAgent(
        llm=llm,
        client=client,
        max_steps=40,              # ツール呼び出しの最大ステップ数
        use_server_manager=True,   # 必要なサーバーにだけ動的に接続する
    )

    result = await agent.run("一時ディレクトリのファイル一覧を取得して、件数を数えて")
    print(result)

asyncio.run(main())

use_server_manager=True を付けると、エージェントは「そのステップで選んだツールが属するサーバー」にだけ接続します。全サーバーへ常時つなぐ無駄を省き、ツール検索もサーバー単位に整理されるため、サーバーが多いほど効果が出ます。特定のサーバーだけを使わせたい場合は、agent.run("...", server_name="filesystem") のように対象を明示することもできます。

max_steps は安全装置でもあります。ツールを延々と呼び続けるループを防ぐため、タスクの複雑さに応じて適切な上限を設定してください。

ステップ4: 実行過程をストリーミングで受け取る

長時間タスクや対話 UI では、最終結果だけでなく「途中でどのツールを呼んだか」を逐次見せたくなります。agent.stream()(action, observation) のペアを順次 yield します。

async def main():
    # ... client / llm / agent の準備は同上 ...
    async for action, observation in agent.stream("一時ディレクトリのファイルを一覧して"):
        # action: 呼び出したツール・入力・思考ログ
        print(f"[tool] {action.tool} <- {action.tool_input}")
        # observation: ツールの実行結果
        print(f"[result] {observation}")

action には呼び出したツール名(tool)・入力(tool_input)・推論ログ(log)が、observation にはツールの実行結果が入ります。これを UI に流せば、エージェントの「考えながら手を動かす」過程をそのまま可視化できます。

ハマりポイント

ポイント1: MCP サーバーの起動コマンドが解決できない

サンプルは npx で MCP サーバーを起動するため、Node.js が未インストールだとセッション確立に失敗します。node -v / npx -v が通ることを先に確認してください。Python 製サーバーを使う場合は commanduvxpython に変えます。

ポイント2: API キー未設定で MCPAgent がエラーになる

MCPClient 単体(ステップ1)は LLM を使わないため API キー不要ですが、MCPAgent は LLM を呼ぶため対応する環境変数(OPENAI_API_KEY など)が必要です。プロバイダーを差し替えたら、対応するキーも設定し直してください。

ポイント3: Server Manager は「多サーバー時」に効く

サーバーが 1 つだけのときは use_server_manager の効果は小さく、かえってオーバーヘッドになります。ツールが多数のサーバーにまたがり、LLM がツール選択で迷う段階になってから有効化するのが目安です。

まとめ

  • mcp-use を使うと「任意の LLM × 任意の MCP サーバー」の接続を共通化でき、プロバイダーやサーバーを差し替えてもエージェント側のコードを保てる
  • MCPClient でツールを直接呼び、MCPAgent で自然言語からツールを自動実行できる
  • 複数サーバーを束ねるときは use_server_manager=Truemax_steps で効率と安全性を確保する
  • agent.stream() で実行過程を可視化でき、対話 UI や長時間タスクの監視に使える

MCP サーバーが増え続けるなか、「つなぎ込み」を標準化しておくと、エージェントの構築・乗り換えが一気に楽になります。まずは server-everything でツール呼び出しの感触をつかむところから始めてみてください。

参考リンク

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?