human-dispatch-mcp について
human-dispatch-mcpは、AIエージェントのタスクを登録済みの人間のサービス提供者へ振り分けます。現実世界やデジタル業務を委託するエージェント運用者と提供者向けで、能力・地域・予算・信頼性に基づき、該当先がない場合は手動処理へ切り替えます。
主な機能
- 01カテゴリ・地域・予算による提供者照合
- 02フォールバックチェーンと手動処理
- 03タスク状況と完了証明の追跡
- 04Webhook提供者の登録と管理
- 05タスク一覧の絞り込みとページング
活用シーン
- 01現場業務やデジタル業務の委託
- 02進捗と完了証明の確認
- 03提供者のWebhook接続とタスク受信
- 04該当提供者がない場合の手動対応
MCP 対応
MCP サーバーとして、stdioまたはHTTP経由でタスクの振り分け、状態確認、キャンセル、提供者管理のツールをクライアントに公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y human-dispatch-mcpRENTAHUMAN_API_KEYシークレットAPI key for the RentAHuman.ai backendMTURK_ACCESS_KEY_IDシークレットAWS access key ID for the Amazon Mechanical Turk backendMTURK_SECRET_ACCESS_KEYシークレットAWS secret access key for the Amazon Mechanical Turk backendMTURK_SANDBOXSet to "false" to use MTurk production environment (defaults to sandbox mode)MANUAL_WEBHOOK_URLWebhook URL for the manual backend to send task notificationsローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
5掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| budget | object | はい | タスクの予算制約 |
| budget.max_usd | number | はい | このタスクに支払う意思のある上限額(USD) |
| budget.currency | string | いいえ | 通貨コード——現在は USD のみ対応しています |
| category | enum | はい | タスクのカテゴリ——最適なバックエンドを決定しますerrand | photo_video | data_collection | verification | delivery | digital_micro | in_person | custom |
| deadline | object | はい | タスクを完了する必要がある時期 |
| deadline.urgency | enum | はい | 緊急度:low=数日、medium=数時間、high=1 時間未満、asap=即時low | medium | high | asap |
| deadline.complete_by | string | はい | タスクの完了期限を示す ISO 8601 日時(例:'2025-01-15T18:00:00Z') |
| location | any | いいえ | タスクを実施する場所。実地タスクでは必須です。デジタルタスクの場合は null に設定するか、省略してください。 |
| metadata | object | いいえ | 独自の追跡に使用する任意のキーと値のペア(例:{'order_id': '12345', 'agent_name': 'my-bot'}) |
| task_type | enum | はい | タスクに実地での対応が必要か、デジタルのみか、またはその両方かphysical | digital | hybrid |
| description | string | はい | 人間の作業者が行う内容を明確かつ詳細に記述してください。場所、時間、期待する成果を具体的に指定してください。例:'Take a photo of the menu board at the Starbucks on 5th Ave and 42nd St, NYC'」 |
| quality_sla | enum | はい | 品質と速度のトレードオフ:low=最速/最安、medium=デフォルト、high=検証済みの作業者と複数の証明low | medium | high |
| callback_url | any | いいえ | ステータス更新通知を受信する Webhook URL。代わりにステータスをポーリングする場合は、null に設定するか省略してください。 |
| fallback_chain | array | いいえ | 優先バックエンドが失敗した場合に使用する、フォールバックバックエンドの順序付きリスト。'manual' バックエンドは常に最後の手段として利用できます。 |
| proof_required | array | はい | 作業者が完了時に提出する必要がある証明の種類。少なくとも 1 つ必要です。例:['photo', 'gps_checkin'] |
| preferred_backends | array | いいえ | このタスクの振り分けに使用する優先バックエンドサービス。記載順に試行します。省略した場合、ルーターが最適なバックエンドを自動選択します。 |
詳細
human-dispatch-mcp
🌐 humandispatch.ai — ホームページとプロバイダー向けドキュメント
AI エージェントから人間へのタスク振り分けを実現する汎用ディスパッチレイヤー — あらゆる事業者(法律事務所、VA サービス、フリーランサー、代理店)が Webhook 経由で接続し、数分で AI が振り分けたタスクを受け取り始められます。
スマートマッチング、フォールバックチェーン、完了証明の追跡機能を備え、登録済みの Webhook プロバイダーにタスクを振り分けます。あらゆるサービスプロバイダーが Webhook を登録すると、ルーターは対応能力、地域、予算に基づいてタスクをプロバイダーにマッチングします。
クイックスタート
# Clone and install
git clone https://github.com/zyntarasystems/human-dispatch-mcp.git
cd human-dispatch-mcp
npm install
# Configure (optional — works out of the box with manual fallback)
cp .env.example .env
# Build and run
npm run build
node dist/index.js
MCP Inspector でのテスト
サーバーが動作していることを確認する最も簡単な方法です。
npx @modelcontextprotocol/inspector node dist/index.js
http://localhost:5173 を開き、ターミナルに表示されたプロキシセッショントークンを入力して、Connect をクリックします。
テスト手順:
-
バックエンドを一覧表示する —
human_list_backendsを呼び出し、webhook_providerとmanualを確認します -
プロバイダーを登録する —
human_register_providerを呼び出します:
{
"name": "Test Provider",
"webhook_url": "https://webhook.site/your-uuid",
"webhook_secret": "a-secret-that-is-at-least-32-chars-long!",
"categories": ["digital_micro"],
"task_types": ["digital"],
"regions": ["*"],
"min_budget_usd": 0,
"max_budget_usd": 500,
"max_concurrent_tasks": 10
}
- タスクをディスパッチする — Raw JSON 入力モードで
human_dispatch_taskを呼び出します:
{
"description": "Test task — verify the MCP server is routing correctly",
"category": "digital_micro",
"task_type": "digital",
"budget": { "max_usd": 5, "currency": "USD" },
"deadline": {
"complete_by": "2026-04-10T18:00:00Z",
"urgency": "low"
},
"proof_required": ["text_report"],
"quality_sla": "low",
"callback_url": null
}
タスクは登録済みのプロバイダーに振り分けられます。一致するプロバイダーがない場合は、手動バックエンドにフォールバックします。
MCP クライアントの設定
Claude Desktop/Cursor/任意の MCP クライアント
{
"mcpServers": {
"human-dispatch": {
"command": "npx",
"args": ["human-dispatch-mcp"]
}
}
}
HTTP トランスポート
注記: HTTP トランスポートは
127.0.0.1のみをバインドします。リモートアクセスする場合は、TLS 終端リバースプロキシ(nginx、Caddy など)をサーバーの前に配置してください。ポートを直接公開しないでください。
必須: HTTP トランスポートは
MCP_AUTH_TOKENが設定されていないと起動しません。すべてのPOST /mcpリクエストにはAuthorization: Bearer <MCP_AUTH_TOKEN>を含める必要があります。/callbacks/task/:taskIdエンドポイントは代わりに HMAC 署名認証を使用するため、プロバイダーがベアラートークンを見ることはありません。
{
"mcpServers": {
"human-dispatch": {
"command": "npx",
"args": ["human-dispatch-mcp"],
"env": {
"TRANSPORT": "http",
"PORT": "3000",
"MCP_AUTH_TOKEN": "a-long-random-string-32-chars-or-more"
}
}
}
}
ツールリファレンス
| ツール | 説明 |
|---|---|
human_dispatch_task | 最も条件に合うプロバイダーを介して、人間の作業者が完了するタスクを送信します |
human_get_task_status | タスクの現在のステータス、作業者情報、提出された完了証明を取得します |
human_cancel_task | 保留中または進行中のタスクをキャンセルします |
human_list_tasks | フィルター(ステータス、バックエンド、カテゴリ)とページネーションを指定してタスクを一覧表示します |
human_list_backends | 利用可能なバックエンド、その設定状況、対応能力を表示します |
human_register_provider | ディスパッチされたタスクを受け取る Webhook プロバイダーを登録します |
human_list_providers | 登録済みプロバイダーを統計情報やフィルターとともに一覧表示します |
human_remove_provider | Webhook プロバイダーの登録を解除します |
アーキテクチャ
┌─────────────┐
│ AI Agent │
│ (Claude, etc)│
└──────┬───────┘
│ MCP Protocol (stdio or HTTP)
▼
┌──────────────────────────────────────┐
│ human-dispatch-mcp Server │
│ │
│ ┌────────────┐ ┌────────────────┐ │
│ │ Task Store │ │ Provider │ │
│ │ (in-memory)│ │ Registry │ │
│ └────────────┘ └───────┬────────┘ │
│ │ │
│ ┌────────────┐ ┌───────▼────────┐ │
│ │ Router │──│ Webhook │ │
│ │ (scoring) │ │ Provider │ │
│ └──────┬─────┘ │ Adapter │ │
│ │ └───────┬────────┘ │
│ │ │ │
│ │ ┌───────────▼─────────┐ │
│ │ │ Provider A (law) │ │
│ │ │ Provider B (VA) │ │
│ │ │ Provider C (photos) │ │
│ │ └─────────────────────┘ │
│ ▼ │
│ ┌────────────┐ │
│ │ Manual │ (always-on fallback) │
│ │ Adapter │ │
│ └────────────┘ │
└──────────────────────────────────────┘
サービスプロバイダー向け
あらゆる事業者がプロバイダーとして登録し、AI が振り分けたタスクを受け取れます。手順は次のとおりです。
1. Webhook エンドポイントを設定する
エンドポイントは、次のヘッダーを含む POST リクエストを受け取ります。
| ヘッダー | 説明 |
|---|---|
x-dispatch-signature | sha256=<hmac_hex> — 共有シークレットを使用したリクエストボディの HMAC-SHA256 |
X-Dispatch-Event | イベントタイプ:task.new、task.cancel、または provider.verify |
X-Dispatch-TaskId | タスクの UUID |
2. task.new イベントを処理する
リクエストボディ:
{
"payload_version": 1,
"event": "task.new",
"task_id": "uuid",
"description": "What needs to be done",
"category": "photo_video",
"task_type": "physical",
"location": { "address": "123 Main St", "region": "US" },
"budget": { "max_usd": 25, "currency": "USD" },
"deadline": { "complete_by": "2026-04-10T18:00:00Z", "urgency": "medium" },
"proof_required": ["photo", "gps_checkin"],
"quality_sla": "medium"
}
payload_version はリクエスト形式のバージョンです。パーサーは既知のバージョンに固定し、不明なバージョンは拒否してください。現在送信されるのは 1 のみです。
次のように応答します:
{ "accepted": true, "external_id": "your-internal-id" }
または、拒否します:
{ "accepted": false, "reason": "Outside service area" }
provider.verify イベントを処理する
プロバイダーが登録されると、サーバーはエンドポイントに到達可能であり、受け入れ可能であることを確認するため、直ちに provider.verify イベントを POST します。200 を返すだけでは不十分です — エンドポイントは JSON ボディで { "verified": true } を返す必要があります。それ以外の場合(フィールドがない、false、JSON 以外)は、到達不能として扱われます。これにより、URL に到達できるだけでなく、エンドポイントから明示的な同意を得て登録できます。
3. 完了を報告する(HTTP トランスポートのみ)
次のヘッダーを付けて http://<server>/callbacks/task/<task_id> に POST します。
x-provider-id:プロバイダーの UUIDx-dispatch-signature:ボディのsha256=<hmac_hex>
{
"status": "completed",
"proof": [
{ "type": "photo", "url": "https://...", "submitted_at": "2026-04-10T12:00:00Z" }
],
"actual_cost_usd": 20,
"notes": "Task completed successfully"
}
4. HMAC 署名を検証する
共有シークレットを使って、受信した Webhook を必ず検証してください。
const crypto = require('crypto');
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
HMAC の正規化に関する契約(重要): 署名は、再シリアライズした JSON オブジェクトではなく、リクエストの POST に使用された正確なバイト列に対して計算されます。コールバックを送信するときは、実際に送信するバイト文字列に署名してください。本文を解析して再度文字列化したものに署名してはいけません。キーの順序や空白が異なる可能性があるためです。JSON.stringify(payload) を一度だけ実行し、生成された文字列を保持して、その文字列に署名し、同じ文字列を送信してください。サーバー側でも受信時に同じルールが適用されます。JSON パーサーが処理する前に、生のリクエスト本文のバッファーを取得します。
スマートルーティング
ルーターは、以下に基づいて最適なバックエンドを自動的に選択します。
- エージェントの設定 —
preferred_backendsとfallback_chainが最初に優先されます - プロバイダーの照合 — カテゴリー、タスクの種類、リージョン、予算の適合性
- 信頼性 — 完了率の高いプロバイダーが優先されます
- 速度 — 高速なプロバイダーほど高く評価されます
- フォールバック —
manualバックエンドは最終的なフォールバックとして常に利用できます
エージェントの使用例
LangGraph を使用した Python
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
async def dispatch_photo_task():
async with MultiServerMCPClient({
"human": {
"command": "node",
"args": ["path/to/human-dispatch-mcp/dist/index.js"],
"transport": "stdio",
}
}) as client:
tools = client.get_tools()
# Register a provider first
await client.call_tool("human_register_provider", {
"name": "Photo Service Co",
"webhook_url": "https://photos.example.com/webhook",
"webhook_secret": "your-secret-that-is-at-least-32-characters",
"categories": ["photo_video"],
"task_types": ["physical"],
"regions": ["US"],
"min_budget_usd": 5,
"max_budget_usd": 100,
"max_concurrent_tasks": 20
})
# Dispatch a task
result = await client.call_tool("human_dispatch_task", {
"description": "Take a photo of the menu board at Starbucks on 5th Ave, NYC",
"category": "photo_video",
"task_type": "physical",
"location": {
"address": "5th Ave & 42nd St, New York, NY",
"region": "US"
},
"budget": {"max_usd": 15, "currency": "USD"},
"deadline": {
"complete_by": "2026-01-15T18:00:00Z",
"urgency": "medium"
},
"proof_required": ["photo", "gps_checkin"],
"quality_sla": "medium"
})
print(result)
asyncio.run(dispatch_photo_task())
環境変数
| 変数 | デフォルト値 | 説明 |
|---|---|---|
TRANSPORT | stdio | トランスポートモード:stdio または http |
PORT | 3000 | HTTP ポート(TRANSPORT=http の場合) |
MCP_AUTH_TOKEN | — | TRANSPORT=http の場合、すべての POST /mcp リクエストに必要なベアラートークンです。未設定の場合、HTTP トランスポートは起動を拒否します。 |
MANUAL_WEBHOOK_URL | — | 手動タスク通知用の Webhook URL |
PROVIDERS_CONFIG | — | 起動時に事前登録するプロバイダーオブジェクトの JSON 配列 |
セキュリティ
このサーバーは呼び出し元に代わって送信 HTTP リクエストを処理するため、信頼できるインフラストラクチャ内での実行を想定しています。関連する保証は次のとおりです。
- HTTP トランスポートには認証が必要です。
MCP_AUTH_TOKENは必須であり、設定されていない場合、サーバーは起動を拒否します。ベアラーの比較には定時間比較(timingSafeEqual)を使用します。 - DNS リバインディング対策は
POST /mcpで有効です。トランスポートは、Hostヘッダーが設定済みのループバック以外を指すリクエストを拒否します。 - 送信 URL の保護。 サーバーが取得するすべての Webhook URL(プロバイダー登録、
MANUAL_WEBHOOK_URL、callback_url、証明 URL)は、構造化された検証を通過します。HTTPS のみを許可し、ループバック、RFC1918/リンクローカル/ユニークローカルのホストを拒否します。また、最後の瞬間のリバインディングを防ぐため、取得時に DNS 解決を確認します。無効化する方法はありません。ローカルテストにはパブリックトンネル(ngrok、cloudflared)を使用してください。 - 受信コールバックは IP ではなく HMAC で認証されます。 各プロバイダーは専用の Webhook シークレットを登録します。サーバーは JSON を解析する前に、生のリクエストバイト列に対する
x-dispatch-signatureを検証します。プロバイダーごとのトークンバケットにより、コールバックの大量送信が制限されます(バースト 30 件、継続時は毎秒 5 件)。 - 終端状態のガード。 タスクが
completed、failed、またはcancelledに到達すると、そのタスクへのコールバックは 409 で拒否されます。これにより、リプレイ、プロバイダーによる遅延再試行、プロバイダー主導のステータス変更を防ぎます。 - Webhook ペイロードのバージョン管理。 すべての送信本文には
payload_versionとeventの識別子が含まれます。パーサーのバージョンを固定し、不明なバージョンは拒否してください。 - Webhook シークレットがサーバーの外部に出ることはありません。 MCP ツールが返すプロバイダーデータはサニタイズされ、
webhook_secretが除去されます。このフィールドがログに記録されることもありません。 - 永続化は行いません。 タスク、プロバイダー、タスクごとの状態はメモリー上に保持されます。サーバーを再起動すると、すべての状態が破棄されます。本番環境で運用する場合は、処理中のタスクがプロバイダー内で停止したままにならず、速やかに失敗するよう、サーバーを適切に終了してください。
セキュリティ上の問題を発見した場合は、公開 Issue ではなく、GitHub で非公開のセキュリティアドバイザリを作成してください。
ロードマップ
- 永続的なプロバイダーレジストリ(SQLite / PostgreSQL)
- タスクの有効期限と自動再試行
- プロバイダーの品質スコアリングとフィードバックループ
- ディスパッチ前のコスト見積もり
- タスクの一括送信
- プロバイダーのダッシュボード / 管理 UI
- OAuth ベースのプロバイダー認証
コントリビューション
新しいバックエンドアダプターの追加
src/services/backends/に新しいファイルを作成しますBaseBackendAdapterを拡張しますBackendAdapterインターフェースのすべてのメソッドを実装しますsrc/types.tsのBackendId列挙型にバックエンド ID を追加しますsrc/index.tsでアダプターを登録します
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。