じゃあ、おうちで学べる

本能を呼び覚ますこのコードに、君は抗えるか

MCP-Use を使っていきます

MCP-Useとは何か?

MCP-Use (Model Context Protocol - Use) は、LLM(大規模言語モデル)とMCPサーバーの間の橋渡しをするPythonライブラリです。このライブラリにより、OpenAI、Anthropic、Groqなど様々なLLMプロバイダーのモデルに、Webブラウジングやファイル操作といった外部ツールへのアクセス権を付与できます。

github.com

環境構築:uvの活用

今回はRustベースの高速パッケージマネージャーuvを使って環境を構築します。

docs.astral.sh

# 仮想環境を作成
uv venv

# 仮想環境をアクティベート
source .venv/bin/activate.fish  # fishシェル使用時

# 必要なパッケージをインストール
uv pip install "mcp-use[dev,anthropic,openai,search]"
uv pip install fastembed
uv pip install python-dotenv langchain-openai

従来のpipと比較してuvは大幅に高速で、特に複雑な依存関係を持つプロジェクトではその差が顕著です。MCP-Useはさまざまな依存関係を持つため、uvの使用が特に有効です。

MCP-Useの基本構造

MCP-Useの中核は以下のクラスから構成されています:

  1. MCPClient: 設定ファイルからMCPサーバーへの接続を管理
  2. MCPAgent: LLMとMCPサーバーを組み合わせてタスクを実行
  3. 各種アダプター: LLMプロバイダーとMCPサーバー間の変換処理

実装例:ウェブ情報取得エージェント

今回はMCP-Useを使って、特定のWebサイトから情報を抽出するエージェントを構築します。

import asyncio
import os

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from mcp_use import MCPAgent, MCPClient


async def main():
    # 環境変数を読み込み
    load_dotenv()

    # 設定ファイルからMCPClientを作成
    client = MCPClient.from_config_file(
        os.path.join(os.path.dirname(__file__), "browser_mcp.json")
    )

    # LLMを初期化
    llm = ChatOpenAI(model="gpt-4o")
    
    # エージェントを作成
    agent = MCPAgent(llm=llm, client=client, max_steps=30)

    # クエリを実行
    result = await agent.run(
        "3-shake.com にアクセスして株式会社スリーシェイクのCEOのxアカウントを教えて下さい",
        max_steps=30,
    )
    print(f"\nResult: {result}")


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

以下、各部分の詳細を解説します。

1. MCPClient初期化とその内部構造

client = MCPClient.from_config_file(
    os.path.join(os.path.dirname(__file__), "browser_mcp.json")
)

MCPClientクラスはMCPサーバーへの接続を管理します。from_config_fileメソッドで設定ファイルから構成を読み込みます。

設定ファイルbrowser_mcp.jsonの中身は以下のようになっています:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"],
      "env": {
        "DISPLAY": ":1"
      }
    }
  }
}

この設定は、PlaywrightをMCPサーバーとして使用することを指定しています。MCPClientはこの設定を読み込み、以下の処理を実行します:

  1. 設定に基づいて適切なコネクタ(この場合はStdioConnector)を作成
  2. コネクタを使ってPlaywright MCPサーバーとの通信チャネルを確立
  3. 初期化処理を実行し、利用可能なツールの一覧を取得

内部的には、MCP-Useは非同期処理を多用しており、asyncioを活用した効率的な通信を実現しています。

2. LLMの初期化と統合

llm = ChatOpenAI(model="gpt-4o")

MCP-UseはLangChainとシームレスに統合されており、様々なLLMプロバイダーのモデルを使用できます。今回はOpenAIのGPT-4oを使用していますが、以下のように簡単に切り替えることも可能です:

# Anthropicのモデルを使用する場合
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")

# Groqのモデルを使用する場合
from langchain_groq import ChatGroq
llm = ChatGroq(model="llama3-8b-8192")

MCP-Useの内部では、LangChainAdapterクラスがLLMとMCPサーバー間の変換処理を担当し、ツールの記述をLLMが理解できる形式に変換しています。

3. MCPAgentの作成と実行

agent = MCPAgent(llm=llm, client=client, max_steps=30)

MCPAgentクラスは、LLMとMCPクライアントを組み合わせてタスクを実行するための中核コンポーネントです。主なパラメータは:

  • llm: 使用するLLMモデル
  • client: MCPクライアントインスタンス
  • max_steps: エージェントが実行できる最大ステップ数

max_stepsパラメータは特に重要で、タスクの複雑さに応じて適切な値を設定する必要があります: - 単純な情報検索: 5-10ステップ - 複数ページの探索: 15-20ステップ - 複雑な操作: 25-30ステップ

4. タスク実行の内部処理

result = await agent.run(
    "3-shake.com にアクセスして株式会社スリーシェイクのCEOのxアカウントを教えて下さい",
    max_steps=30,
)

agent.run()メソッドが呼び出されると、以下の処理が実行されます:

  1. 指定されたクエリをLLMに送信し、実行プランを生成
  2. LLMが適切なツールを選択し、その実行をリクエス
  3. MCPクライアントがツールのリクエストをMCPサーバーに転送
  4. MCPサーバーがツールを実行し、結果を返す
  5. 結果をLLMに返し、次のステップを決定
  6. 最終的な回答が生成されるまで、ステップ2-5を繰り返す

内部的には、この処理はMCPAgent.run()メソッド内の_agent_executor._atake_next_step()メソッドで実装されています。