0
0

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ツールを同時に利用可能なChatbotを最小構成で作ってみる(Google Gemini版)

Last updated at Posted at 2025-06-18

はじめに

前編「MCPサーバーの最小構成を作ってみる(Node.js版) 」では、Model Context Protocol(MCP)プロトコルの仕様を軽く解説し、OpenAIやClaudeなどのAPIを持たなくてもMCPツールの開発及び検証の方法を紹介しました。

本編では、実際にAIサービス(Google Gemini)のAPIを使って、本物のAI Agentを開発してみます。

シリーズ記事

記事 内容
1 MCPサーバーの最小構成を作ってみる(Node.js版) AIサービスのアカウントを持たなくてもMCPツールの開発ができます
2 簡単なMCP利用可能なChatbotを作ってみる(Google Gemini版) 本編
3 MCPサーバーの最小構成を作ってみる(Python版) Coming Soon
4 簡単なMCP利用可能なChatbotを作ってみる(Azure OpenAI版) Coming Soon
5 RAGをMCPサーバーとして利用し、簡単な映画推薦Chatbotを作ってみる(Azure OpenAI版) Coming Soon
6 MCPを活用してAI Agentで定期タスクを実行できるように 自分自身に指向するMCPサーバーを使って、定期タスクを実装する方法

実装

実行環境

Google Gemini APIキーの申請

下記のページにアクセスし、 「Google AI Studio で無料で取得」 をクリックして、案内に従えば無料に取得できます。

image.png

image.png

Google GeminiのAPIキーを取得したら、 環境変数 GEMINI_API_KEY をセットアップします。

パッケージのインストール

npm i @google/genai @modelcontextprotocol/sdk dotenv

また、試したいMCPツールがあれば、事前にインストールすると、後ほどスムーズに実行できるので、 事前インストールをおすすめします。

Geminiチャットボットの実装

まずはMCPツールを持たない単純なAIチャットボットを作ります。使ったのはGemini SDKのマルチターンの会話(チャット)APIです。

gemini_demo.js
import { GoogleGenAI } from '@google/genai';
import { createInterface } from "readline/promises";
import dotenv from "dotenv";
dotenv.config(); // .envファイルを読み込む

// クライアントを設定
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const chat = ai.chats.create({
  model: "gemini-2.0-flash",
  config: {
    systemInstruction: "あなたはMCPを使って、いろんな操作を行うことができます。",
  },
});

// ユーザー入力用のreadlineインターフェースを作成
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});

// readlineインターフェースのプロンプトを設定
rl.setPrompt(`Waiting for chat input... \n> `);
rl.prompt();

rl.on("line", async (line) => {
  const trimmedLine = line.trim();

  // 入力が空の場合は再度プロンプトを表示
  if (!trimmedLine) {
    rl.prompt();
    return;
  }

  try {
    const response = await chat.sendMessage({
      role: "user",
      message: { type: "text", text: trimmedLine },
    });

    console.log("Gemini: ", response.text);
  } catch (error) {
    console.error("Error: ", error);
  } finally {
    rl.prompt();
  }
});

Node.jsのReadlineを使って、非同期的にコマンドラインの入力を取得し、GeminiのチャットAPIで送信しています。

実行結果:

$ node gemini_demo.mjs 
Waiting for chat input...
> こんにちは
Gemini:  こんにちは!何かお手伝いできることはありますか?

Waiting for chat input...
>

MCPツールの活用

今回の記事は前回で作られた「Streamable HTTPを使ったMCPサーバー」 add_http.mjs、及び公式のFilesystem MCP Serverを使って Streamable HTTPSTDIO 二種類のClientをDemoします。

[注意]: Google Geminiは現在(2025-06-18)MCPサポートが試験運用であるため、ツールのみがサポートされ、リソースやプロンプトはサポートされないとのことです。

image.png

MCP Clientの初期化

尺を考慮して、ここは追加分のコードのみ展示します。フルバージョンのソースコードをみたい方は文末の Full Souce Code を参照してください。

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

// MCPサーバーの設定
const stdioTransport = new StdioClientTransport({
  command: "npx",
  args: ['-y', '@modelcontextprotocol/server-filesystem', './'],
});

const client1 = new Client(
  {
    name: "server-filesystem",
    version: "1.0.0"
  }
);

await client1.connect(stdioTransport, { timeout: 30000 });

// HTTP Transportの設定
const httpTransport = new StreamableHTTPClientTransport(
  new URL("http://localhost:3000/mcp"),
  {
    sessionId: undefined,
    requestInit: { headers: { } },
  },
);

const client2 = new Client(
  {
    name: "demo-http-client",
    version: "1.0.0"
  }
);

await client2.connect(httpTransport);

Geminiにツールを提供する

ここも変更点だけ表示します。。フルバージョンのソースコードをみたい方は文末の Full Souce Code を参照してください。

- import { GoogleGenAI } from '@google/genai';
+ import { GoogleGenAI, mcpToTool } from '@google/genai';

...

// クライアントを設定
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const chat = ai.chats.create({
  model: "gemini-2.0-flash",
  config: {
    systemInstruction: "あなたはMCPを使って、いろんな操作を行うことができます。",
+    tools: [ mcpToTool(client1), mcpToTool(client2) ],
  },
});

...

見た通り、Gemini SDKは mcpToTool()という便利メソッドを提供していて、標準のMCP SDKのClientをGeminiが利用できるツール形式に変換してくれます。変換したツールは、Geminiのサービスを初期化する際に、toolsフィールドに提供すれば利用できます。

実行結果:

まずは別のターミナルで node add_http.mjs で自前のMCPサーバーを立ち上げます。

$ node gemini_demo.mjs 
Secure MCP Filesystem Server running on stdio
Allowed directories: [
  'PATH/TO/YOUR/DIR'
]
Waiting for chat input...
> こんにちは、現在使えるMCPツールの一覧を出してください。
Gemini:  現在使えるMCPツールは以下の通りです。

- read_file
- read_multiple_files
- write_file
- edit_file
- create_directory
- list_directory
- directory_tree
- move_file
- search_files
- get_file_info
- list_allowed_directories
- add_test

また、アクセス可能なディレクトリは `PATH/TO/YOUR/DIR` です。
Waiting for chat input...
> MCPツールadd_testは何ができます?
Gemini:  MCPツール`add_test`は、与えられた2つの数値(aとb)を足し算し、さらにその結果に10を足した値を返します。

Waiting for chat input...
> このツールで12+20を計算して
Gemini:  12 + 20 の計算結果は 42 です。
Waiting for chat input...
> 上記結果を./result.csvに保存して
Gemini:  結果を ./result.csv に保存しました。
Waiting for chat input...
> ./result.csvの内容を読み取って
Gemini:  ./result.csv の内容は "42" です。
Waiting for chat input...
>

Full Souce Code

gemini_demo.mjs
gemini_demo.mjs
import { GoogleGenAI, mcpToTool } from '@google/genai';
import { createInterface } from "readline/promises";
import dotenv from "dotenv";
dotenv.config(); // .envファイルを読み込む

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

// MCPサーバーの設定
const stdioTransport = new StdioClientTransport({
  command: "npx",
  args: ['-y', '@modelcontextprotocol/server-filesystem', './'],
});

const client1 = new Client(
  {
    name: "server-filesystem",
    version: "1.0.0"
  }
);

await client1.connect(stdioTransport, { timeout: 30000 });

// HTTP Transportの設定
const httpTransport = new StreamableHTTPClientTransport(
  new URL("http://localhost:3000/mcp"),
  {
    sessionId: undefined,
    requestInit: { headers: {} },
  },
);

const client2 = new Client(
  {
    name: "demo-http-client",
    version: "1.0.0"
  }
);

await client2.connect(httpTransport);


// クライアントを設定
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const chat = ai.chats.create({
  model: "gemini-2.0-flash",
  config: {
    systemInstruction: "あなたはMCPを使って、いろんな操作を行うことができます。",
    tools: [ mcpToTool(client1), mcpToTool(client2) ],
  },
});

// ユーザー入力用のreadlineインターフェースを作成
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});
// readlineインターフェースのプロンプトを設定
rl.setPrompt(`Waiting for chat input... \n> `);
rl.prompt();

rl.on("line", async (line) => {
  const trimmedLine = line.trim();

  // 入力が空の場合は再度プロンプトを表示
  if (!trimmedLine) {
    rl.prompt();
    return;
  }

  // "exit"と入力された場合は終了
  if (trimmedLine.toLowerCase() === 'exit') {
    console.log("Exiting...");
    // readlineインターフェースを閉じる
    rl.close();
    // クライアントを閉じる
    console.log("Closing clients...");
    await Promise.all([
      client1.close(),
      client2.close(),
    ]).catch(console.error);
    process.exit(0);
  }

  try {
    const response = await chat.sendMessage({
      role: "user",
      message: { type: "text", text: trimmedLine },
    });

    console.log("Gemini: ", response.text);
  } catch (error) {
    console.error("Error: ", error);
  } finally {
    rl.prompt();
  }
});

余談: Geminiの読み方

天文学や西洋占星術に詳しい方だと、 Gemini は「ふたご座」を意味すると気付くでしょう。星座を表す時、Geminiの発音は「ジェミナイ」(英語発音: [ˈdʒɛmɨnaɪ])ですが、 Google Gemini語源は星座ではなく、アメリカが1960年代実行した有人宇宙計画「ジェミニ計画」ですので、故に読み方は「ジェミニ」と確定です。

まぁ、本家のビデオや宣伝資料もご丁寧に「Gemini(ジェミニ)」と書いていますね。

image.png

参考

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?