AIエージェントに「確実性」を与えるMCPサーバーが50ツールになりました

はじめに

以前こちらの記事で、AIエージェント向けのユーティリティMCPサーバー Thousand API を公開しました。

https://zenn.dev/redwing/articles/21a0d106b993a8

リリース時はCalendar・Scraper・ExchangeRate・IPLookup・Distance・QRCodeの6ツールでした。

あれから継続して開発を続け、ついに50ツールに到達しました

この記事では、新たに追加したツール群の紹介と、開発を続けて気づいたことをまとめます。


Thousand APIとは

「AIが推論するより、確実に処理できる」ツール群を提供するMCPサーバーです。

LLMは賢いですが、以下のような処理で稀に誤ります。

  • 浮動小数点計算(0.1 + 0.1 + 0.10.30000000000000004 になる)
  • タイムゾーン・祝日を考慮した日付計算
  • UUIDの生成(フォーマットは正しくてもバージョンビットがおかしい)
  • Base64エンコード(日本語・絵文字を含む場合)
  • セマンティックバージョンの大小比較(1.10.0 > 1.9.0 を文字列比較すると逆になる)

「稀に間違える」は業務では困ります。Thousand APIはこれらを確実に処理するツールとして機能します。

// MCPサーバーの設定(Claude Desktop / Cursor 共通)
{
  "mcpServers": {
    "thousand-api": {
      "url": "https://mcp.thousand-api.com/mcp",
      "headers": {
        "x-api-key": "YOUR_API_KEY"
      }
    }
  }
}

APIキーは https://www.thousand-api.com で無料登録後に発行できます(Free: 1,000回/月)。


新たに追加した主なツール

カテゴリ別に紹介します。

🔐 セキュリティ・認証

HMAC署名生成・検証(generate_hmac

StripeやGitHubのWebhook検証でよく使うHMAC署名を生成・検証します。検証にはcrypto.timingSafeEqual()を使用しており、タイミング攻撃対策済みです。

// Webhookペイロードの署名検証
{
  "name": "generate_hmac",
  "arguments": {
    "mode": "verify",
    "algorithm": "sha256",
    "secret": "webhook-secret",
    "message": "{\"event\":\"payment.completed\"}",
    "signature": "受信したX-Signature-256の値"
  }
}
// → { "verified": true }

LLMにHMAC計算を頼むと、シークレットキーがプロンプトに残ります。ツールとして分離することでシークレットを会話に出さずに処理できます。

UUID生成・検証(generate_uuid / validate_uuid

crypto.randomUUID()を使ったRFC 4122準拠のUUID v4を生成します。LLMが生成するUUIDはフォーマットが正しくてもバージョンビット・バリアントビットがおかしいことがあります。

// 10件一括生成
{
  "name": "generate_uuid",
  "arguments": { "count": 10 }
}

🔄 変換・フォーマット

TOML↔JSON変換(convert_toml

Cargo.tomlpyproject.tomlなどの設定ファイルを扱う際に便利です。

XML↔JSON変換(convert_xml

SOAP・RSS・AWS設定ファイルなど、XMLを扱う場面で活躍します。属性は@プレフィックスで表現されます。

// XMLをJSONに変換
{
  "name": "convert_xml",
  "arguments": {
    "input": "<user id=\"1\"><name>Alice</name></user>",
    "direction": "to_json"
  }
}
// → { "user": { "@id": 1, "name": "Alice" } }

セマンティックバージョン比較(compare_versions

1.10.0 > 1.9.0 を文字列比較すると誤って 1.9.0 の方が大きいと判定されます。semverとして正しく比較します。

{
  "name": "compare_versions",
  "arguments": {
    "compare": "1.10.0",
    "against": "1.9.0"
  }
}
// → { "result": 1, "result_label": "greater" }

📝 テキスト・文字列

スラッグ生成(generate_slug

日本語を含むタイトルからURLスラッグを生成します。kuroshiroによるHepburnローマ字変換と組み合わせています。

{
  "name": "generate_slug",
  "arguments": {
    "text": "Thousand API — 祝日カレンダー機能",
    "locale": "ja"
  }
}
// → { "slug": "thousand-api-shukujitsu-karendaa-kinou" }

テキスト差分(diff_text

unified diff形式またはJSON形式で差分を返します。AIが生成したテキストと元のテキストを比較するのに便利です。

HTML→プレーンテキスト抽出(extract_text_from_html

スクレイピングしたHTMLからプレーンテキストを抽出します。<script><style>タグを除去し、HTMLエンティティをデコードします。LLMに渡すトークンを大幅に削減できます。


🛡️ データ処理

JSONマージ/パッチ(merge_json

deep mergeとRFC 6902 JSON Patchの両方に対応します。

// RFC 6902 JSON Patchで特定フィールドだけ更新
{
  "name": "merge_json",
  "arguments": {
    "mode": "patch",
    "base": { "name": "Alice", "age": 30, "role": "user" },
    "operations": [
      { "op": "replace", "path": "/role", "value": "admin" }
    ]
  }
}
// → { "name": "Alice", "age": 30, "role": "admin" }

配列差分(diff_arrays

2つの配列を比較してadded・removed・unchangedを返します。オブジェクト配列はキーフィールドで比較できます。

{
  "name": "diff_arrays",
  "arguments": {
    "before": [{ "id": 1 }, { "id": 2 }],
    "after":  [{ "id": 1 }, { "id": 3 }],
    "key": "id"
  }
}
// → { "added": [{"id": 3}], "removed": [{"id": 2}], "summary": "+1 -1 =1" }

🎨 カラー

WCAGコントラスト比計算(calc_color_contrast

WCAG 2.1のアルゴリズムでコントラスト比を計算します。AA/AAAの適合レベルを返します。

{
  "name": "calc_color_contrast",
  "arguments": {
    "foreground": "#FFFFFF",
    "background": "#1976D2"
  }
}
// → { "contrast_ratio": 4.68, "wcag_aa_normal": true, "wcag_aaa_normal": false }

sRGBのガンマ補正・相対輝度の計算をLLMに任せると高確率で誤ります。


🗾 50機能目:郵便番号↔住所変換(lookup_postal_code

記念すべき50機能目は郵便番号↔住所変換です。

日本郵便の公式CSVデータ(約12万件)をS3に保存し、Lambda起動時にメモリに展開してインメモリ検索します。

正引き(郵便番号→住所)

{
  "name": "lookup_postal_code",
  "arguments": { "code": "358-0001" }
}
// → {
//   "results": [{
//     "prefecture": "埼玉県",
//     "city": "入間市",
//     "town": "向陽台",
//     "code_formatted": "358-0001"
//   }]
// }

逆引き(住所キーワード→郵便番号)

「入間」「向陽台」など、住所の一部から中間一致検索できます。

{
  "name": "lookup_postal_code",
  "arguments": { "address": "向陽台" }
}
// → 向陽台を含む全国の住所候補を返す

LLMの学習データには廃止・新設された郵便番号が含まれていないことがあります。日本郵便の公式データを使うことで最新の情報に対応しています。

将来的には海外の郵便番号にも対応予定です(country パラメータは最初から設計に含まれています)。


現在の全ツール一覧(50ツール)

カテゴリツール
日時・カレンダーget_holidays, is_holiday, add_business_days, get_calendar_month, calc_schedule, get_cron_next, get_current_datetime, calc_datetime_diff
テキスト・文字列render_template, convert_string_case, generate_random_string, get_text_stats, convert_japanese, test_regex, diff_text, extract_text_from_html, generate_slug
変換・フォーマットconvert_markdown, convert_unit, format_number, get_qrcode, transform_image, convert_csv, convert_yaml, convert_toml, convert_xml, convert_base64
データ処理validate_json, query_json, merge_json, diff_arrays, calc_stats, validate_format
ネットワークget_page_meta, get_exchange_rate, get_ip_info, lookup_postal_code, resolve_url, dns_lookup, inspect_url
セキュリティdecode_jwt, generate_hash, generate_hmac, generate_uuid, validate_uuid
開発ユーティリティget_distance, convert_coordinates, generate_color_palette, calc_color_contrast, compare_versions

おわりに

50ツールまで続けてきて、改めて感じることがあります。

AIの「確実性の穴」は意外と多い

計算・変換・検証といった「答えが一意に決まる処理」はLLMには向いていません。しかしエージェントがタスクをこなす中でこれらの処理は頻繁に現れます。

Thousand APIはその穴を埋めるための存在です。

「自分でも作れるけど毎回作りたくない」処理をAIに任せる

これがThousand APIのコンセプトです。開発者はエージェントに「この郵便番号の住所を調べて」「このWebhookを検証して」と頼むだけで、確実な結果が返ってきます。


Thousand APIはFreeプランで月1,000回まで無料でお試しいただけます。

https://www.thousand-api.com

フィードバック・ご要望はXまたはお問い合わせフォームからお気軽にどうぞ。