API reference
Endpoints, headers, auth and error codes for the tool-call hook.
API reference
The endpoints your agent uses to get tool calls governed. All calls authenticate with an agent key.
Authentication
Send your agent key (it starts with sk-mcp-) as a bearer token on every request.
Authorization: Bearer sk-mcp-...Headers
| Header | Purpose |
|---|---|
| Authorization | Bearer sk-mcp-... agent key. Required. |
| x-vw-agent-run-id | Groups model calls into the same run. Aliases: x-session-id, helicone-session-id. |
POST /v1/mcp/hook
Ask for a decision on a native tool call. The gateway never runs the tool; it only returns a decision.
Request body:
| Field | Description |
|---|---|
| tool_name | Name of the tool, e.g. "Bash". |
| arguments | Object with the tool arguments, e.g. { "command": "ls" }. |
| session_id | The run id for this turn. Used to group the call into a run. |
| tool_use_id | A unique id for this specific call. |
curl -X POST "$VW_GATEWAY_URL/v1/mcp/hook" \
-H "Authorization: Bearer $VW_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"tool_name":"Bash","arguments":{"command":"ls"},"session_id":"run-123","tool_use_id":"call-1"}'Responses, one per decision:
{ "decision": "allow" }
{ "decision": "deny", "reason": "policy violation", "detections": [] }
{ "decision": "approval_required", "approval_id": 42,
"poll_endpoint": "/v1/mcp/approvals/42/status",
"expires_at": "2026-04-20T15:30:00+00:00" }
{ "decision": "rate_limited", "reason": "rate limit exceeded" }POST /v1/mcp/hook/result
Report the result of a tool that has already run, so the run shows what happened. Best-effort; it never blocks.
| Field | Description |
|---|---|
| tool_name | Name of the tool that ran. |
| tool_response | Object with the tool result. |
| session_id | Same run id used on the hook call. |
| tool_use_id | Same call id used on the hook call. |
import httpx, os
httpx.post(
f"{os.environ['VW_GATEWAY_URL']}/v1/mcp/hook/result",
headers={"Authorization": f"Bearer {os.environ['VW_AGENT_KEY']}"},
json={
"tool_name": "Bash",
"tool_response": {"stdout": "file1\nfile2"},
"session_id": "run-123",
"tool_use_id": "call-1",
},
)GET /v1/mcp/approvals/{id}/status
Check whether a pending approval has been decided. Returns a status of pending, approved, denied or expired.
curl "$VW_GATEWAY_URL/v1/mcp/approvals/42/status" \
-H "Authorization: Bearer $VW_AGENT_KEY"JSON-RPC error codes
On the MCP proxy path (POST /v1/mcp), an approval requirement comes back as a JSON-RPC error.
| Code | Meaning |
|---|---|
| -32001 | Tool requires approval. error.data has approval_id, poll_endpoint and expires_at. |
What gets scanned
For file-write tools, the gateway scans the content being written, not the file path or the text being removed. For other tools it scans the full arguments. This means writing sensitive data can be blocked, while deleting it is allowed.