Open11

MCP Client 作成 , Gemini Ollama + Electron , Express.js

knaka Tech-Blogknaka Tech-Blog

概要

  • MCP Clientの 調査メモになります。
  • Ollama ローカルLLM を使用します。
  • MCP Client作成に難航した為、関連記事を参考にしました。
  • 作業PCは、RAM 32GB、CPU (GPUなし)
  • 無課金で使用可能です (PCの、電気代の出費あります。)

[ 公開 2025/04/19 ]


関連の記事


環境

  • node 20
  • windows 11

感想

  • ローカルLLM 環境で、処理は遅めでしたが。
  • 短い、プロンプトでは。30秒位で処理できました。
  • MCPの連続テストでも、無課金で使用できそうでした。

deepwiki

https://deepwiki.com/kuc-arc-f/mcp_client_1ex

knaka Tech-Blogknaka Tech-Blog

MCP Server , 外部API連携

  • 上記の、MCP クライアント参考に。 MCP Serverを追加。
  • 外部APIの、接続URL は。.env から取得します。
  • d1 databaseに、データ保存します

書いたコード


  • src/mcp-2ex-test.ts
  • クライアントから、MCP Server設定を追加します。
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import 'dotenv/config'
console.log("API_URL=", process.env.API_URL);

const server = new McpServer({
  name: "mcp-2ex",
  version: "1.0.0",
});

server.tool(
  "mcp-2ex-test",
  `指定した 文字列を登録する。`,
  {
    text: z.string().min(1, { message: 'タイトルは必須です' })
  },
  async ({text}) => {
    try{
      const url = process.env.API_URL;
      const item = {title: text, description:"" }
      const response = await fetch(url + "/api/todos/create" ,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(item),
        }
      );
      if(response.ok === false){
        throw new Error("Error, response <> OK:");
      }
      const body = await response.text();
      return {
        content: [
          {
            type: "text",
            text: body,
          },
        ],
      };
    }catch(e){
      throw new Error("Error, mcp-2ex-test:" + e);
    }

  }
);

export const Mcp2exTestServer = server;


Test

  • プロンプトは、下記です、
  • todoを、d1に保存。
mcp-2ex-test を使って、お茶を購入して。休憩する を送信して欲しい。

  • 画面スクショ
  • 右側が、登録済の。 d1 画面になります。

knaka Tech-Blogknaka Tech-Blog

MCP Client 作成、Electron + Ollama版

  • electron で、MCP クライアント作成メモです。
  • 外部APIの、接続URL は。.env から取得します。
  • d1 databaseに、データ保存します

書いたコード


操作

  • model 選択 : qwen2.5-coder:14b(右上) プルダウン
  • 右側は、登録済の d1 database画面


  • プロンプト参考
mcp-2ex-test を使って、お茶を購入して。休憩する を送信して欲しい。

  • MCP server
  • mcp-client-ui/src/mcp-servers/mcp-2ex-test.ts

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui/src/mcp-servers/mcp-2ex-test.ts


  • home画面
  • mcp-client-ui/src/client/home.tsx

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui/src/client/home.tsx


knaka Tech-Blogknaka Tech-Blog

自然言語処理 使わず、 MCP Client 作成する例

  • 自然言語処理 未使用で、MCP Client 操作する例です。
  • 前回は、ollama使用しました。
  • NLP 使用に、重要と考えてない場合。
  • 直接 MCP Client実行する方法も選択も良いかもしれないです。
  • LLMの 自然言語処理を、実行しない為。大幅に時間短縮できます。

関連の記事

https://huggingface.co/blog/lynn-mikami/mcp-server-tutorial-jp


書いたコード


  • MCP Server
  • mcp-cli-2/src/mcp-servers/get-random-number.ts
  • ランダム数を返す。 toolパラメータ無し

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-2/src/mcp-servers/get-random-number.ts


  • MCP client
  • mcp-cli-2/src/cli-get-random.ts

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-2/src/cli-get-random.ts

  • client.callTool : tool.name を指定します。
  • arguments: tool に渡すパラメータ(この例は、無しです)
  • 下記は、別client 例ですが。arguments 指定例です。
    const result = await client.callTool({
      name: "name123",
      arguments: {
        sides: 4,
      },
    });

  • build
npx esbuild --bundle ./src/cli-get-random.ts --format=esm --minify --outfile=./dist/cli-get-random.js
  • start
node dist/cli-get-random.js

  • Log
  • MCP Serve から、結果を受信できます。
>node dist/cli-get-random.js
{ content: [ { type: 'text', text: 'Result : 7' } ] }

  • vitest 実行
npx vitest run ./src/cli-get-random.test.ts
  • Log
>npx vitest run ./src/cli-get-random.test.ts

 RUN  v3.1.2 D:/work/node/extra/mcp/mcp-cli-2

stdout | src/cli-get-random.test.ts > getRandomNumber > ランダムな数字を返す。
result= Result : 6

 ✓ src/cli-get-random.test.ts (1 test) 6ms
   ✓ getRandomNumber > ランダムな数字を返す。 5ms

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  12:33:51
   Duration  369ms (transform 54ms, setup 0ms, collect 88ms, tests 6ms, environment 0ms, prepare 88ms)


knaka Tech-Blogknaka Tech-Blog

Vercel AI SDK で、 MCP Client 的な CLI作成

  • Vercel AI SDK の例になります。
  • toolに対応しているようです。
  • LLM = gemini の構成になります。

関連の記事


書いたコード


  • tool 追加
  • mcp-cli-3/src/tools/getNumber.ts
  • MCP Serverの、tool設定に、似ています。
  • parameters: プロンプトから、LLM抽出した パラメータ
  • execute: 成功した時の、実行関数

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-3/src/tools/getNumber.ts


  • mcp-cli-3/src/index.ts
  • CLI - main:
  • generateText を使用します。
  • tools : 複数のtool設定し、LLMに送信できるようです。
async function executeMcp(input: string) {
  const result = await generateText({
    model: google(MODEL_NAME),
    tools: {
      getNumber, addTodo,
    },
    maxSteps: 5,
    messages: [{ role: "user", content: input }],
  });
  console.log("artifact", result.text);
}

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-3/src/index.ts


  • 補足: 別toolですが。tool内関数で。外部連携で、TODO登録する。
  • d1 databaseに、登録します。
  • 右側は、 d1の画面です


knaka Tech-Blogknaka Tech-Blog

Electron + Vercel AI SDK で、 MCP Client 画面作成

  • 前回同様、Vercel AI SDK の例になります。
  • LLM = gemini の構成になります。

書いたコード


  • home
  • mcp-client-ui-3/src/client/home.tsx

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui-3/src/client/home.tsx


  • tool
  • mcp-client-ui-3/src/tools/getNumber.cjs

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui-3/src/tools/getNumber.cjs


  • プロンプト参考
サイコロを振ってください。1から6までの整数を返してください。

  • 補足:

  • 別 toolですが。tool内関数で。外部連携APIで、消費品の金額登録する。

  • d1 databaseに、登録します。

  • プロンプト参考

addItemPrice を使って、 カフェラテの普通サイズ , 198 JPY を送信して欲しい。
  • 右側は、連携している web画面の一覧 ( AIとは直接関係ないです。 )


  • 登録時の動画
  • 登録完了まで、2,3秒 (ローカルLLM は、30秒前後)

knaka Tech-Blogknaka Tech-Blog

作業時間の登録、一覧表示 , Vercel AI SDK + MCPクライアント 作例

  • 前回同様、Vercel AI SDK の例になります。
  • LLM = gemini の構成になります。
  • 表示は、MD形式表示です。

書いたコード


  • .env
  • 設定: Google の、API_KEY設定
  • API_URL: 外部連携APIサービス
GOOGLE_GENERATIVE_AI_API_KEY="api-key"
API_URL=http://localhost:8787

  • home
  • mcp-client-ui-3/src/client/home.tsx

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui-3/src/client/home.tsx


  • tool , 登録
  • mcp-client-ui-3/src/tools/saveWorkHour.cjs

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui-3/src/tools/saveWorkHour.cjs


  • tool , 表示
  • mcp-client-ui-3/src/tools/getWorkList.cjs

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui-3/src/tools/getWorkList.cjs


  • プロンプト参考
  • 作業時間、登録
saveWorkHourを使って、 本日の作業開始 8:30 作業終了 17:00 を送信して。

  • 作業時間、表示
getWorkListを使って、作業一覧を、markdown記法の表形式で表示して欲しい。

  • 動画、 登録& 表示

knaka Tech-Blogknaka Tech-Blog

タスク管理の登録, 表示 Vercel AI SDK + MCPクライアント 作例

  • 前回同様、Vercel AI SDK の例になります。
  • LLM = gemini の構成になります。
  • d1 databaseに、データ保存します.。

構成

  • Vercel AI SDK
  • LLM gemini
  • Vercel AI SDK
  • electron
  • React
  • d1 + CF-workers

書いたコード


  • .env
  • 設定: gemini の、API_KEY設定
  • TASK_API_URL: タスク管理の外部連携APIサービス
  • TASK_API_KEY: タスク管理の認証鍵
GOOGLE_GENERATIVE_AI_API_KEY="api-key"
TASK_API_URL="API_URL=http://localhost:8787"
TASK_API_KEY="123"

  • tool , 登録
  • mcp-client-ui-3/src/tools/addTask.cjs

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-client-ui-3/src/tools/addTask.cjs


  • プロンプト参考
addTaskを使って、プロジェクトID 24 , タイトル テスト工程-1 , 開始日 2025-04-18 , 終了日 2025-04-22 を送信して。
  • 表示は、外部webアプリで表示

  • 動画、 登録& 表示

knaka Tech-Blogknaka Tech-Blog

Express + Vercel AI SDK + MCP作例

  • 前回同様、Vercel AI SDK の例になります。
  • LLM = gemini の構成になります。

構成

  • Vercel AI SDK
  • LLM gemini
  • Vercel AI SDK
  • express
  • React
  • node20
  • d1 + CF-workers

書いたコード


  • .env
  • 設定: gemini の、API_KEY設定
  • ユーザー名、パスワード
GOOGLE_GENERATIVE_AI_API_KEY="api-key"
USER_NAME="user1@example.com"
PASSWORD="123"

  • 参考: vercelデプロイで、env変数の設定
  • Settings > Environment Variables
  • Git push時に、 .envファイルをアップしなくて楽でした。


  • プロンプト参考
サイコロを振ってください。1から6までの整数を返してください。

  • tree
  • src/tools : tool配置
$ tree .
.
├── nodemon.json
├── package.json
├── public
│   ├── empty
├── rolldown.config.js
├── src
│   ├── App.tsx
│   ├── client
│   │   ├── Home.tsx
│   │   ├── Login.tsx
│   │   ├── about.tsx
│   │   └── lib
│   │       ├── HttpCommon.ts
│   │       └── LibConfig.ts
│   ├── components
│   │   └── Head.tsx
│   ├── config.ts
│   ├── entry-client.jsx
│   ├── entry-server.jsx
│   ├── index.ts
│   ├── lib
│   │   ├── Common.ts
│   │   └── LibConfig.ts
│   ├── main.css
│   ├── pages
│   │   └── App.tsx
│   ├── routes
│   │   ├── common.ts
│   │   ├── index.ts
│   │   ├── mcpRouter.ts
│   │   └── user.ts
│   └── tools
│       ├── addItemPrice.ts
│       ├── addTask.ts
│       ├── addTodo.ts
│       ├── getNumber.ts
│       ├── getTodoList.ts
│       ├── getWeatherInfo.ts
│       ├── getWorkList.ts
│       └── saveWorkHour.ts
├── tsconfig.json
└── vite.config.ts

  • 天気を調べるmcp的な、記事を参考にして。コピーすると そこそこ使えました。


knaka Tech-Blogknaka Tech-Blog

Qwen3 + Ollama 、MCP 作成

  • 前回同様、Ollama 版の例になります。
  • LLM = Qwen3 の構成になります。
  • qwen3:8b を使用 (サイズ 5.2GB)

構成

  • LLM qwen3:8b
  • node20

書いたコード


  • プロンプト参考
get-random-number を使って、数字を返す。

  • tree
  • src/mcp-servers に、McpServer 配置
$ tree .
.
├── package.json
├── src
│   ├── index.ts
│   ├── libs
│   │   └── direct-transport.ts
│   └── mcp-servers
│       ├── get-random-number.ts
│       └── mcp-2ex-test.ts
└── tsconfig.json


  • McpServerの例
  • mcp-cli-4/src/mcp-servers/get-random-number.ts

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-4/src/mcp-servers/get-random-number.ts


  • start
npm run dev

knaka Tech-Blogknaka Tech-Blog

Vercel AI SDK + Ollama + Qwen3、MCP 作成

  • 前回同様、Vercel AI SDK の例になります。
  • LLM = Qwen3 の構成になります。
  • qwen3:8b を使用

構成

  • Vercel AI SDK
  • LLM qwen3:8b
  • ollama-ai-provider
  • node20

書いたコード


  • プロンプト参考
サイコロを振ってください。1から6までの整数を返してください。

  • tree
  • src/tools に、tool 配置
$ tree .
├── package.json
├── src
│   ├── index.ts
│   └── tools
│       ├── addTask.ts
│       ├── addTodo.ts
│       ├── getNumber.ts
│       ├── getTodoList.ts
│       ├── getWorkList.ts
│       └── saveWorkHour.ts
└── tsconfig.json



import { generateText, tool } from "ai";
import { z } from "zod";
import { ollama } from 'ollama-ai-provider';
const MODEL_NAME = "qwen3:8b";

async function executeMcp(input: string) {
  let message = input + " /no_think";
  const result = await generateText({
    model: ollama(MODEL_NAME),
    tools: {
      getNumber, addTodo, saveWorkHour , getWorkList , addTask , getTodoList
    },
    maxSteps: 5,
    messages: [{ role: "user", content: message }],
  });
  console.log("artifact:");
  console.log(result.text);
}

  • package.json

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-6/package.json


  • start
npm run dev

  • tool の例、ランダム数を返却する。
  • mcp-cli-6/src/tools/getNumber.ts

https://github.com/kuc-arc-f/mcp_client_1ex/blob/main/mcp-cli-6/src/tools/getNumber.ts