Skip to main content

MCP Gateway Log Export API

Use the Log Export API to read MCP Gateway tool call logs from your own data platform, SIEM, warehouse, or scheduled export job.

The API returns newline-delimited JSON. Each response line is one complete JSON object, so clients can stream, parse, and checkpoint logs incrementally.

GET https://<your-gateway-host>/mcpgateway/logs/export

Response content type:

Content-Type: application/x-ndjson

Authentication

Pass a log export key from MCP Gateway:

X-Quilr-Log-Export-Key: sk-export-...

Do not use your MCP API token or admin API key as the request credential for this endpoint. The log export key is separate from tool-call authentication and management API authentication.

MCP Gateway exposes two export scopes:

Export keyScope
log_export_keyExports logs only for the MCP backend it belongs to.
tenant_log_export_keyExports logs for all MCP backends in the tenant.

Both scopes use the same endpoint, header, query parameters, pagination model, and response format. In tenant-scoped exports, each mcpgateway.tool_call event still includes the concrete backend in backend.id and backend.name.

Admin backend management responses include log_export_key for each backend and tenant_log_export_key for the tenant. Treat both as bearer secrets. They cannot call MCP tools, but they can read exportable tool call logs for their scope.

Query Parameters

All query parameters are optional.

ParameterDescription
start_timeISO 8601 lower bound for exported logs. Naive timestamps are treated as UTC.
end_timeISO 8601 upper bound for exported logs. Naive timestamps are treated as UTC.
cursorOpaque cursor from the previous checkpoint.next_cursor. When provided, it wins over start_time.
limitMaximum tool call rows to export in this response. Default 1000, maximum 5000.

Logs are available for a maximum of 15 days. Choose start_time within that retention window when backfilling. Requests with an effective start_time, end_time, or cursor timestamp before the retention window fail with 400.

If neither start_time nor cursor is provided, the API exports a default 24-hour window ending at the effective export end time.

Export Lag

The API does not export logs newer than 15 minutes. Gateway logs and prediction payloads are written asynchronously, so this lag keeps exported rows stable.

If end_time is newer than now - 15 minutes, the server clamps it to the maximum exportable time. The request still succeeds. The export_started and checkpoint events include the effective export bounds.

Request Examples

Start a backend-scoped export window:

curl -N \
-H "X-Quilr-Log-Export-Key: sk-export-..." \
"https://<your-gateway-host>/mcpgateway/logs/export?start_time=2026-05-14T00:00:00Z&end_time=2026-05-14T01:00:00Z&limit=1000"

Start a tenant-scoped export window:

curl -N \
-H "X-Quilr-Log-Export-Key: sk-exportl-..." \
"https://<your-gateway-host>/mcpgateway/logs/export?start_time=2026-05-14T00:00:00Z&end_time=2026-05-14T01:00:00Z&limit=1000"

Resume from the previous checkpoint:

curl -N \
-H "X-Quilr-Log-Export-Key: sk-export-..." \
"https://<your-gateway-host>/mcpgateway/logs/export?cursor=<next_cursor>"

When resuming with cursor, you do not need to pass start_time or end_time.

Pagination

Rows are ordered by:

started_at ASC, id ASC

The cursor is opaque. Store it exactly as returned in checkpoint.next_cursor and send it back as the cursor query parameter on the next request.

If checkpoint.has_more is true, call the endpoint again immediately with cursor=<next_cursor>.

If checkpoint.has_more is false, there are no more rows in the current effective window. Store next_cursor and poll later with that cursor to continue incremental export.

When an initial request returns zero rows, the API still returns a checkpoint cursor pinned to the effective end time. This lets exporters store one cursor value even for empty windows.

Coverage

The export covers MCP Gateway tool call traffic for the selected export scope, including:

Data typeExported
Tool call request metadataYes
Tool nameYes
Tool argumentsYes, with credential redaction
Tool response contentYes, with credential redaction
Input guardrail outcome and predictionsYes, with credential redaction
Output guardrail outcome and predictionsYes, with credential redaction
User emailYes
Agent identity from User-AgentYes
Extra metadataYes, with credential redaction
Raw bearer tokensNo
Raw request headersNo
Backend transport URLsNo

Response Events

Every successful response starts with export_started, contains zero or more mcpgateway.tool_call events, and ends with checkpoint.

export_started

The first line describes the export scope and effective export window.

{
"type": "export_started",
"schema_version": "v1",
"backend": {
"id": "backend_a1b2c3",
"name": "My Jira MCP"
},
"effective_start_time": "2026-05-14T00:00:00.000000Z",
"effective_end_time": "2026-05-14T01:00:00.000000Z",
"max_exportable_time": "2026-05-14T10:45:00.000000Z",
"end_time_clamped": false,
"limit": 1000
}
FieldTypeDescription
typestringAlways export_started.
schema_versionstringEvent schema version. Current value is v1.
backendobject or omittedMCP backend metadata for a backend-scoped export. Omitted for tenant-scoped exports.
scopeobject or omittedTenant export scope metadata for a tenant-scoped export. Omitted for backend-scoped exports.
effective_start_timestringISO 8601 timestamp where this export starts.
effective_end_timestringISO 8601 timestamp where this export ends.
max_exportable_timestringNewest timestamp eligible for export after the 15-minute lag.
end_time_clampedbooleantrue when the requested end_time was newer than max_exportable_time.
limitnumberMaximum tool call rows returned in this response.

For tenant-scoped export, the first line uses this scope shape:

{
"type": "export_started",
"schema_version": "v1",
"scope": {
"type": "tenant",
"tenant_id": "tenant_abc123",
"backend_count": 3
},
"effective_start_time": "2026-05-14T00:00:00.000000Z",
"effective_end_time": "2026-05-14T01:00:00.000000Z",
"max_exportable_time": "2026-05-14T10:45:00.000000Z",
"end_time_clamped": false,
"limit": 1000
}

scope

FieldTypeDescription
typestringAlways tenant for tenant-scoped exports.
tenant_idstringTenant ID for the exported logs.
backend_countnumberNumber of tenant backends included in the export scope.

mcpgateway.tool_call

Each tool call row is emitted as one mcpgateway.tool_call event.

{
"type": "mcpgateway.tool_call",
"schema_version": "v1",
"cursor": "<opaque-cursor>",
"backend": {
"id": "backend_a1b2c3",
"name": "My Jira MCP"
},
"request": {
"id": "jsonrpc-request-id",
"log_id": 123,
"started_at": "2026-05-14T00:00:01.123456Z",
"completed_at": "2026-05-14T00:00:01.573456Z",
"duration_ms": 450
},
"auth": {
"mode": "token"
},
"tool": {
"name": "create_issue"
},
"guardrails": {
"input": {
"outcome": "allowed",
"is_blocked": false,
"predictions": []
},
"output": {
"outcome": "allowed",
"is_blocked": false,
"predictions": []
}
},
"payload": {
"tool_arguments": {},
"response_content": {}
},
"response": {
"success": true,
"error_message": null
},
"metadata": {
"user_email": "dev@company.com",
"agent": "cursor",
"extra_data": {}
}
}

Top-Level Fields

FieldTypeDescription
typestringAlways mcpgateway.tool_call.
schema_versionstringEvent schema version. Current value is v1.
cursorstringOpaque cursor for this tool call row.
backendobjectMCP backend metadata.
requestobjectJSON-RPC request and log metadata.
authobjectAuthentication mode used for the tool call.
toolobjectTool metadata.
guardrailsobjectInput and output guardrail outcomes and predictions.
payloadobjectTool arguments and response content, with credential redaction.
responseobjectTool call success and error metadata.
metadataobjectUser, agent, and extra request metadata.

backend

FieldTypeDescription
idstringMCP backend ID.
namestringMCP backend display name.

request

FieldTypeDescription
idstring or nullJSON-RPC request ID.
log_idnumberInternal log row ID used for stable pagination ordering.
started_atstringTool call start timestamp in ISO 8601 format.
completed_atstring or nullTool call completion timestamp in ISO 8601 format.
duration_msnumber or nullTool call duration in milliseconds.

auth

FieldTypeDescription
modestring or nullAuthentication mode used by the gateway, such as token or OAuth-backed proxy auth.

tool

FieldTypeDescription
namestring or nullMCP tool name.

guardrails

FieldTypeDescription
inputobjectGuardrail result for tool call arguments.
outputobjectGuardrail result for tool response content.

Each guardrail result uses this shape:

FieldTypeDescription
outcomestring or nullFinal guardrail outcome for that direction.
is_blockedbooleanWhether that side of the tool call was blocked.
predictionsarray or nullPrediction results, with credential fields redacted.

payload

FieldTypeDescription
tool_argumentsobject, array, string, or nullTool call arguments, with credential fields redacted.
response_contentobject, array, string, or nullTool response content, with credential fields redacted.

The export redacts common credential fields and token patterns inside payloads, predictions, and metadata. Header-like objects are replaced with [REDACTED_HEADERS].

response

FieldTypeDescription
successboolean or nullWhether the tool call completed successfully.
error_messagestring or nullError message when the tool call failed, with credential patterns redacted.

metadata

FieldTypeDescription
user_emailstring or nullEnd-user email associated with the tool call, when provided.
agentstring or nullAgent identity extracted from the request User-Agent header.
extra_dataobjectAdditional request metadata, with credential fields redacted.

checkpoint

The final line on a successful response is a checkpoint.

{
"type": "checkpoint",
"schema_version": "v1",
"next_cursor": "<opaque-cursor>",
"rows": 1000,
"has_more": true,
"effective_end_time": "2026-05-14T01:00:00.000000Z",
"max_exportable_time": "2026-05-14T10:45:00.000000Z"
}
FieldTypeDescription
typestringAlways checkpoint.
schema_versionstringEvent schema version. Current value is v1.
next_cursorstringOpaque cursor to store and use on the next request.
rowsnumberNumber of mcpgateway.tool_call events emitted in this response.
has_morebooleantrue when another page is available for the same effective export window.
effective_end_timestringEffective upper bound used for this export response.
max_exportable_timestringNewest timestamp eligible for export after the 15-minute lag.

Errors

Errors are returned as NDJSON too.

{"type":"error","error":{"message":"<message>","code":"<code>"}}
FieldTypeDescription
typestringAlways error.
error.messagestringHuman-readable error message.
error.codestringMachine-readable error code.

Errors before streaming starts use HTTP status codes. Errors after streaming has started are emitted as an error event line because the HTTP response has already been committed.