😽

【MCP】AIからMCPサーバーの自動的な使い分けをさせる短いサンプルコード【ローカル】

に公開

さて、ロボットを作っています。
https://x.com/mty_mno/status/1964643843477062084
このハロにMCPの機能を付けました。
その時にAIからmcpサーバーの使い分けをする最小構成をつくったりしたので、ブログでもそこを公開しようと思い立ちました。

MCPって何がうれしいの?

AIにやってもらいたいこととして
「これやっておいて」
といったら、AI側でそれを実現できるツールをよしなに選択してイイカンジにやっておいてほしいわけです。
「MCPの概要を教えて」
といったら、検索ツールに接続して結果をイイカンジに教えてくれたり、
「洗濯機回しておいて」
といったら、検索ではなく、洗濯機をスタートさせてもらいたいわけです。
なんだけど、今まではツールへの指示方法がバラバラだからそれぞれで実装が必要で大変、という現実がありました。
それを「同じにしたらいいじゃん」というのがMCPなわけです。
なので本来やりたいこととしては
「AI側が目的を達成できるツールをよしなに選んで実行できること」
これになります。

実際にAIに出し分けさせるような例が少なめ?

MCPの簡単な例を探していると、MPCサーバー実装してクライアント実装して直接叩いて結果が出る……が多い気がしました。
AIからよしなにツール使い分けは?となりましたので、簡易的な例を作ってブログに置いておこうと思った次第でした。

Playwright MCPとBrave search MCPの使い分けをやってみる

まずはコード。
これでAIに
「テスターちゃんの概要を教えて?」(※僕はマンガ家をやっておりまして、出版しているマンガです)
と言えばBrave search MCPが呼び出されますし
https://hotel-example-site.takeyaqa.dev/ja/ にアクセスして、宿泊予約をクリックして、どんなプランがあるか教えて」
と言えばPlaywright MCPでブラウザがゴリゴリ動いてプランを教えてくれます。
メッセージを投げるだけで、AI側でよしなにツールの使い分けをしてくれる というわけです。
https://github.com/jam0824/mcp_local_demo

import { Agent, run, MCPServerStdio } from "@openai/agents";

// Brave(検索)— 同一PCで子プロセス起動(stdio)
const brave = new MCPServerStdio({
  name: "brave",
  // 公式サーバーを使うなら: "npx -y @brave/brave-search-mcp-server"
  fullCommand: "npx -y brave-search-mcp",
  env: { BRAVE_API_KEY: process.env.BRAVE_API_KEY },
});

// Playwright(ブラウザ操作)— 同一PCで子プロセス起動(stdio)
const playwright = new MCPServerStdio({
  name: "playwright",
  fullCommand: "npx -y @playwright/mcp@latest --browser=chromium",
  env: {
    // 画面を表示したい時は headless を使わない(デフォで表示されます)
    // 明示したいなら次行をコメント解除: HEADLESS: "0",
  },
});

await brave.connect();
await playwright.connect();

try {
  const agent = new Agent({
    name: "local-mcp-agent",
    model: "gpt-4o-mini",
    instructions: `
あなたはMCPツールを使ってユーザーの依頼を解決します。
- Web/ニュース/画像の検索: 「brave」を使う。
- 実ブラウザ操作(遷移/クリック/入力/待機など): 「playwright」を使う。
- 出典URLや実行手順を簡潔に示し、日本語で答える。`,
    mcpServers: [brave, playwright],
  });

  const query =
    process.argv[2] ??
    "https://hotel-example-site.takeyaqa.dev/ja/ にアクセスして、宿泊予約をクリックして、どんなプランがあるか教えて";
  const result = await run(agent, query);

  // きれいにして標準出力(JSONのみ)
  process.stdout.write(JSON.stringify({ output: result.finalOutput }) + "\n");

} catch (e) {
  console.error(e?.stack || String(e));
  process.exitCode = 1;
} finally {
  await Promise.allSettled([brave.close(), playwright.close()]);
}

前準備

必要なもののインストール

npm i @openai/agents

playwrightのブラウザもインストール

npx playwright install chromium

API keyの設定

windowsのpowershellだと以下

$env:OPENAI_API_KEY = "<あなたのOpenAI APIキー>"
$env:BRAVE_API_KEY  = "<あなたのBrave APIキー>"

macなどだと以下

export OPENAI_API_KEY="あなたのOpenAI APIキー"
export BRAVE_API_KEY="あなたのBrave APIキー"

実行

以下の様に入力すると、AIがよしなにplaywright MCPを選択して自動テスト練習サイトを開き、プラン情報を取得してくれます。

node index.mjs "https://hotel-example-site.takeyaqa.dev/ja/ にアクセスして、宿泊予約をクリックして、どんなプランがあるか教えて"


以下の様に入力すると、AIがよしなにBrave search MCPを選択して検索結果を教えてくれます。

node index.mjs "テスターちゃんについて教えて"

説明

このコードはOpenAI Agent SDKを使っています。
また、このコードではコードを実行している同じPC上でのMCPサーバー実行をさせています。(標準入出力を使用)

サービスの追加

以下の様に、使いたいMCPサーバーを追加していけばよいです。

// Brave(検索)— 同一PCで子プロセス起動(stdio)
const brave = new MCPServerStdio({
  name: "brave",
  // 公式サーバーを使うなら: "npx -y @brave/brave-search-mcp-server"
  fullCommand: "npx -y brave-search-mcp",
  env: { BRAVE_API_KEY: process.env.BRAVE_API_KEY },
});

// Playwright(ブラウザ操作)— 同一PCで子プロセス起動(stdio)
const playwright = new MCPServerStdio({
  name: "playwright",
  fullCommand: "npx -y @playwright/mcp@latest --browser=chromium",
  env: {
    // 画面を表示したい時は headless を使わない(デフォで表示されます)
    // 明示したいなら次行をコメント解除: HEADLESS: "0",
  },
});

await brave.connect();
await playwright.connect();

fullCommandは、自分のPCで動かすときのコマンドです。
envには渡したい環境変数を書きます。(braveだとapi keyなどですね)

外部公開されているサービスとやり取りしたい

外部の公開MCPサーバーとやり取りしたい場合はこんな感じにすればよいです。

const playwright = new MCPServerStreamableHttp({
  name: "playwright",
  url: "https://~~~~~~~~~~~~~~~~~",
  // 認証をかけている場合はヘッダも渡せる
  // requestInit: { headers: { Authorization: "Bearer xxx" } },
});

playwrightなど、他のPCで実行してるんだけどどうアクセスしよう……
という人はngrokを使うのもよさそうです。
(ローカルPC上で動いているモノを外部公開できるサービス)
……って、やろうとしたらウィルス判定されているし……。

AI側の設定

const agent = new Agent({
    name: "multi-mcp-agent",
    model: "gpt-4o-mini",
    instructions: `
あなたはMCPツールを使ってユーザーの依頼を解決します。
- Web/ニュース/画像の検索: 「brave」を使う。
- 実ブラウザ操作(遷移/クリック/入力/待機など): 「playwright」を使う。
- 出典URLや実行手順を簡潔に示し、日本語で答える。`,
    mcpServers: [brave, playwright],
  });

まずnameは、任意で自分でつける名前です。
modelは今は安いやつを使っていますが、任意で変更ができます。
instructionsは、AIの役割を指示しています。実際の処理したいクエリはコマンド実行時に与えています。
mcpServersに上で設定したサービス名(braveやplaywright)を列挙します。
これだけでよしなにAIが使い分けをしてくれます。

最後に

よくよく考えたら、AIツールを開発している人にしか需要がないかもしれません(汗)
けど、これで僕が作っているハロが世界のリソースに手を延ばせるぞ……ふふふ……。

Discussion