OpenAPI コントラクト を使って連携用クライアントを生成できます。公開 API、ダッシュボード、MCP 管理エンドポイントは、同じワークスペースのリソースと権限を扱います。
| 機能 | エンドポイント |
|---|---|
| 再利用できるツール | GET / POST /api/v1/voice/tools |
| ツールの取得・更新・削除 | GET / PATCH / DELETE /api/v1/voice/tools/{id} |
| ツールのプレビュー・テスト | POST /api/v1/voice/tools/{id}/test |
| ツールをエージェントに紐づけ | PUT /api/v1/voice/agents/{id}/tools |
| ナレッジベース | GET / POST /api/v1/voice/knowledge-bases |
| ナレッジベースの取得・更新・削除 | GET / PATCH / DELETE /api/v1/voice/knowledge-bases/{id} |
| ドキュメントの追加・一覧 | POST / GET /api/v1/voice/knowledge-bases/{id}/documents |
| ドキュメントの取得・削除 | GET / DELETE /api/v1/voice/knowledge-bases/{id}/documents/{doc_id} |
| 通話イベントの購読 | GET / POST /api/v1/voice/webhooks |
| 購読の取得・更新・削除 | GET / PATCH / DELETE /api/v1/voice/webhooks/{id} |
| 署名付きテストイベントを送信 | POST /api/v1/voice/webhooks/{id}/test |
| リモート MCP ツールの検出 | POST /api/v1/voice/mcp/discover |
| MCP 管理エンドポイント | /api/v1/voice/mcp |
CRM アダプターに照会する HTTP ツールを登録します。
{
"name": "lookup_customer",
"description": "Find a customer after confirming their customer ID.",
"kind": "http",
"url": "https://crm.example.com/customers/{{customer_id}}",
"method": "GET",
"read_only": true,
"credential_ref": "crm",
"input_schema": {
"type": "object",
"properties": { "customer_id": { "type": "string" } },
"required": ["customer_id"],
"additionalProperties": false
},
"response_path": "data"
}
POST /tools は { "data": { "id": "TOOL_ID", ... } } を返します。PUT /agents/AGENT_ID/tools と { "tool_ids": ["TOOL_ID"] } でその定義をエージェントに紐づけます。これはツール一覧全体をスナップショットで置き換えます。ライブラリのツールが変わったら紐づけ直してください。ライブラリの定義を削除しても既存のスナップショットは残ります。エージェント API の tools フィールドでインラインの定義を読み取り・置き換えることもできます。分析とウィジェットはエージェント API の analysis_config と widget_config で設定します。
ツールは GET、POST、PUT、PATCH、DELETE を使えます。query と request_body は { "customer": { "id": "{{customer_id}}" } } のような入れ子の JSON テンプレートを受け付けます。値全体がプレースホルダーの場合は元の JSON の型が保たれます。URL のプレースホルダーはエンコードされ、固定の公開 HTTPS ホストのあとにのみ置けます。request_body がない場合、GET 以外のツールは { "arguments": {...}, "call": { "callId": "...", "agentId": "...", "toolCallId": "...", "idempotencyKey": "..." } } を受け取ります。response_path はドット記法でフィールドを選びます。単純な parameters も引き続き使えます。input_schema はさらに入れ子のオブジェクト、配列、列挙、数値の範囲に対応します。外部スキーマの参照と正規表現は使えません。
static_args:モデルが何を書いても毎回送られる値(店舗 ID など)。アドレスと本文の {{name}} も埋めます。extract:[{name, path}] で関数の回答のフィールド(data.id)を保持し、後の関数の {{name}} に使います。照会で得た customer_id をモデルに繰り返させずに続く注文に渡せます。開始時の照会のフィールドも同じように保持されます。reject_when:最大 5 件のルール {on: caller|agent, pattern, negate}。直近の発言がすべてを満たす間は関数を実行せず、エージェントに reject_message を返します。model_says:呼び出しのたびにモデルが 1 文を書き、関数の実行中にそれを話します。固定の speak_before の代わりです。連携 → Webhook と通知 → 連携アプリ でアプリを接続し、エージェントの「ナレッジとツール」タブで「既製の関数を追加」を使います。自前のエンドポイントは不要です。
check_availability(指定日の空き時間)と book_appointment(発信者が選んだ時間を予約)を追加します。Google カレンダーの時間は、設定したタイムゾーン、営業日、営業時間、予約の長さに従います。Cal.com はイベントタイプ自体の空き状況を使い、発信者がメールアドレスを伝えない場合は設定した代替のメールアドレスを使います。save_to_sheet を追加し、指定した列に通話の ID と時刻を加えて 1 行追記します。notify_team を追加し、エージェントが書いたメッセージを Slack チャンネル(Incoming Webhook)に投稿します。これらの関数は、接続したアカウントで EvaSay のコントロールプレーンが実行します。Worker もエージェント定義もアプリの認証情報を持ちません。API でエージェントを読み取ると、これらは kind: "app"(app、action、connection_id、app_config 付き)として表示されます。tools を置き換えるときに残すには、そのまま送り返してください。アプリの接続はダッシュボードでのみ行えます。
エージェントのツールの 1 つに run_at_start: true を設定すると、各通話の開始時、エージェントが挨拶や応答をする前に呼び出されます。caller_number、called_number、direction、channel、call_id という名前のパラメーターには値が入ります。返されたフィールドは first_message、system_prompt、idle_messages の {{variables}} を埋め(1 階層下のフィールドは {{customer.name}})、回答全体が背景情報としてエージェントに渡されます。変数を含む挨拶は回答を最大 3 秒待ち、見つからないものは空欄のままになります。開始時に実行できるツールはエージェントごとに 1 つです。
認証情報はワークスペースと接続先ごとにサーバー環境で設定されます。credential_ref の発行は support@evasay.com にご依頼ください。API キーをエージェント定義、ヘッダー、プロンプト、ツールのパラメーターに入れないでください。CRM の認証情報はアダプター自身の環境に置けます。
業務システムにリクエストを送る前にツールをプレビューします。
{
"arguments": { "customer_id": "customer-123" },
"dry_run": true,
"mock_result": { "name": "Alex", "order_status": "shipped" }
}
プレビューはパラメーターを検証し、変換後のリクエストを表示します。会話の実行や業務システムへの接続は行いません。実際に実行するには dry_run=false を設定します。書き込みの本番テストには、さらに confirmed=true と idempotency_key(8–128 文字の英数字、ドット、アンダースコア、コロン、ハイフン)が必要です。テストのレスポンスには ok、status、duration_ms と上限付きの結果が含まれ、認証情報は返しません。読み取り・書き込みのテストにはワークスペースの書き込み権限が必要です。
通話中、業務リクエストには固定の Idempotency-Key が付きます。業務エンドポイントはこれを尊重する必要があります。1 通話内の同一の書き込みは、タイムアウトで結果が不明になった操作も含めて重複排除されます。意図的に別の操作を行うには、operation_id のような別の業務引数が必要です。EvaSay は書き込みを自動で再実行しません。ツール実行イベントにはステータスと所要時間が含まれます。会話テスト機能はテキストのシミュレーションであり、ツール実行のテストではありません。
POST /mcp/discover は { "url": "https://crm.example.com/mcp", "credential_ref": "crm" } を受け取り、サーバーのツールとスキーマを返します。選んだツールだけを登録します。
{
"name": "lookup_customer",
"description": "Find a CRM customer by confirmed ID.",
"kind": "mcp",
"url": "https://crm.example.com/mcp",
"mcp_tool": "get_customer",
"credential_ref": "crm",
"read_only": true,
"input_schema": {
"type": "object",
"properties": { "customer_id": { "type": "string" } },
"required": ["customer_id"]
}
}
エージェントが使えるのは登録したツールだけです。リモート接続は、リクエストへの JSON または SSE レスポンスを返す Streamable HTTP、公開 HTTPS の接続先、事前設定された認証情報に対応します。旧来の SSE エンドポイント、OAuth のネゴシエーション、サーバー起点の sampling/elicitation、バイナリ添付には対応しません。検出しても、サーバーのすべてのツールへのアクセスが自動で許可されるわけではありません。リモートツールのスキーマはインラインで、対応する JSON Schema のサブセットを使う必要があります。