AIエージェントに「確実性」を与えるMCPサーバーを個人開発した話

はじめに

Claude や Cursor を使っていると、こんな場面に遭遇したことはないでしょうか。

  • 「2026年5月22日は営業日ですか?」と聞いたら自信満々に間違えた
  • タイムゾーン変換を頼んだらサマータイムを無視した結果を返してきた
  • 「5営業日後」を計算させたら祝日をスキップし忘れた

AIは賢いですが、「確実に正しい答えを返す」ことが苦手な処理があります。
推論で処理するため、稀に間違える。しかし業務で使う場合、「稀に間違える」は困ります。

そこでAIエージェントが外部ツールとして呼び出せる、確実性保証のユーティリティMCPサーバーを作りました。

https://www.thousand-api.com

Thousand API とは

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

AIが自分では持てない3つのものを補完します。

  1. リアルタイムデータ(為替レート・IPジオロケーション・祝日データなど)
  2. 確実な計算(営業日・タイムゾーン変換・距離計算など)
  3. 副作用処理(QRコード生成・URLメタ情報取得など)

現在提供しているツール

ツール概要
Calendar祝日判定・N営業日計算・タイムゾーン変換(DST自動考慮)
ScraperURLのタイトル・OGP・favicon取得
ExchangeRateリアルタイム為替レート・金額換算
IPLookupIPアドレスの地理情報取得
Distance2地点間の距離計算
QRCodeテキスト・URLからQRコード生成

ClaudeやCursorへの接続方法

設定ファイルに以下を追加するだけで使えます。

Claude Desktop の場合(claude_desktop_config.json):

{
  "mcpServers": {
    "thousand-api": {
      "url": "https://mcp.thousand-api.com/mcp",
      "headers": {
        "x-api-key": "YOUR_API_KEY"
      }
    }
  }
}

Cursor の場合も同じ設定です。
APIキーは https://www.thousand-api.com で無料登録後に発行できます。

実際の動作例

Cursorで「来週月曜日から3営業日後の日付を教えて」と聞いたとき、
add_business_days ツールが呼び出され、祝日を正確に考慮した日付が返ってきます。

// MCPツールの呼び出し例
{
  "name": "add_business_days",
  "arguments": {
    "country": "JP",
    "from": "2026-05-26",
    "days": 3
  }
}

// レスポンス
{
  "from": "2026-05-26",
  "days": 3,
  "country": "JP",
  "result": "2026-05-29"
}

Cursorでの実際に利用したスクリーンショット

ThousandAPIをCursorで利用

なぜ作ったのか

もともとは「自作できるけど毎回作るのが面倒な処理をAPIにする」という
開発者向けユーティリティAPIとして始めました。

しかし「それならライブラリで良くない?」という根本的な問いにぶつかりました。
APIである必然性が弱かったのです。

そこで方向転換。「AIエージェントが使う」という文脈に絞ると話が変わります。

  • ライブラリは人間がインストールして使うもの
  • MCPサーバーはAIエージェントがそのまま呼び出せるツール

「人間が叩くAPIではなく、AIが叩くAPI」として再定義したことで、
提供する価値が明確になりました。


技術スタック

個人開発なのでコストと運用負荷を最小限にすることを優先しました。

インフラ構成

graph TD
    User["👤 ユーザー / AIエージェント"]

    User -->|"www.thousand-api.com"| CF["CloudFront"]
    User -->|"api.thousand-api.com"| APIGW_API["API Gateway\n(thousand-api)"]
    User -->|"mcp.thousand-api.com"| APIGW_MCP["API Gateway\n(thousand-api-mcp)"]

    CF -->|"/_next/static/*"| S3["S3\n(静的アセット)"]
    CF -->|"その他"| APIGW_WEB["API Gateway\n(thousand-api-web)"]

    APIGW_WEB --> LAMBDA_WEB["Lambda\n(Next.js Server)"]
    APIGW_API --> LAMBDA_AUTH["Lambda\n(Authorizer)"]
    LAMBDA_AUTH --> LAMBDA_API["Lambda\n(Calendar / Scraper /\nExchangeRate / etc.)"]
    APIGW_MCP --> LAMBDA_MCP["Lambda\n(MCPサーバー)"]

    LAMBDA_AUTH -->|"APIキー検証"| DYNAMO["DynamoDB\n(thousand-api)"]
    LAMBDA_API -->|"使用量記録"| DYNAMO
    LAMBDA_WEB -->|"ユーザー・APIキー管理"| DYNAMO
    LAMBDA_MCP -->|"HTTP"| APIGW_API

    style CF fill:#FF9900,color:#fff
    style S3 fill:#569A31,color:#fff
    style DYNAMO fill:#4053D6,color:#fff
    style APIGW_API fill:#E7157B,color:#fff
    style APIGW_MCP fill:#E7157B,color:#fff
    style APIGW_WEB fill:#E7157B,color:#fff
    style LAMBDA_WEB fill:#FF9900,color:#fff
    style LAMBDA_AUTH fill:#FF9900,color:#fff
    style LAMBDA_API fill:#FF9900,color:#fff
    style LAMBDA_MCP fill:#FF9900,color:#fff

EC2・RDS・ALBは一切使っていません。アクセスがない時間帯のコストがほぼゼロです。

使用技術

領域技術
言語TypeScript
APIフレームワークHono
MCPサーバー@modelcontextprotocol/sdk
インフラAWS CDK
実行環境Lambda(Node.js 22)+ API Gateway(HTTP API)
HPNext.js 15 + OpenNext + CloudFront
DBDynamoDB(シングルテーブル設計)
認証(HP)Auth.js v5
決済Stripe

モノレポ構成

thousand-api/
├── apps/
│   └── web/          # Next.js 15(HP)
├── packages/
│   ├── api/          # Lambda関数群(AI向けAPI)
│   ├── mcp/          # MCPサーバー
│   └── shared/       # 共通型定義・DynamoDBアクセス・認証
└── infra/            # AWS CDK

Hono on Lambda

API GatewayのHTTP APIにHonoを乗せています。
Lambda 1関数 = 1カテゴリで分割しているので、コールドスタートの影響を最小化できます。

// packages/api/src/functions/calendar/index.ts
import { Hono } from 'hono';
import { handle } from 'hono/aws-lambda';

const app = new Hono();
app.use('*', trackUsage());
app.get('/v1/calendar/holidays',      holidaysHandler);
app.get('/v1/calendar/is-holiday',    isHolidayHandler);
app.get('/v1/calendar/business-days', businessDaysHandler);

export const handler = handle(app);

MCPサーバーのLambda対応

MCPのStreamable HTTP transportをLambda上で動かすため、
Expressを薄く挟んでserverless-expressでアダプトしています。

// packages/mcp/src/index.ts
const app = express();
app.use(express.json());

app.post('/mcp', async (req, res) => {
  const server    = createServer();
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined, // ステートレスモード
  });
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

export const handler = serverlessExpress({ app });

DynamoDBシングルテーブル設計

ユーザー・APIキー・使用量をすべて1テーブルで管理しています。

PKSK用途
USER#<userId>METADATAユーザー情報
USER#<userId>APIKEY#<apiKeyId>APIキー一覧用
APIKEY#<hashedKey>METADATAAPIキー逆引き
USAGE#<userId>MONTH#<YYYYMM>月次使用量

APIキーはSHA-256ハッシュのみ保存し、平文は発行時の1度だけ表示します。


料金プラン

プラン月間リクエスト価格
Free1,000回無料
Starter10,000回¥480/月
Pro100,000回¥1,980/月

無料プランでも全ツールが使えます。
まずは登録して試してみてください。

https://www.thousand-api.com

今後の予定

現在実装中・検討中のツールです。

  • Cron式パーサー(次回実行日時計算)
  • JSON Schema Validator(AI出力JSONの検証・自動修復)
  • テキスト統計(文字数・読了時間)
  • TrimSilence(音声ファイルの無音除去)

MCPのエコシステムはまだ発展途上で、
「AIエージェントが使うAPIはどうあるべきか」を試行錯誤しながら開発しています。

フィードバックや要望は https://www.thousand-api.com/contact からお気軽にどうぞ。


まとめ

  • AIが「推論で曖昧にしか処理できないこと」を確実に解決するMCPサーバーを作った
  • Claude・Cursorに設定を1行追加するだけで使える
  • 完全サーバーレス構成でコストを最小化
  • 無料プランあり

AIエージェントを使って開発している方、ぜひ試してみてください!