Skip to main content

MCP Protocol

The Model Context Protocol (MCP) is the primary interface for AI agents interacting with Claw GRC. MCP provides a structured session-based protocol with authentication, authorization, tool invocation, and audit logging built in.

Protocol Overview​

MCP follows a three-phase lifecycle:

Phase 1: Handshake​

The handshake establishes a session and returns the available tools.

Request​

POST /api/v1/mcp/handshake
Content-Type: application/json
X-API-Key: cgrc_...

{
"agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"protocol_version": "1.0",
"capabilities": ["grc.list_frameworks", "grc.create_finding"]
}
FieldTypeRequiredDescription
agent_idstring (UUID)YesThe registered agent's ID
protocol_versionstringYesMust be "1.0"
capabilitiesstring[]YesTools the agent intends to use

Response (201 Created)​

{
"session_id": "mcp_xK9mP2vB7nQ4wR8sT1uY3cE5fG6hJ",
"status": "active",
"supported_tools": [
"grc.list_frameworks",
"grc.get_compliance_score",
"grc.create_finding",
"grc.create_ticket",
"grc.list_findings",
"grc.trigger_scan",
"grc.call_agent",
"grc.discover_agents"
],
"expires_at": "2025-01-15T15:30:00Z"
}

Handshake Validation​

The server validates:

  1. Authentication -- The API key must be valid and belong to an active agent
  2. Agent status -- The agent must be active (not inactive)
  3. Protocol version -- Must be "1.0" (the only supported version)
  4. Organization match -- The agent must belong to the authenticated organization

Error Cases​

StatusErrorDescription
400Agent not foundThe agent ID does not exist in this organization
400Agent is inactiveThe agent has been deregistered
400Unsupported protocol versionOnly "1.0" is supported
401UnauthorizedInvalid or missing API key

Phase 2: Message (Tool Invocation)​

Once a session is established, the agent sends tool invocations as messages.

Request​

POST /api/v1/mcp/message
Content-Type: application/json
X-API-Key: cgrc_...

{
"session_id": "mcp_xK9mP2vB7nQ4wR8sT1uY3cE5fG6hJ",
"method": "grc.list_frameworks",
"params": {
"limit": 10,
"offset": 0
}
}
FieldTypeRequiredDescription
session_idstringYesThe session ID from the handshake
methodstringYesThe MCP tool to invoke
paramsobjectYesTool-specific parameters

Response (200 OK)​

Success:

{
"session_id": "mcp_xK9mP2vB7nQ4wR8sT1uY3cE5fG6hJ",
"result": {
"frameworks": [...],
"total": 11
},
"error": null
}

Tool error (authorization failure):

{
"session_id": "mcp_xK9mP2vB7nQ4wR8sT1uY3cE5fG6hJ",
"result": null,
"error": {
"code": "permission_denied",
"message": "Agent does not have capability for tool 'grc.trigger_scan'"
}
}

Message Validation​

The server validates:

  1. Session exists -- The session must be in the database and not expired
  2. Session ownership -- The authenticated actor must be the session owner (prevents cross-session hijacking)
  3. Session not expired -- Sessions expire 1 hour after creation
  4. Method recognized -- The method must be one of the supported MCP tools
  5. Capability authorized -- The agent's registered capabilities must include the requested tool
  6. Payload size -- The params field must not exceed 64KB

Error Cases​

StatusErrorDescription
400Session not found or expiredThe session has expired or does not exist
400Unknown methodThe tool name is not recognized
403Caller does not own this sessionCross-session access attempt detected
413Tool params too largePayload exceeds 64KB limit

Phase 3: Close​

Close a session to release resources and record the closure.

Request​

DELETE /api/v1/mcp/sessions/{session_id}
X-API-Key: cgrc_...

Response (204 No Content)​

No body is returned. The closure is logged in the audit trail.

Error Cases​

StatusErrorDescription
404Session not foundThe session does not exist or is already closed

Session Management​

Session Lifetime​

Sessions expire 1 hour after creation. Each tool invocation extends the session activity timestamp, but the expiration is based on creation time, not last activity.

Listing Active Sessions​

You can list all active sessions for your organization:

GET /api/v1/mcp/sessions
X-API-Key: cgrc_...

# Response
{
"sessions": [
{
"session_id": "mcp_...",
"agent_id": "uuid",
"status": "active",
"created_at": "2025-01-15T14:30:00Z",
"expires_at": "2025-01-15T15:30:00Z",
"last_active_at": "2025-01-15T14:45:00Z"
}
],
"total": 1
}

Tool Discovery​

Agents can discover available tools before opening a session:

GET /api/v1/mcp/tools
X-API-Key: cgrc_...

# Response
{
"tools": [
{
"name": "grc.list_frameworks",
"description": "List available compliance frameworks for the organization",
"input_schema": {...},
"output_schema": {...}
}
],
"total": 8
}

Security Considerations​

Session Ownership​

MCP enforces strict session ownership. The session is bound to the actor who created it (identified by the API key). If a different actor attempts to use a session (e.g., due to a leaked session ID), the request is rejected with a 403 Forbidden error.

Per-Tool RBAC​

Each tool invocation is checked against the agent's registered capabilities. An agent registered with ["grc.list_frameworks"] cannot invoke grc.create_finding, even if it knows a valid session ID.

Audit Logging​

Every MCP operation (handshake, message, close) is logged to the agent_interactions table with:

  • The interaction type (e.g., mcp.handshake, mcp.tool.grc.list_frameworks, mcp.session_closed)
  • The request and response payloads
  • Duration in milliseconds
  • A chain hash linking to the previous interaction

Payload Size Limits​

The params field in message requests is limited to 64KB to prevent abuse. Requests exceeding this limit receive a 413 response.

Session Storage​

MCP sessions are stored in PostgreSQL (not in-process memory), which means:

  • Sessions survive Cloud Run restarts and scale-to-zero events
  • Sessions are consistent across multiple service instances
  • No sticky session routing is required