💬

MCPクライアントの実装を段階的に学んでみた(TypeScript SDK、Anthropic API)

に公開

はじめに

MCP サーバーの実装は少しやってみたんですが、MCP クライアントについてはやっていなかったので、公式チュートリアルのサンプルについて勉強してみました。

https://modelcontextprotocol.io/quickstart/client#node

ただ、チュートリアルのサンプルは複数の構成要素(MCP クライアント、MCP サーバー、Anthropic API、CLI チャット機能)を組み合わせたアプリになっているため、いきなりこれをそのまま理解するのは少し大変でした。そのため以下のように段階的に理解を進めるようにしました。

  1. MCP クライアント から MCP サーバー を呼び出すだけのシンプルなものを作成
  2. Anthropic API で AI モデル を使うだけのものを作成
  3. Anthropic API を利用した簡単な CLI チャットボットを作成
  4. MCP クライアント、MCP サーバー、Anthropic API を連携させたものを作成
  5. MCP クライアント、MCP サーバー、Anthropic API、CLI チャット機能、を組み合わせて簡単なチャットボットアプリを作成

最終形態の構成は大まかに以下のような感じです。

https://github.com/t-shiratori/mcp-client-example

1. MCP クライアントと MCP サーバーを連携する

シンプルに MCP クライアントと MCP サーバーを連携させて、MCP サーバーのツールを呼び出すだけのものを作成します。
MCP サーバーは以下で作成したものを利用しています。
https://zenn.dev/s_takashi/articles/time-tracker-mcp-server-in-vscode

処理の流れ

  • new StdioClientTransport()で MCP サーバー連携用のトランスポートを作成
  • new Client()で MCP クライアントを作成
  • client.connect(transport)で MCP サーバーに接続
  • client.listTools()で MCP サーバーのツール一覧を取得
  • client.callTool()で MCP サーバーのツールを実行

MCP サーバーのスクリプトパスは env ファイルから読み込むようにしています。

.env
MCP_SERVER_SCRIPT_PATH=/path/to/time-tools-mcp/build/index.js
src/index.ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import dotenv from "dotenv";

/** .envファイルから環境変数を読み込む */
dotenv.config();

const MCP_SERVER_SCRIPT_PATH = process.env.MCP_SERVER_SCRIPT_PATH;

async function main() {
    if (!MCP_SERVER_SCRIPT_PATH) {
        throw new Error("MCP_SERVER_SCRIPT_PATH is not set");
    }

    try {
        /** サーバーへ接続するためのトランスポートを作成 */
        const transport = new StdioClientTransport({
            command: "node",
            args: [MCP_SERVER_SCRIPT_PATH],
        });

        /** クライアントを作成 */
        const client = new Client({
            name: "example-client",
            version: "1.0.0",
        });

        /** クライアントをサーバーに接続 */
        await client.connect(transport);

        /**
         * MCPサーバーのツール一覧を取得
         */
        const toolsResult = await client.listTools();
        const tools = toolsResult.tools.map((tool) => {
            return {
                name: tool.name,
                description: tool.description,
                input_schema: tool.inputSchema,
            };
        });

        console.log(
            "Connected to server with tools:",
            tools.map(({ name }) => name),
        );

        /** MCPツールを呼び出す */
        const currentTime = await client.callTool({
            name: tools[0].name,
        });
        console.log("Current date and time:", currentTime);
    } finally {
        process.exit(0);
    }
}

main();

実行結果

これを実行すると MCP サーバーのツール一覧と、get_current_date_time ツールを実行した結果が表示されています。

mcp-client-example $ pnpm start

> mcp-client-example@1.0.0 start /path/to/mcp-client-example
> node build/index.js

Example MCP Server running on stdio
Connected to server with tools: [ 'get_current_date_time', 'get_elapsed_time' ]
Current date and time: { content: [ { type: 'text', text: '2025-05-05 21:54:07' } ] }

2. Anthropic API を使用する

シンプルに Anthropic API を実行するだけのものを作成します。

API ドキュメントはこちらです。

https://docs.anthropic.com/ja/docs/initial-setup

https://docs.anthropic.com/ja/api/messages

API を実行するためには、API キーが必要になるので取得しておきます。
env ファイルに API キーを書いておきます。

.env
ANTHROPIC_API_KEY=your-api-key

new Anthropic()で Anthropic API を実行するクライアントを作成し、anthropic.messages.create()で API を実行します。

src/index.ts
import Anthropic from '@anthropic-ai/sdk';
import dotenv from 'dotenv';

/** .envファイルから環境変数を読み込む */
dotenv.config();

const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
if (!ANTHROPIC_API_KEY) {
  throw new Error('ANTHROPIC_API_KEY is not set');
}

async function main() {
  const anthropic = new Anthropic({
    apiKey: ANTHROPIC_API_KEY,
  });

  const response = await anthropic.messages.create({
    model: 'claude-3-7-sonnet-20250219',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Hello, world' }],
  });

  console.log(response);
  return response;
}

main();

実行結果

実行すると、Anthropic API に送信したメッセージに対して AI モデルが生成した会話内容が返ってきていることが確認できます。


mcp-client-example $ pnpm start

> mcp-client-example@1.0.0 start /path/to/mcp-client-example
> node build/index.js /path/to/time-tools-mcp/build/index.js

{
  id: 'msg_01Bz1ibWAWKfiycL8D9dA26u',
  type: 'message',
  role: 'assistant',
  model: 'claude-3-7-sonnet-20250219',
  content: [
    {
      type: 'text',
      text: "Hello! It's nice to meet you. How can I help you today? I'm ready to assist with information, answer questions, or discuss topics you're interested in."
    }
  ],
  stop_reason: 'end_turn',
  stop_sequence: null,
  usage: {
    input_tokens: 10,
    cache_creation_input_tokens: 0,
    cache_read_input_tokens: 0,
    output_tokens: 38
  }
}

3. Anthropic API を使って CLI 形式の チャットボットを作成する

Node.js のreadlineを使うことで対話形式の CLI を作ることができます。readline.createInterface() を使って、readlinePromises.Interfaceのインスタンスを作成します。rl.question("\n🖌 Query: ") でユーザー入力の受け付けを開始します。ループ処理でquitが入力されるまで、ユーザー入力受付を継続するようにしています。

.env
ANTHROPIC_API_KEY=your-api-key
src/index.ts
import Anthropic from "@anthropic-ai/sdk";
import dotenv from "dotenv";
import * as readline from "node:readline/promises";

/** .envファイルから環境変数を読み込む */
dotenv.config();

const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
if (!ANTHROPIC_API_KEY) {
    throw new Error("ANTHROPIC_API_KEY is not set");
}

async function main() {
    /** Anthropic SDKのインスタンスを作成 */
    const anthropic = new Anthropic({
        apiKey: ANTHROPIC_API_KEY,
    });

    /** Anthropic APIを使ってメッセージを送信する関数 */
    const postAnthropicApi = async (query: string) => {
        return await anthropic.messages.create({
            model: "claude-3-7-sonnet-20250219",
            max_tokens: 1024,
            messages: [{ role: "user", content: query }],
        });
    };

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

    try {
        while (true) {
            /** ユーザーからの入力を待つ */
            const inputMessage = await rl.question("\n🖌 Query: ");

            /** 'quit'と入力されたらループを終了 */
            if (inputMessage.toLowerCase() === "quit") {
                break;
            }

            /** Anthropic APIにメッセージを送信し、応答を取得 */
            const response = await postAnthropicApi(inputMessage);

            /** メッセージのタイプが'text'の場合、それを表示 */
            const message = response.content[0];
            if (message.type === "text") {
                console.log(`\n${message.text}`);
            }
        }
    } catch (error) {
        console.error("Error in chat loop: ", error);
    } finally {
        rl.close();
    }
}

main();

実行結果

コードを実行すると、🖌 Query:が表示されて、ユーザーからの入力を待ち受けます。

mcp-client-example $ pnpm start

> mcp-client-example@1.0.0 start /path/to/mcp-client-example
> node build/index.js


🖌 Query:

入力を受け取ったら Anthropic API を実行して AI が生成した会話内容を表示しています。
quit と入力するとことで、ループを抜けてプログラムが終了できています。

🖌 Query: こんにちわ

こんにちは!何かお手伝いできることはありますか?

🖌 Query: 得意なことは?

得意なことは、情報提供、文章作成、質問への回答、対話など様々なタスクをこなすことです。特に言語処理や情報整理が得意で、複雑な質問にも分かりやすく回答するよう心がけています。また、幅広い分野の知識をもとに、ユーザーの皆さんのお手伝いをすることも得意としています。何かお手伝いできることがあれば、お気軽にお尋ねください。

🖌 Query: quit
mcp-client-example $

4. MCP クライアント、MCP サーバー、Anthropic API を連携する

.env
ANTHROPIC_API_KEY=your-api-key
MCP_SERVER_SCRIPT_PATH=/path/to/time-tools-mcp/build/index.js

MCP クライアントと MCP サーバーを連携しておいて、 MCP サーバーから tools を取得しておきます。そして、anthropic.messages.create()で Anthropic API を実行する際のパラメーターに MCP サーバーのtoolsを追加しています。

src/index.ts
import Anthropic from "@anthropic-ai/sdk";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import dotenv from "dotenv";
import type { MessageParam } from "@anthropic-ai/sdk/resources.mjs";

/** .envファイルから環境変数を読み込む */
dotenv.config();

const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
const MCP_SERVER_SCRIPT_PATH = process.env.MCP_SERVER_SCRIPT_PATH;

if (!ANTHROPIC_API_KEY) {
    throw new Error("ANTHROPIC_API_KEY is not set");
}

if (!MCP_SERVER_SCRIPT_PATH) {
    throw new Error("MCP_SERVER_SCRIPT_PATH is not set");
}

async function main() {
    const anthropic = new Anthropic({
        apiKey: ANTHROPIC_API_KEY,
    });

    try {
        /** 新しいMCPクライアントを作成 */
        const mpcClient = new Client({
            name: "example-client",
            version: "1.0.0",
        });

        const transport = new StdioClientTransport({
            command: "node",
            args: MCP_SERVER_SCRIPT_PATH ? [MCP_SERVER_SCRIPT_PATH] : undefined,
        });

        /** MCPサーバーに接続 */
        mpcClient.connect(transport);

        /** MCPサーバーのツール一覧を取得 */
        const toolsResult = await mpcClient.listTools();
        const tools = toolsResult.tools.map((tool) => {
            return {
                name: tool.name,
                description: tool.description,
                input_schema: tool.inputSchema,
            };
        });
        console.log(
            "Connected to server with tools:",
            tools.map(({ name }) => name),
        );

        /** AIモデルへの入力メッセージ */
        const messages: MessageParam[] = [
            {
                role: "user",
                content: "現在時間を教えてください",
            },
        ];

        /**
         * 質問メッセージとMCPツールをAPIへ送信。
         * AIモデルが次の会話メッセージを生成して返す。
         */
        const response = await anthropic.messages.create({
            model: "claude-3-5-sonnet-20241022",
            max_tokens: 1000,
            messages,
            tools,
        });

        console.log("tools messages response: ", response);
    } catch (e) {
        console.log("Failed to connect to MCP server: ", e);
        throw e;
    }
}

main();

実行結果

mcp-client-example $ pnpm start

> mcp-client-example@1.0.0 start /path/to/mcp-client-example
> node build/index.js

Example MCP Server running on stdio
Connected to server with tools: [ 'get_current_date_time', 'get_elapsed_time' ]
tools messages response:  {
  id: 'msg_01M2WdH23w8pfcsuqRgQ9YNP',
  type: 'message',
  role: 'assistant',
  model: 'claude-3-5-sonnet-20241022',
  content: [
    { type: 'text', text: '現在の日時を取得いたします。' },
    {
      type: 'tool_use',
      id: 'toolu_011ZcE7vEJWxZ7gejcJKv7Fk',
      name: 'get_current_date_time',
      input: {}
    }
  ],
  stop_reason: 'tool_use',
  stop_sequence: null,
  usage: {
    input_tokens: 547,
    cache_creation_input_tokens: 0,
    cache_read_input_tokens: 0,
    output_tokens: 54
  }
}

前のステップではテキストだけのメッセージだけでしたが、今回はcontentにツール用のタイプ(type: 'tool_use')が追加されていることが確認できます。

content: [
{ type: 'text', text: '現在の日時を取得いたします。' },
{
    type: 'tool_use',
    id: 'toolu_011ZcE7vEJWxZ7gejcJKv7Fk',
    name: 'get_current_date_time',
    input: {}
}
],
stop_reason: 'tool_use',

5. すべて組み合わせて CLI 形式のチャットボットアプリを作る

MCP クライアント、MCP サーバー、Anthropic API、CLI の対話機能、を組み合わせて簡単なチャットボットアプリを作成します。

コードが長くなったので MCPClient クラスに処理をまとめています。

src/index.ts
import { MCPClient } from "./MCPClient.js"

async function main() {
    const mcpClient = new MCPClient();
    try {
        await mcpClient.connectToServer();
        await mcpClient.chatLoop();
    } finally {
        await mcpClient.cleanup();
        process.exit(0);
    }
}

main();
.env
ANTHROPIC_API_KEY=your-api-key
MCP_SERVER_SCRIPT_PATH=/path/to/time-tools-mcp/build/index.js
src/const.ts
import dotenv from "dotenv";

/** .envファイルから環境変数を読み込む */
dotenv.config();

export const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
export const MCP_SERVER_SCRIPT_PATH = process.env.MCP_SERVER_SCRIPT_PATH;
export const AI_MODEL = "claude-3-7-sonnet-20250219";

src/McpClient.ts の全体のコードです。少し長いので折りたたんでます。

src/McpClient.ts
src/McpClient.ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import type {
    MessageParam,
    Tool,
} from "@anthropic-ai/sdk/resources/messages/messages.mjs";
import { Anthropic } from "@anthropic-ai/sdk";
import * as readline from "node:readline/promises";
import {
    AI_MODEL,
    ANTHROPIC_API_KEY,
    MCP_SERVER_SCRIPT_PATH,
} from "./const.js";

export class MCPClient {
    private readonly mpcClient: Client;
    private readonly anthropic: Anthropic;
    private transport: StdioClientTransport | null = null;
    private tools: Tool[] = [];

    constructor() {
        if (!ANTHROPIC_API_KEY) {
            throw new Error("ANTHROPIC_API_KEY is not set");
        }
        this.anthropic = new Anthropic({
            apiKey: ANTHROPIC_API_KEY,
        });
        this.mpcClient = new Client({
            name: "example-mcp-client",
            version: "1.0.0",
        });
    }

    /** MCPサーバーを実行するコマンドを作成 */
    createCommand(serverScriptPath: string) {
        const isJs = serverScriptPath.endsWith(".js");
        const isPy = serverScriptPath.endsWith(".py");
        if (!isJs && !isPy) {
            throw new Error("Server script must be a .js or .py file");
        }
        const command = isPy
            ? process.platform === "win32"
                ? "python"
                : "python3"
            : process.execPath;

        return command;
    }

    /** MCPサーバーに接続 */
    async connectToServer() {
        try {
            if (!MCP_SERVER_SCRIPT_PATH) {
                throw new Error("MCP_SERVER_SCRIPT_PATH is not set");
            }

            /** MCPサーバーと通信するためのトランスポートを作成 */
            this.transport = new StdioClientTransport({
                command: this.createCommand(MCP_SERVER_SCRIPT_PATH),
                args: [MCP_SERVER_SCRIPT_PATH],
            });

            /** MCPサーバーに接続 */
            this.mpcClient.connect(this.transport);

            /** MCPサーバーのツール一覧を取得 */
            const toolsResult = await this.mpcClient.listTools();
            this.tools = toolsResult.tools.map((tool) => {
                return {
                    name: tool.name,
                    description: tool.description,
                    input_schema: tool.inputSchema,
                };
            });
            console.log(
                "Connected to server with tools:",
                this.tools.map(({ name }) => name),
            );
        } catch (e) {
            console.log("Failed to connect to MCP server: ", e);
            throw e;
        }
    }

    /** MCPサーバーへの接続を終了 */
    async cleanup() {
        await this.mpcClient.close();
    }

    /**
     * CLIでインタラクティブなユーザーインターフェースを作成
     */
    async chatLoop() {
        /** ユーザー入力用のreadlineインターフェースを作成 */
        const rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
        });

        try {
            console.log("\nMCP Client Started!");
            console.log("Type your queries or 'quit' to exit.");

            while (true) {
                /** ユーザーからの入力を受け付ける */
                const inputMessage = await rl.question("\n🖌 Query: ");
                if (inputMessage.toLowerCase() === "quit") {
                    break;
                }
                /** AIモデルとの会話を開始 */
                const response = await this.processQuery(inputMessage);
                /** AIモデルの応答を表示 */
                console.log(`\n${response}`);
            }
        } catch (error) {
            console.error("Error in chat loop: ", error);
        } finally {
            rl.close();
        }
    }

    /**
     * 各質問に対する会話を管理
     */
    async processQuery(query: string) {
        /** 入力メッセージを収集するための配列 */
        const queryMessages: MessageParam[] = [
            {
                role: "user",
                content: query,
            },
        ];

        /**
         * 質問メッセージとMCPツールをAPIへ送信。
         * AIモデルが次の会話メッセージを生成して返す。
         */
        const response = await this.anthropic.messages.create({
            model: AI_MODEL,
            max_tokens: 1000,
            messages: queryMessages,
            tools: this.tools,
        });

        /** 最終的な出力メッセージを収集 */
        const finalText = [];

        /**
         * レスポンスの"content"プロパティを解析
         */
        for (const content of response.content) {
            if (content.type === "text") {
                finalText.push(content.text);
            } else if (content.type === "tool_use") {
                const toolName = content.name;
                const toolArgs = content.input as
                    | { [x: string]: unknown }
                    | undefined;

                /** MCPサーバーのツールを呼び出す */
                const result = await this.mpcClient.callTool({
                    name: toolName,
                    arguments: toolArgs,
                });

                finalText.push(
                    `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`,
                );

                /** 質問メッセージを更新 */
                queryMessages.push({
                    role: "user",
                    content: result.content as string,
                });

                /** 再度APIにリクエストを送信 */
                const response = await this.anthropic.messages.create({
                    model: "claude-3-5-sonnet-20241022",
                    max_tokens: 1000,
                    messages: queryMessages,
                });

                /** 最終的な出力結果に最新の会話メッセージのみを追加 */
                finalText.push(
                    response.content[0].type === "text"
                        ? response.content[0].text
                        : "",
                );
            }
        }

        return finalText.join("\n");
    }
}

これまでのステップに新たに追加される主な機能は、AI モデルとのやりとりの中に MCP サーバーのツール実行を組み込む部分です。

まずユーザー入力の機能について。
ここは前のステップ 3 のコードとほぼ同じです。入力を受け取ったらthis.processQuery()を呼び出して、AI モデルとの会話を開始します。

src/McpClient.ts
/**
 * CLIでインタラクティブなユーザーインターフェースを作成
 */
async chatLoop() {
    /** ユーザー入力用のreadlineインターフェースを作成 */
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
    });

    try {
        console.log("\nMCP Client Started!");
        console.log("Type your queries or 'quit' to exit.");

        while (true) {
            /** ユーザーからの入力を受け付ける */
            const inputMessage = await rl.question("\n🖌 Query: ");
            if (inputMessage.toLowerCase() === "quit") {
                break;
            }
            /** AIモデルとの会話を開始 */
            const response = await this.processQuery(inputMessage);
            /** AIモデルの応答を表示 */
            console.log(`\n${response}`);
        }
    } catch (error) {
        console.error("Error in chat loop: ", error);
    } finally {
        rl.close();
    }
}

次に AI モデルとの会話部分です。

src/McpClient.ts
async processQuery(query: string) {
    /** 入力メッセージを収集するための配列 */
    const queryMessages: MessageParam[] = [
        {
            role: "user",
            content: query,
        },
    ];

    /**
     * 質問メッセージとMCPツールをAPIへ送信。
     * AIモデルが次の会話メッセージを生成して返す。
     */
    const response = await this.anthropic.messages.create({
        model: AI_MODEL,
        max_tokens: 1000,
        messages: queryMessages,
        tools: this.tools,
    });

    /** 最終的な出力メッセージを収集 */
    const finalText = [];

    /**
     * レスポンスの"content"プロパティを解析
     */
    for (const content of response.content) {
        if (content.type === "text") {
            finalText.push(content.text);
        } else if (content.type === "tool_use") {
            const toolName = content.name;
            const toolArgs = content.input as
                | { [x: string]: unknown }
                | undefined;

            /** MCPサーバーのツールを呼び出す */
            const result = await this.mpcClient.callTool({
                name: toolName,
                arguments: toolArgs,
            });

            finalText.push(
                `[Calling tool ${toolName} with args ${JSON.stringify(toolArgs)}]`,
            );

            /** 質問メッセージを更新 */
            queryMessages.push({
                role: "user",
                content: result.content as string,
            });

            /** 再度APIにリクエストを送信 */
            const response = await this.anthropic.messages.create({
                model: "claude-3-5-sonnet-20241022",
                max_tokens: 1000,
                messages: queryMessages,
            });

            /** 最終的な出力結果に最新の会話メッセージのみを追加 */
            finalText.push(
                response.content[0].type === "text"
                    ? response.content[0].text
                    : "",
            );
        }
    }


    return finalText.join("\n");
}

ユーザーからのクエリ入力を受け取るたびに AI モデルとの会話処理を開始します。
最初にthis.anthropic.messages.create()で Anthropic API を実行し、AI モデルに次の会話メッセージを生成させます。最初のクエリに対して、AI モデルが MCP サーバーのツールを利用するか判断してメッセージを返します。レスポンスにはcontentが含まれています。

ツールを利用しない場合、contentにあるメッセージタイプはtype: 'text'のみです。

content: [
    {
      type: 'text',
      text: 'こんにちは!お手伝いできることがありましたら、お知らせください。日本語でのご質問やご依頼に対応いたします。\n' +
        '\n' +
        '現在の日時を確認したり、二つの日時の間の経過時間を計算したりするツールがありますが、お使いになりたいでしょうか?'
    }
  ],
stop_reason: 'end_turn',

ツールを利用する場合、contentに含まれるメッセージタイプにtype: 'tool_use'が入っています。

content: [
    { type: 'text', text: '現在の日付と時刻をお知らせします。' },
    {
        type: 'tool_use',
        id: 'toolu_01Wvzv6U5VrzJXjZfVhU2pmT',
        name: 'get_current_date_time',
        input: {}
    }
],
stop_reason: 'tool_use',

レスポンスのcontentに入っているメッセージのうち、type: 'text'のメッセージはそのままtextの値を finalText に追加します。type: 'tool_use'のメッセージの場合は、nameプロパティのツールを MCP クライアントから MCP サーバーにコールして実行します。ツールの実行結果を queryMessages に追加し、再度 API にリクエストを送ります。ツールの実行結果を踏まえて AI モデルから次の会話が生成されて返ってくるので、finalTextにそのメッセージを追加します。最終的に表示する出力テキストとして finalText.join("\n")を返します。

実行結果

実行するとクエリ入力のプロンプト🖌 Query:が表示されます。

mcp-client-example $ pnpm start

> mcp-client-example@1.0.0 start /path/to/mcp-client-example
> node build/index.js

Example MCP Server running on stdio
Connected to server with tools: [ 'get_current_date_time', 'get_elapsed_time' ]

MCP Client Started!
Type your queries or 'quit' to exit.

🖌 Query:

クエリを入力すると、AI の応答が表示されます。

🖌 Query: こんにちわ

こんにちは!お手伝いできることがありましたら、お気軽にお知らせください。現在の日時を確認したり、2つの日時の間の経過時間を計算したりするツールを使用できます。何かお手伝いできることはありますか?

🖌 Query: 現在時間は?

現在の日時をお調べします。
[Calling tool get_current_date_time with args {}]
2025年5月6日の11時5分36秒ですね。

🖌 Query: `2025-05-06 10:00:00` と `2025-05-06 11:00:00` の時間差を教えて

この2つの時間の差を計算します。`2025-05-06 10:00:00`から`2025-05-06 11:00:00`までの時間差を調べます。
[Calling tool get_elapsed_time with args {"from":"2025-05-06 10:00:00","to":"2025-05-06 11:00:00","unit":"second"}]
正解です!

`2025-05-06 11:00:00` と `2025-05-06 10:00:00` の差は1時間で、
1時間 = 60分 = 3600秒 なので、3600秒となります。

計算方法:
* 1時間の差
* 1時間 = 60分
* 60分 × 60秒 = 3600秒

MCP サーバーのツールを使って回答していることが確認できました。

おわりに

想定より記事が長くなってしまい大変でしたが、段階的に学ぶことで理解しやすかったかなと思います。MCP クライアントの実装を学ぶことで AI エージェントについての解像度も少し上がったような気がしました。LLM の API に MCP を組み合わせることでオリジナルの AI ツールが作れるのは楽しいですね。

Discussion