ライブラリ「Agentic」を使って MCP を扱う【Node.js】

## はじめに

今回の記事は、以下のライブラリ「Agentic」に関する内容です。

●Intro - Agentic
　https://agentic.so/intro

![Agentic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/09293e07-60d9-42bf-a53c-5033be499a93.jpeg)


### 今回試すこと

今回、最終的に試すものは以下の「Agentic で MCPサーバーのツールを扱う処理」です。


●MCP Tools - Agentic
　https://agentic.so/tools/mcp

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5a80cf30-b51e-41e0-beb4-4a5561de7ae1.png)


 
### Agentic を知ったきっかけ

ここで、今回扱う Agentic を知ったきっかけに少しふれておきます。

以前、GitHub で「ai agents sdk」というキーワードで、AIエージェントの開発に役立つ SDK を探したことがありました。その時に、検索結果の 2番目に [transitive-bullshit/agentic](https://github.com/transitive-bullshit/agentic) が出てきたのを見かけました。

●Repository search results
　https://github.com/search?q=ai%20agents%20sdk&type=repositories

![GitHubでの検索.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4d66d9ea-585b-4a46-9f79-570ccf1afbf4.jpeg)

#### Agentic を別のところでも見かけた話

上記が最初に見かけた時の話でしたが、その他にも Vercel AI SDK のドキュメントを見ていた時に Agentic を見かけたことがありました。

具体的には、以下のページです。

●Foundations: Tools
　https://ai-sdk.dev/docs/foundations/tools

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d9030e56-af0f-4ad7-a763-76c43e6b8edb.png)


## 実際に試してみる

上で書いた流れで Agentic を見かけて、それで気になって試してみようと思いました。ここから、試した内容について書いていきます。


### 公式の情報

Agentic を試していくにあたり、参照する情報を公式ドキュメントから探します。

●Intro - Agentic
　https://agentic.so/intro


#### サンプル 1つ目

公式の情報を見ていくと、 https://agentic.so/tools/mcp#usage という部分に以下のコードサンプルが掲載されていました。


```javascript
import 'dotenv/config'

import { createAISDKTools } from '@agentic/ai-sdk'
import { createMcpTools } from '@agentic/mcp'
import { openai } from '@ai-sdk/openai'
import { generateText } from 'ai'

async function main() {
  // Create an MCP tools provider, which will start a local MCP server process
  // and use the stdio transport to communicate with it.
  const mcpTools = await createMcpTools({
    name: 'agentic-mcp-filesystem',
    serverProcess: {
      command: 'npx',
      args: [
        '-y',
        // This example uses a built-in example MCP server from Anthropic, which
        // provides a set of tools to access the local filesystem.
        '@modelcontextprotocol/server-filesystem',
        // Allow the MCP server to access the current working directory.
        process.cwd()
        // Feel free to add additional directories the tool should have access to.
      ]
    }
  })

  const result = await generateText({
    model: openai('gpt-4o-mini'),
    tools: createAISDKTools(mcpTools),
    toolChoice: 'required',
    temperature: 0,
    system: 'You are a helpful assistant. Be as concise as possible.',
    prompt: 'What files are in the current directory?'
  })

  console.log(result.toolResults[0])
}

await main()
```


冒頭の部分で以下のインポート文があります。

```javascript
import { openai } from '@ai-sdk/openai'
import { generateText } from 'ai'
```

このサンプルでは、前に試している [Vercel の AI SDK](https://ai-sdk.dev/docs/introduction) も使われているようです。


#### サンプル 2つ目

さらに GitHub も含めて情報を見ていくと、以下のサンプルもありました。

●agentic/examples/ai-sdk/bin/mcp-filesystem.ts at main · transitive-bullshit/agentic
　https://github.com/transitive-bullshit/agentic/blob/main/examples/ai-sdk/bin/mcp-filesystem.ts


先ほどのサンプルと似たようなものでしたが、以下の部分が少し違ったもののようでした（以下は、GitHub上のサンプルのほうにのみ書かれている部分）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/15a770db-78bd-482d-977c-30ebabdd30f2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/16f5f3e2-70ff-4980-9a34-330f4fc9f8fe.png)


さらに、ログ出力の処理も 2つの内容に関して少し違いがありました。

```javascript:公式ページ上のサンプル
  console.log(result.toolResults[0]);
```

```javascript:GitHub上のサンプル
  console.log(result.toolResults[0]?.result || JSON.stringify(result, null, 2));
```


それらを見て、最終的には終了まわりの処理が加わっている GitHub上のサンプルをもとに、今回のお試しを進めていくことにしました。


### 下準備

#### パッケージのインストールと環境変数の設定

先ほど見たコードの冒頭を見て、使われているパッケージをインストールします。

```zsh
npm i @agentic/mcp @agentic/ai-sdk @ai-sdk/openai exit-hook
```

また、環境変数 OPENAI_API_KEY に、OpenAI の APIキーをセットしておきます。

#### フォルダの作成

サンプルでは、MCPサーバーとして「[Filesystem MCP Server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem)」を使っていて、その作業対象は「ワーキングディレクトリ」になっています。

この部分は、明確に処理結果を保存するフォルダを分離するほうが結果を確認しやすいと思われるため、ワーキングディレクトリ直下に処理対象となるフォルダを新規に作りました（「mcp」という名前のサブフォルダを作成します）。


これで下準備は完了です。


### コードの内容

今回用いたコード（サンプルコードに少しだけ手を加えたもの）を以下に掲載します。


```javascript
import { createAISDKTools } from "@agentic/ai-sdk";
import { createMcpTools } from "@agentic/mcp";
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { gracefulExit } from "exit-hook";

async function main() {
  const mcpTools = await createMcpTools({
    name: "agentic-mcp-filesystem",
    serverProcess: {
      command: "npx",
      args: [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        process.cwd() + "/mcp",
      ],
    },
  });

  const result = await generateText({
    model: openai("gpt-4o"),
    tools: createAISDKTools(mcpTools),
    toolChoice: "required",
    temperature: 0,
    maxSteps: 10,
    system: "You are a helpful assistant. Be as concise as possible.",
    prompt:
      "フォルダのルートに、AIの説明を1文にしたものを書き込んだ AI.txt というファイルを新規作成してください。",
  });

  console.log(result.toolResults[0]);
  console.log(result.toolResults[0]?.result || JSON.stringify(result, null, 2));
}

try {
  await main();
  gracefulExit(0);
} catch (err) {
  console.error(err);
  gracefulExit(1);
}
```


#### 処理結果

上記のコードを実行した結果は、以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/619aecfd-b4b2-417f-9b61-65fc9cbf6a77.png)


ファイル名が指定していたものと少し違っていますが、以下のように、「AI に関する説明の文 1つが書かれたテキストファイルの作成」が行われました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/89040f54-44b5-43d1-b08c-eba001167b95.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/11f7b373-8be0-4462-a15b-2e945c4af45c.png)