Intercept

Intercept

The intercept endpoint is the integration point for agent hook scripts — Claude Code hooks, Gemini CLI hooks, and any agent framework that supports pre/post-execution interceptors. It accepts a tool call event, evaluates it against the same policy engines used by the MCP gateway, and returns a structured verdict the hook script can act on. This aligns with SEP-1763 and the experimental-ext-interceptors proposal for standardized tool-call interception.

Endpoint

POST /api/v1/intercept

This endpoint is available when the gateway is running in http or sse mode and intercept.enabled is true (the default). It uses the same CEL and AI policy engines as the MCP gateway.

Request Headers

HeaderRequiredDescription
Content-TypeYesMust be application/json
X-Maybe-Dont-Client-IDNoClient identifier for audit attribution
X-Request-IDNoPer-request tracing ID (generated if missing)

Request Body

{
  "event": "tools/call",
  "phase": "request",
  "payload": {
    "name": "Bash",
    "arguments": {
      "command": "rm -rf /"
    }
  },
  "context": {
    "sessionId": "session-abc123",
    "traceId": "trace-def456",
    "principal": {
      "type": "agent",
      "id": "claude-code-v1"
    }
  }
}
FieldRequiredTypeDescription
eventYesstringThe event type (e.g., tools/call)
phaseYesstringrequest to validate before execution, response to validate after
payload.nameYesstringName of the tool being called (e.g., Bash, Read, Write)
payload.argumentsNoobjectStructured arguments passed to the tool
payload.resultNoanyTool output. Required when phase is response
context.sessionIdNostringSession identifier for audit correlation
context.traceIdNostringTrace identifier for distributed tracing
context.principalNoobjectIdentity of the actor. Has type and id fields

Response Phase

When validating after execution ("phase": "response"), include the tool’s output in payload.result:

{
  "event": "tools/call",
  "phase": "response",
  "payload": {
    "name": "Bash",
    "arguments": {
      "command": "cat /etc/passwd"
    },
    "result": {
      "content": [
        {"type": "text", "text": "root:x:0:0:root:/root:/bin/bash\n..."}
      ]
    }
  }
}

Response: Valid

{
  "interceptor": "maybe-dont",
  "type": "validation",
  "phase": "request",
  "valid": true,
  "severity": "info",
  "messages": [],
  "durationMs": 12,
  "info": {
    "request_id": "req-abc123",
    "server_version": "1.4.0",
    "results": []
  }
}

Response: Invalid

{
  "interceptor": "maybe-dont",
  "type": "validation",
  "phase": "request",
  "valid": false,
  "severity": "error",
  "messages": [
    {
      "message": "Destructive command detected",
      "severity": "error"
    }
  ],
  "durationMs": 42,
  "info": {
    "request_id": "req-abc123",
    "server_version": "1.4.0",
    "results": [
      {
        "policy_name": "no-destructive-ops",
        "policy_type": "ai",
        "action": "deny",
        "message": "Recursive rm operations are not permitted"
      }
    ]
  }
}

Response Fields

FieldTypeDescription
interceptorstringAlways "maybe-dont". Identifies the interceptor to the calling agent
typestringAlways "validation". Reserved for future response types
phasestringEchoes the request phase (request or response)
validbooleanWhether the tool call passed all policies
severitystringOverall severity: info when valid, error when denied
messagesarrayPer-policy messages with individual severity levels
durationMsintegerTotal evaluation time in milliseconds
info.request_idstringUnique request identifier for audit correlation
info.server_versionstringGateway version
info.resultsarrayPer-policy evaluation results

Error Codes

CodeHTTP StatusDescription
intercept_disabled400Intercept endpoint not enabled in gateway config
invalid_request400Malformed request body
missing_event400Required event field is empty
missing_phase400Required phase field is empty
unsupported_event400Event type is not supported (only tools/call)
invalid_phase400Phase must be request or response
missing_payload_name400Required payload.name field is empty
response_phase_missing_result400payload.result is required for response phase
invalid_content_type415Wrong Content-Type header

Error Response Format

{
  "error": "invalid_request",
  "message": "Request body must be valid JSON"
}

Example: curl

curl -X POST http://localhost:8080/api/v1/intercept \
  -H "Content-Type: application/json" \
  -H "X-Maybe-Dont-Client-ID: developer@example.com" \
  -d '{
    "event": "tools/call",
    "phase": "request",
    "payload": {
      "name": "Bash",
      "arguments": {"command": "gh pr create --title \"Feature X\""}
    },
    "context": {
      "sessionId": "session-abc123",
      "principal": {"type": "user", "id": "developer@example.com"}
    }
  }'

Configuration

The intercept endpoint is enabled by default. To disable it:

intercept:
  enabled: false

Or via environment variable:

MAYBE_DONT_INTERCEPT_ENABLED=false

The shell_tool_names list tells the gateway which tool names contain CLI commands in their arguments (e.g., Bash, execute_command). When the gateway receives one of these tools, it extracts the command string and evaluates it against CLI policies. Override the defaults to match the tool names used by your agent:

intercept:
  shell_tool_names:
    - Bash
    - shell
    - run_terminal_command

Audit Integration

Intercept validations appear in the audit log alongside MCP, CLI, and action entries. Intercept entries use "source": "intercept" to distinguish them. The phase field maps to request_validation or response_validation in the audit record:

{
  "timestamp": "2025-06-01T10:30:00Z",
  "source": "intercept",
  "phase": "request_validation",
  "tool": {
    "name": "Bash",
    "arguments": {"command": "gh pr create --title \"Feature X\""}
  },
  "context": {
    "sessionId": "session-abc123",
    "principal": {"type": "user", "id": "developer@example.com"}
  },
  "decision": "allow",
  "duration_ms": 12
}

The context fields from the request are preserved in the audit entry, making it straightforward to correlate intercept decisions with specific agent sessions and users.

This endpoint is designed for agent hook scripts that intercept tool calls before or after execution. For MCP-native integrations, the MCP gateway handles interception automatically. For non-hook CLI wrappers, see CLI Validate.