こんにちは!私は普段、Webアプリケーション開発を中心に活動するエンジニアです。先日、AIエージェントを使った業務自動化プロジェクトを進めていたとき、MCP(Model Context Protocol)という技術に出会いました。今回は、MCPのTool Use機能を拡張し、カスタムServerを登録する方法について、ゼロから丁寧に解説します。

MCP(Model Context Protocol)とは?

MCPは、AIアシスタントが外部ツールやデータソースと安全に接続するためのプロトコルです。従来のAPI呼び出しと異なり、MCPを使うことで...

事前準備:HolyShehep AIアカウント作成

まず、今すぐ登録してAPIキーを取得しましょう。HolySheep AIは、レートが¥1=$1(公式サイト¥7.3=$1の比較で85%の節約)という破格の料金体系が魅力で、DeepSeek V3.2は$0.42/MTokという的低コストで使用可能です。WeChat PayやAlipayにも対応しているので、日本国内でも簡単に始められます。登録すると無料クレジットが付与されるのも嬉しいポイントです。

Step 1:基本的なMCP Serverの構造を理解する

MCP Serverは、以下の3つの主要コンポーネントで構成されます:

まず、最もシンプルなServerを作成してみましょう。プロジェクトフォルダを新規作成し、必要なパッケージをインストールします:

# プロジェクトフォルダの作成
mkdir mcp-custom-server
cd mcp-custom-server

npm初期化と依存関係インストール

npm init -y npm install @modelcontextprotocol/sdk zod

TypeScript環境構築

npm install -D typescript @types/node ts-node npx tsc --init

Step 2:カスタムTool定義ファイルを作成する

次に、MCP Serverに組み込むToolの定義ファイルを作成します。「スクリーンショット例:プロジェクト構造がtreeコマンドで表示されている様子」

// src/tools/weather.ts
import { z } from "zod";

// Tool入力のスキーマ定義
export const WeatherInputSchema = z.object({
  city: z.string().describe("都市名(日本語または英語)"),
  units: z.enum(["celsius", "fahrenheit"]).optional().default("celsius"),
});

// Tool出力のスキーマ定義
export const WeatherOutputSchema = z.object({
  temperature: z.number(),
  condition: z.string(),
  humidity: z.number(),
  city: z.string(),
  timestamp: z.string(),
});

// 型安全な型推論
export type WeatherInput = z.infer;
export type WeatherOutput = z.infer;

// Toolの実装関数
export async function getWeather(input: WeatherInput): Promise {
  // 実際のAPI呼び出しはここに実装
  // デモ用のモックデータを返す
  return {
    temperature: 22,
    condition: "sunny",
    humidity: 65,
    city: input.city,
    timestamp: new Date().toISOString(),
  };
}

// Toolのメタデータ定義
export const weatherToolDefinition = {
  name: "get_weather",
  description: "指定された都市の現在の天気を取得します",
  inputSchema: WeatherInputSchema,
  outputSchema: WeatherOutputSchema,
};

Step 3:MCP ServerをHolySheep APIに接続する

ここが核心部分です。定義したToolをMCP Serverに登録し、HolySheep AIのAPIに接続します。HolySheep AIの低レイテンシ(<50ms)という特徴は、リアルタイム性が求められるTool呼び出しにおいて大きな役割を果たします。

// src/server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { weatherToolDefinition, getWeather } from "./tools/weather.js";

// 環境変数からAPIキーを読み込み
const HOLYSHEEP_API_KEY = process.env.HOLYSHEEP_API_KEY || "YOUR_HOLYSHEEP_API_KEY";
const BASE_URL = "https://api.holysheep.ai/v1";

// MCP Serverのインスタンス作成
const server = new Server(
  {
    name: "weather-mcp-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// 利用可能なToolリスト 등록
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: weatherToolDefinition.name,
        description: weatherToolDefinition.description,
        inputSchema: weatherToolDefinition.inputSchema,
      },
    ],
  };
});

// Tool呼び出しの 핸들러
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  try {
    if (name === "get_weather") {
      const result = await getWeather(args);
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
    }

    throw new Error(Unknown tool: ${name});
  } catch (error) {
    return {
      content: [
        {
          type: "text",
          text: エラーが発生しました: ${error instanceof Error ? error.message : String(error)},
        },
      ],
      isError: true,
    };
  }
});

// HolySheep API を 直接呼び出す функции
async function callHolySheepAI(userMessage: string, mcpTools: any[]) {
  const response = await fetch(${BASE_URL}/chat/completions, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": Bearer ${HOLYSHEEP_API_KEY},
    },
    body: JSON.stringify({
      model: "gpt-4o-mini",
      messages: [
        { role: "system", content: "あなたは有帮助なアシスタントです。" },
        { role: "user", content: userMessage },
      ],
      tools: mcpTools,
    }),
  });

  return response.json();
}

// Server起動
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Weather Server が起動しました");
}

main().catch(console.error);

Step 4:Server設定ファイルをjsonで作成する

MCPクライアントがServerを認識できるように、設定ファイルを追加します。

{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": ["dist/server.js"],
      "env": {
        "HOLYSHEEP_API_KEY": "YOUR_HOLYSHEEP_API_KEY"
      }
    }
  }
}

Step 5:実際に動かしてみる

「スクリーンショット例: терминал에서 node dist/server.js 를実行している様子」

# ビルド実行
npm run build

動作確認

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/server.js

天気取得Toolを呼び出すテスト

echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"東京"}}}' | node dist/server.js

応用:複数のToolを登録する

実践では、複数のToolを同時に使う場面が多いでしょう。以下は、Tool登録を拡張する方法です:

// src/tools/index.ts - Toolの一元管理
import { weatherToolDefinition, getWeather } from "./weather.js";

// 新しいToolを追加轻易
const TODO_ITEMS = [
  { id: 1, title: "MCPServer構築", done: true },
  { id: 2, title: "API統合テスト", done: false },
];

export const todoToolDefinition = {
  name: "manage_todos",
  description: "タスクリストの管理(作成・更新・削除・一覧取得)",
  inputSchema: {
    type: "object",
    properties: {
      action: {
        type: "string",
        enum: ["list", "add", "update", "delete"],
        description: "実行するアクション",
      },
      id: { type: "number", description: "タスクID(update/delete時必須)" },
      title: { type: "string", description: "タスクタイトル(add/update時必須)" },
      done: { type: "boolean", description: "完了フラグ(update時使用)" },
    },
    required: ["action"],
  },
};

// 全Tool定義の纏め
export const allTools = [weatherToolDefinition, todoToolDefinition];

// Tool実行のディスパッチ関数
export async function executeTool(name: string, args: any) {
  switch (name) {
    case "get_weather":
      return getWeather(args);
    case "manage_todos":
      return manageTodos(args);
    default:
      throw new Error(未対応のTool: ${name});
  }
}

function manageTodos(args: { action: string; id?: number; title?: string; done?: boolean }) {
  const { action, id, title, done } = args;

  switch (action) {
    case "list":
      return TODO_ITEMS;
    case "add":
      const newId = Math.max(...TODO_ITEMS.map(t => t.id)) + 1;
      TODO_ITEMS.push({ id: newId, title: title!, done: false });
      return { success: true, item: TODO_ITEMS[TODO_ITEMS.length - 1] };
    case "update":
      const item = TODO_ITEMS.find(t => t.id === id);
      if (item) {
        if (title !== undefined) item.title = title;
        if (done !== undefined) item.done = done;
      }
      return { success: true, item };
    case "delete":
      const index = TODO_ITEMS.findIndex(t => t.id === id);
      if (index > -1) TODO_ITEMS.splice(index, 1);
      return { success: true };
    default:
      throw new Error(不明なアクション: ${action});
  }
}

Hermes-Agentでの活用

Hermes-Agentを使用すると、MCP Server登録がさらに简单になります。設定ファイルに以下を追加してください:

# hermes-agent.config.yaml
agents:
  - name: my-assistant
    model: gpt-4o
    mcp_servers:
      - name: weather
        command: node
        args: [dist/server.js]
        env:
          HOLYSHEEP_API_KEY: ${HOLYSHEEP_API_KEY}
      - name: todos
        command: node
        args: [dist/todo-server.js]

料金比較:HolySheep AIを選ぶ理由

私は複数のAI API提供商を試しましたが、HolySheep AIのコストパフォーマンスは本当に别格です。実際の料金比较表をご覧ください:

特に高频にToolを呼び出す場合、レート节约効果は絶大です。WeChat Pay/Alipay対応で充值も简单、<50msの低レイテンシでストレスのない開発が可能です。

よくあるエラーと対処法

エラー1:APIキーが認識されない

// ❌ 误り
const API_KEY = "YOUR_HOLYSHEEP_API_KEY"; // リテラル文字列のまま

// ✅ 正しい
const API_KEY = process.env.HOLYSHEEP_API_KEY; // 環境変数から読み込み

// 起動時に环境変数を確認
if (!API_KEY) {
  console.error("エラー: HOLYSHEEP_API_KEY 环境変数が設定されていません");
  console.error(".env ファイルを作成して APIキーを設定してください");
  process.exit(1);
}

エラー2:Tool呼び出し時に「Unknown tool」エラー

// 原因:ListToolsRequestSchema のハンドラーが正しく注册されていない

// 确认ポイント
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "get_weather", // ← 呼び出し時の名前と完全一致させる
        description: "天気を取得します",
        inputSchema: { ... },
      },
    ],
  };
});

// ❌ 误り:名前が不一致
// Call: "getWeather" → Register: "get_weather" ← エラー発生

// ✅ 正しい:名前を统一
// Call: "get_weather" → Register: "get_weather" ← 正常に動作

エラー3:base_url設定の误り

// ❌ 误り:一般的なドキュメントのURLを使用
const BASE_URL = "https://api.openai.com/v1"; // ← 使わない
const BASE_URL = "https://api.anthropic.com";  // ← 使わない

// ✅ 正しい:HolySheep AIのエンドポイント
const BASE_URL = "https://api.holysheep.ai/v1";

// エンドポイント确认
console.log("API Endpoint:", BASE_URL); // デバッグ時にログ出力

エラー4:スキーマバリデーションエラー

import { z } from "zod";

// ❌ 误り:スキーマ定义が不完整
const BadSchema = z.object({
  name: z.string(), // descriptionがない
});

// ✅ 正しい:MCP仕様に基づいた完全なスキーマ
const GoodSchema = z.object({
  city: z.string().describe("取得したい都市名"),
  units: z.enum(["celsius", "fahrenheit"])
    .optional()
    .default("celsius")
    .describe("温度の単位"),
});

// バリデーションエラーの捕获
try {
  const result = GoodSchema.parse({ city: 123 }); // numberは不允许
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error("スキーマエラー詳細:", error.errors);
  }
}

まとめ

今回は、MCP(Model Context Protocol)を使ったTool Use拡張開発とカスタムServer登録」について解説しました。ポイントをまとめると:

HolySheep AIなら、レート¥1=$1の破格料金でGPT-4.1やClaude Sonnetが使える上、DeepSeek V3.2なら$0.42/MTokという惊异的低コスト。WeChat Pay/Alipay対応で充值も简单、<50msの低レイテンシで开发体验もバツグンです。

「スクリーンショット例:HolySheep AIのダッシュボードでAPIキーをコピーしている様子」

まずは今すぐ登録して 무료 크레딧を獲得し、MCP開発を始めてみましょう!

何か質問があれば、お気軽にコメントください。Happy coding!

👉 HolySheep AI に登録して無料クレジットを獲得