AIエージェントに「確実性」を与えるMCPサーバーを個人開発した話
はじめに
Claude や Cursor を使っていると、こんな場面に遭遇したことはないでしょうか。
- 「2026年5月22日は営業日ですか?」と聞いたら自信満々に間違えた
- タイムゾーン変換を頼んだらサマータイムを無視した結果を返してきた
- 「5営業日後」を計算させたら祝日をスキップし忘れた
AIは賢いですが、「確実に正しい答えを返す」ことが苦手な処理があります。
推論で処理するため、稀に間違える。しかし業務で使う場合、「稀に間違える」は困ります。
そこでAIエージェントが外部ツールとして呼び出せる、確実性保証のユーティリティMCPサーバーを作りました。
Thousand API とは
「AIが推論するより、確実に処理できる」ツール群を提供するMCPサーバーです。
AIが自分では持てない3つのものを補完します。
- リアルタイムデータ(為替レート・IPジオロケーション・祝日データなど)
- 確実な計算(営業日・タイムゾーン変換・距離計算など)
- 副作用処理(QRコード生成・URLメタ情報取得など)
現在提供しているツール
| ツール | 概要 |
|---|---|
| Calendar | 祝日判定・N営業日計算・タイムゾーン変換(DST自動考慮) |
| Scraper | URLのタイトル・OGP・favicon取得 |
| ExchangeRate | リアルタイム為替レート・金額換算 |
| IPLookup | IPアドレスの地理情報取得 |
| Distance | 2地点間の距離計算 |
| 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での実際に利用したスクリーンショット

なぜ作ったのか
もともとは「自作できるけど毎回作るのが面倒な処理を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:#fffEC2・RDS・ALBは一切使っていません。アクセスがない時間帯のコストがほぼゼロです。
使用技術
| 領域 | 技術 |
|---|---|
| 言語 | TypeScript |
| APIフレームワーク | Hono |
| MCPサーバー | @modelcontextprotocol/sdk |
| インフラ | AWS CDK |
| 実行環境 | Lambda(Node.js 22)+ API Gateway(HTTP API) |
| HP | Next.js 15 + OpenNext + CloudFront |
| DB | DynamoDB(シングルテーブル設計) |
| 認証(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テーブルで管理しています。
| PK | SK | 用途 |
|---|---|---|
| USER#<userId> | METADATA | ユーザー情報 |
| USER#<userId> | APIKEY#<apiKeyId> | APIキー一覧用 |
| APIKEY#<hashedKey> | METADATA | APIキー逆引き |
| USAGE#<userId> | MONTH#<YYYYMM> | 月次使用量 |
APIキーはSHA-256ハッシュのみ保存し、平文は発行時の1度だけ表示します。
料金プラン
| プラン | 月間リクエスト | 価格 |
|---|---|---|
| Free | 1,000回 | 無料 |
| Starter | 10,000回 | ¥480/月 |
| Pro | 100,000回 | ¥1,980/月 |
無料プランでも全ツールが使えます。
まずは登録して試してみてください。
今後の予定
現在実装中・検討中のツールです。
- Cron式パーサー(次回実行日時計算)
- JSON Schema Validator(AI出力JSONの検証・自動修復)
- テキスト統計(文字数・読了時間)
- TrimSilence(音声ファイルの無音除去)
MCPのエコシステムはまだ発展途上で、
「AIエージェントが使うAPIはどうあるべきか」を試行錯誤しながら開発しています。
フィードバックや要望は https://www.thousand-api.com/contact からお気軽にどうぞ。
まとめ
- AIが「推論で曖昧にしか処理できないこと」を確実に解決するMCPサーバーを作った
- Claude・Cursorに設定を1行追加するだけで使える
- 完全サーバーレス構成でコストを最小化
- 無料プランあり
AIエージェントを使って開発している方、ぜひ試してみてください!



