MCP を試してみたの続き

# はじめに

「AI エージェント」を使おう、とよく聞きます。また、にわかに「MCP」が話題になっています。
そこで、LangChain を使って MCP を試してみました。

[LangChain を使って MCP を試してみた #AI - Qiita](https://qiita.com/tinymouse/items/2e22b655d8ba5fe6f3b3)

LangChain は、MCP だけでなく、生成 AI プログラムを作成するための多機能なライブラリです。MCP を容易に使うためのライブラリがないか、探してみました。

# mcp-use で MCP を使ってみる

`mcp-use` というライブラリが紹介されていました。これを使ってみます。

[任意のLLMを任意のMCPサーバーにMCP-Useを使用して接続する方法](https://apidog.com/jp/blog/beginners-guide-to-mcp-use/)

## 実行環境を用意する

AI プログラムの実行環境は、高速な計算するために大きなメモリや GPU を使います。そこでこれまで Google Colab を使ってきました。
ところが、MCP プログラムは後述するように、Colab 環境で期待したように動きません。
高性能な実行環境をクラウドサービスで用意することもできますが、Gemini API のようなクラウドサービスを呼出するなら CPU のみの実行環境でいいでしょう。
ただし、Python プログラムが実行できるようにしておきます。

## mcp-use を使う

必要なライブラリをインストールします。

```console
$ pip install mcp-use
```

`mcp-use` ライブラリは、`LangChain` を利用しているようです。また、`mcp` ライブラリも使用しているようです。上記のコマンドで、関連するライブラリもインストールされます。↑

続いて、`Gemini API` を使用するための準備します。

参考 [LangChainからGeminiを使う方法を詳しく解説する #Python - Qiita](https://qiita.com/Isaka-code/items/fd897f8745b847e15164)

```console
$ pip install langchain-google-genai
```

```ini:.env
GOOGLE_API_KEY=(予め取得した API キー)
```

`mcp-use` ライブラリを使って MCP サーバを呼出するコードです。↓

```python
import langchain_google_genai
import mcp_use
import asyncio

async def main():

    # モデルを準備
    model = langchain_google_genai.ChatGoogleGenerativeAI(
        model="gemini-2.0-flash",
    )

    # MCP サーバ呼出の設定
    config = {
        "mcpServers": {
            "filesystem": {
                "command": "npx",
                "args": ["-y","@modelcontextprotocol/server-filesystem","~/"]
            }
        }
    }

    # MCP クライアントを作成
    client = mcp_use.MCPClient.from_dict(config)

    # エージェントを用意
    agent = mcp_use.MCPAgent(model, client)

    # クエリを準備
    query = "ディレクトリ ~/ にどんなファイルがありますか。"

    # クエリを実行
    result = await agent.run(query=query)
    print(result)

    # セッションを閉じる
    await client.close_all_sessions()

asyncio.run(main())
```

実行結果↓

```
Final Answer: ディレクトリ ~/ にはファイルがなく、ディレクトリ .config と Desktop があります。
```

`mcp` ライブラリ、`LangChain` ライブラリをつかっているためか、以前に書いたコードとよく似ています。

以前は以下のプロンプトを指定していました。

```python
    # プロンプトを準備
    prompt = langchain_core.prompts.chat.ChatPromptTemplate.from_template(
    """Question: {input}
    Thought: Let's think step by step.
    Use one of registered tools to answer the question.
    Answer: {agent_scratchpad}"""
    )
```

これに相当するのは `mcp-use` ライブラリの内部に仕込まれているのでしょう。

## ウェブ検索する MCP サーバを使ってみる

ウェブ検索してみたいと思います。該当する機能の MCP サーバを探すと幾つか見つかります。そのうち以下の MCP サーバを使ってみます。

[microsoft/playwright-mcp: Playwright MCP server](https://github.com/microsoft/playwright-mcp )

この MCP サーバを呼出してみます。↓

```python
(前略)

    # MCP サーバ呼出の設定
    config = {
        "mcpServers": {
            "web-search": {
                "command": "npx",
                "args": ["@playwright/mcp"],
            }
        }
    }

(中略)

    # クエリを準備
    query = """Yahoo ニュースのサイトを開いて
    どんなニュースがあるか教えて下さい。"""

(後略)
```

## Gmail を操作する MCP サーバを使ってみる

メールを操作してみたいと思います。Gmail を操作する MCP サーバが幾つか見つかります。そのうち以下の MCP サーバを使ってみます。

[GongRzhe/Gmail-MCP-Server: A Model Context Protocol (MCP) server for Gmail integration.](https://github.com/GongRzhe/Gmail-MCP-Server)

Google Cloud サービスの `Gmail API` を使うようです。予め以下の用意しておきます。

参考 [GmailAPIを使うための事前設定（OAuth2認証）の行い方 | Analytics Transformation Blog](https://analytics-x.tech/archives/5613)

①Google Cloud サービスのコンソール画面を開きます。
②プロジェクトを用意します。
③[API とサービス] メニューの [API とサービス] 画面を開きます。
④ここで `Gmail API` を有効にします。

⑤[API とサービス] メニューの [認証情報] 画面を開きます。
⑥[認証情報を作成] して [OAuth クライアント ID] を作成します。
⑦[デスクトップアプリ] を指定します。
⑧適当な名前を入力して [作成] します。
⑨JSON ファイルをダウンロードします。
⑩ファイル名を `gcp-oauth.keys.json` にしておきます。

⑪ユーザフォルダつまり `~/` に `.gmail-mcp` フォルダを作ります。
⑫そこに上記のファイルをコピーします。
⑬コマンド `npx @gongrzhe/server-gmail-autoauth-mcp auth` を実行します。
⑭上記のフォルダに `credentials.json` ファイルが作られたことを確認します。

MCP サーバは、上記のフォルダの JSON ファイルの設定を利用して、Google Cloud の Gmail API を呼出することで、Gmail の操作します。

この MCP サーバを呼出してみます。↓

```python
(前略)

    # MCP サーバ呼出の設定
    config = {
        "mcpServers": {
            "web-search": {
                "command": "npx",
                "args": ["@gongrzhe/server-gmail-autoauth-mcp"],
            }
        }
    }

(中略)

    # クエリを準備
    query = "受信トレイに幾つのメールがありますか。"

(後略)
```

実行結果↓

```
{'input': '受信トレイに幾つのメールがありますか。', 'output': '受信トレイには9通のメールがあります。'}
```

## 複数の MCP サーバを連携して使ってみる

ウェブ検索して結果をメールで送る、みたいなことができないでしょうか。

呼出の設定に複数の MCP サーバを指定しておいて、エージェントの作成時に `use_server_manager` を指定するとできるようです。

```python
(前略)

    # MCP サーバ呼出の設定
    config = {
        "mcpServers": {
            "playwright": {
                "command": "npx",
                "args": ["@playwright/mcp"],
            },
            "gmail": {
                "command": "npx",
                "args": ["@gongrzhe/server-gmail-autoauth-mcp"],
            },
        }
    }

(中略)

    # エージェントを用意
    agent = mcp_use.MCPAgent(
        model, client,
        use_server_manager=True, max_steps=30,
    )

    # クエリを準備
    query = """Yahoo ニュースのウェブサイトを開いて、どんなニュースがあるか一覧にして、
    その結果を ********@gmail.com 宛にメールして。"""

(後略)
```

実行結果↓

```
Yahoo ニュースのウェブサイトを開いて、どんなニュースがあるか一覧にして、その結果を ********@gmail.com 宛にメールしました。
```

デバッグ情報を表示してみます。

```python
# デバッグモードの指定
mcp_use.set_debug(1)

(後略)
```

実行結果↓

```
2025-05-15 00:00:00,000 - mcp_use - INFO - 🚀 Initializing MCP agent and connecting to services...
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Server manager mode active with 6 management tools
2025-05-15 00:00:00,000 - mcp_use - INFO - 🧠 Agent ready with tools: list_mcp_servers, connect_to_mcp_server, get_active_mcp_server, disconnect_from_mcp_server, search_mcp_tools, use_tool_from_server
2025-05-15 00:00:00,000 - mcp_use - INFO - ✨ Agent initialization complete
2025-05-15 00:00:00,000 - mcp_use - INFO - 💬 Received query: 'Yahoo ニュースのウェブサイトを開いて、どんなニュースがあるか一覧にして、     その結果を ...'
2025-05-15 00:00:00,000 - mcp_use - INFO - 🏁 Starting agent execution with max_steps=30
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 1/30
(中略)
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: search_mcp_tools with input: {'top_k': 5.0, 'query': 'open website'}
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Search results  [1] Tool: browser_click (70.3% match)     Server: playwright     Description: Per...   
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 2/30
(中略)
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: search_mcp_tools with input: {'top_k': 5.0, 'query': 'list news'}
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Search results  [1] Tool: browser_tab_list (66.3% match)     Server: playwright     Description: ...   
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 3/30
(中略)
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: search_mcp_tools with input: {'top_k': 5.0, 'query': 'extract text from website'}
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Search results  [1] Tool: browser_type (70.4% match)     Server: playwright     Description: Type...   
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 4/30
(中略)
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: search_mcp_tools with input: {'top_k': 5.0, 'query': 'send email'}
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Search results  [1] Tool: send_email (80.7% match)     Server: gmail     Description: Sends a new...   
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 5/30
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: connect_to_mcp_server with input: {'server_name': 'playwright'}
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Connected to MCP server 'playwright'. 25 tools are now available.
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 6/30
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: connect_to_mcp_server with input: {'server_name': 'gmail'}
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Connected to MCP server 'gmail'. 13 tools are now available.
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 7/30
2025-05-15 00:00:00,000 - mcp_use - INFO - Executing tool 'browser_navigate' on server 'playwright'with input: {structured_input}
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: use_tool_from_server with input: {'server_name': 'playwright', 'tool_input': '{"url": "https://news.yahoo.co.jp/"}', 'tool_name': ...
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: - Ran Playwright code: ```js // Navigate to https://news.yahoo.co.jp/ await page.goto('https://ne...   
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 8/30
2025-05-15 00:00:00,000 - mcp_use - INFO - Executing tool 'send_email' on server 'gmail'with input: {structured_input}
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: use_tool_from_server with input: {'server_name': 'gmail', 'tool_input': '{"to": "********@gmail.com", "subject": "Yahoo News", "...
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Error: [   {     "code": "invalid_type",     "expected": "array",     "received": "string",     "...   
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 9/30
2025-05-15 00:00:00,000 - mcp_use - INFO - Executing tool 'send_email' on server 'gmail'with input: {structured_input}
2025-05-15 00:00:00,000 - mcp_use - INFO - 🔧 Tool call: use_tool_from_server with input: {'server_name': 'gmail', 'tool_input': '{"to": ["********@gmail.com"], "subject": "Yahoo News",...
2025-05-15 00:00:00,000 - mcp_use - INFO - 📄 Tool result: Email sent successfully with ID: 196d63e7421215d2
2025-05-15 00:00:00,000 - mcp_use - INFO - 👣 Step 10/30
2025-05-15 00:00:00,000 - mcp_use - INFO - ✅ Agent finished at step 10
2025-05-15 00:00:00,000 - mcp_use - INFO - 🎉 Agent execution complete

```

`mcp-use` ライブラリが、与えられた指示に対して使用できる機能をチェックして順々に呼出していることが分かります。↑

# おわりに

MCP を使うことで、アプリ自体で機能（関数）を実装しないで別に用意されたプログラムを呼出すればよく、機能の呼出を生成 AI モデルで制御することで、プログラミング言語でなく自然言語で指示できるようになっています。

上記のコードは、実行してみると成功したり失敗したりします。生成 AI モデルで制御している限界でしょうか。生成 AI モデルに渡すプロンプトを、呼出する機能に合わせて追加で指示するといいのかも知れません。