【Mastra入門】Claudeとペアプロしてみた その１（Tools編）

## はじめに

こんにちは！いのせです。

最近、AIの進化が止まらない中、ふと思いついたことがありました。

「**生成AI**に学習教材を作ってもらってそれを元に勉強をすれば良いのでは...?」

早速、Claude先生に「MastraのToolが学べる資料を作成して！」と投げてみたところ、驚くほど分かりやすいハンズオン形式の資料を生成してくれました。

今回は、まるで**Claudeとペアプロ**をしているような感覚で、実際にMastraのTool機能をハンズオン形式で学び、簡単な計算ツールを開発した内容を執筆していこうと思います。

:::note warn
出力してくれる内容全てがあっているとは限らない（というより大体ミスがある）ので、あくまでも雛形程度に使用するのをお勧めします。
:::

## MastraのToolsとは？

Mastraにおける「Tools」は、エージェントやワークフローから呼び出せる型付き関数として定義されたコンポーネントです。
AIエージェントがLLMの応答を通じてこれらのツールを関数コールの形式で実行することで、外部システムとの連携、計算処理、データアクセスなど、さまざまなタスクを実現できます。

詳しくは[公式ドキュメントへ](https://mastra.ai/ja/docs/tools-mcp/overview)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737055/a10f0cc2-e287-4b85-83a6-bee7397f4310.png)

※GettingStartedとAgentsについてはこちらに。

https://qiita.com/i-inose/items/34ffa9872cde26ab7787

https://qiita.com/i-inose/items/d790eb1ddaf85a1ac208

## ディレクトリ構成と環境



```bash
.
├── .mastra/
├── node_modules/
├── src/
│   ├── mastra/
│   │   ├── agents/
│   │   │   └── math-agent.ts
│   │   └── tools/
│   │       └── calculator.ts
│   └── test-calculator.ts
├── index.ts
└── .env
```

```.env
OPENAI_API_KEY=your_openai_key
```

```
# セットアップ時の選択

✔ Where should we create the Mastra files? › src/
✔ Choose components to install › Agents
✔ Add tools? › Yes
✔ Select default provider › OpenAI
✔ Enter API key › sk-... (またはEnterでスキップ)
```

## ハンズオン実践編

今回はToolsの実装方法について学ぶことをメインにしたので内容はかなり簡単になっています。
（Claude先生が優しくしてくれたのかも？）

### シンプルな計算Tools

```src/tools/calculator.ts
import { createTool } from "@mastra/core";
import { z } from "zod";

export const calculatorTool = createTool({
  id: "calculator",
  description: "簡単な計算を実行するツール",
  inputSchema: z.object({
    a: z.number().describe("1つ目の数値"),
    b: z.number().describe("2つ目の数値"),
    operation: z.enum(["add", "subtract", "multiply", "divide"])
      .describe("実行する演算")
  }),
  outputSchema: z.object({
    result: z.number(),
    explanation: z.string()
  }),
  execute: async (params) => {
    const { a, b, operation } = params;
    let result: number;
    let explanation: string;
    
    switch (operation) {
      case "add":
        result = a + b;
        explanation = `${a} + ${b} = ${result}`;
        break;
      case "subtract":
        result = a - b;
        explanation = `${a} - ${b} = ${result}`;
        break;
      case "multiply":
        result = a * b;
        explanation = `${a} × ${b} = ${result}`;
        break;
      case "divide":
        if (b === 0) {
          throw new Error("ゼロで除算することはできません");
        }
        result = a / b;
        explanation = `${a} ÷ ${b} = ${result}`;
        break;
    }
    
    return { result, explanation };
  }
});
```

### AgentsにToolsを追加

```src/agents/math-agent.ts
import { openai } from '@ai-sdk/openai';
import { Agent } from '@mastra/core/agent';
import { calculatorTool } from '../tools/calculator';

export const mathAgent = new Agent({
  name: 'Math Agent',
  instructions: `あなたは数学の問題を解決する親切なアシスタントです。
    ユーザーから計算の質問を受けたら、calculatorツールを使って正確な答えを提供してください。
    計算過程も分かりやすく説明してください。`,
  model: openai("gpt-4.1-nano"),
  tools: { calculatorTool },
});
```

:::note info
modelをgpt-4.1-nanoにしているのは、単純に節約です。
（未だに使用した合計が0ドル換算になっているからかなり安いのかも？）
:::

### mastraインスタンスに登録

```src/mastra.ts
import { Mastra } from "@mastra/core";
import { mathAgent } from "./agents/math-agent";

export const mastra = new Mastra({
  agents: { mathAgent }
});
```

### いざ開発サーバーを起動してPlaygroundで確認！

```bash
# 開発サーバー起動
$ npm run dev
```

## 実行結果
![スクリーンショット 2025-06-10 22.34.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737055/ea69817b-b0ad-49b6-8cf6-343a53092e42.png)

しっかりと計算結果が出力されました。

## おわりに
今回はClaude先生とペアプロをしてMastraのToolsについてハンズオン形式で学びました。
この勉強方法はかなり効果が感じられたので、次はWorkflowsについて同じように

**チュートリアルを読む＆動かす→Claude先生とペアプロ**

で進めてみようかなと思います。