Skip to main content

Export to SIEM

MintMCP exports activity logs to your SIEM or observability platform in real time using the OpenTelemetry Logs protocol (OTLP/HTTP). Tool invocations, prompt submissions, gateway requests, and access policy changes are captured and forwarded to any OTLP-compatible endpoint, or to a Splunk HEC endpoint.

What gets exported

MintMCP exports logs from three sources:

SourceWhat's capturedWhen
Agent MonitorTool calls from Claude Code, Cursor, and other agentsBefore each tool executes (via hooks)
Agent MonitorPrompt submissions from Claude Code and CursorBefore the prompt is sent to the model
MCP GatewayTool calls routed through the gatewayAfter each request completes
Audit logAccess grants and revokes on Virtual MCP servers, and connector credential lifecycle eventsWhen the change is recorded

The schemas below describe the exported event fields. OTLP delivers them as log records; Splunk HEC wraps the same fields as HEC events.

Configure the export

Via the UI

  1. Go to Enterprise in the sidebar
  2. Under OTLP Export, choose the Export Format: OTLP (default) or Splunk HEC
  3. Enter your collector endpoint URL
  4. Add any required headers (e.g., API keys or authorization tokens). Header values will be encrypted.
  5. Enable the export

Splunk HEC format

With the Splunk HEC format, each log record is delivered as an HTTP Event Collector event instead of an OTLP payload:

HEC fieldContents
timeEvent timestamp (epoch seconds)
eventThe log body merged with the log attributes
sourceAlways mintmcp
sourcetypeAlways _json
fieldsThe log attributes, which Splunk treats as indexed fields

Attributes appear in both event and fields, so user and tool attribution survives receivers that only ingest event. When a body key collides with an attribute name, the body value wins; non-object bodies (like the tool call array) are nested under a body key inside event.

Log record schemas

Agent Monitor: tool call logs

Each log record contains one or more tool calls that were intercepted by the agent hook.

Attributes:

AttributeTypeDescription
org.idstringOrganization ID
event.idstringUnique event ID (ULID)
user.idstringUser who triggered the tool call
matched_rulesstring[]IDs of any Agent Monitor rules that matched (omitted if none)

Body — an array of tool call objects, each containing:

{
"toolUseId": "toolu_abc123",
"tool": {
"type": "mcp",
"mcp": { "type": "remote", "url": "https://mcp.example.com" },
"name": "query_database"
},
"input": { "sql": "SELECT * FROM users LIMIT 10" },
"matchedRules": ["rule_block_pii_queries"],
"eventSource": "beforeMCPExecution"
}

The tool field identifies what was called:

Tool typeFieldsExample
Agent built-intype: "agent", agent, nameClaude Code's Bash tool
Remote MCPtype: "mcp", mcp.type: "remote", mcp.url, nameA MintMCP gateway tool
Local stdio MCPtype: "mcp", mcp.type: "stdio", mcp.command, nameA locally-running MCP server

The eventSource field identifies which agent hook produced the record. Every Cursor tool hook event is exported: beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, preToolUse, postToolUse, afterFileEdit, and beforeReadFile. Claude Code exports PreToolUse and PostToolUse. Prompt submissions are not tool calls, so they flow through their own schema below.

Agent Monitor: prompt submission logs

Each log record represents a prompt submitted by a user in Claude Code or Cursor, captured before the prompt is sent to the model.

Attributes:

AttributeTypeDescription
org.idstringOrganization ID
event.idstringUnique event ID (ULID)
event.typestringAlways prompt_submit
event.providerstringAgent that submitted the prompt (claudecode or cursor)
user.idstringUser who submitted the prompt
matched_rulesstring[]IDs of any Agent Monitor rules that matched (omitted if none)

Body:

{
"prompt": "Deploy the latest changes to staging",
"truncated": false,
"decision": "allow",
"sessionId": "session-abc123"
}
FieldTypeDescription
promptstringThe prompt text (truncated to 1024 characters, secrets redacted)
truncatedbooleanWhether the prompt was truncated
decisionstringallow or deny
decisionReasonstringWhy the prompt was denied (only present when decision is deny)
sessionIdstringSession or conversation ID

MCP Gateway logs

Each log record represents one completed request through the gateway.

Attributes:

AttributeTypeDescription
org.idstringOrganization ID
event.idstringUnique event ID
endpoint.idstringThe MCP endpoint that handled the request
user.idstringUser who made the request (omitted for non-user callers)
user.emailstringEmail of the user who made the request (omitted when unavailable)
agent.idstringAgent identity that made the request (omitted for user callers)
gateway.idstringGateway that routed the request (omitted when unavailable)
jsonrpc.methodstringJSON-RPC method (e.g., tools/call, tools/list)
tool.namestringTool that was called (for tools/call requests)
statusstringResult status (see below)
duration_msnumberRequest handling time in milliseconds
matched_rulesstring[]IDs of any gateway rules that matched (omitted if none)

Status values:

StatusMeaning
jsonRpcSuccessTool call completed successfully
jsonRpcErrorTool call returned an error
http202Request accepted (streaming)
http400Bad request
http401Unauthorized
http403Forbidden

Body:

{
"message": "MCP request completed",
"tool.arguments": "{\"sql\": \"SELECT * FROM users LIMIT 10\"}",
"detections": [
{
"ruleId": "rule_block_aws_keys",
"ruleName": "Block AWS access keys",
"scope": "org",
"action": "block",
"matchedText": "AKIA****************",
"start": 142,
"end": 162
}
]
}

The body is truncated to 16 KB to keep export volume bounded. Failed requests use "MCP request failed" as the message and set severity to WARN.

Detections: tools/call records include a detections array when at least one gateway rule fired, with one entry per rule match:

FieldTypeDescription
ruleIdstringRule that fired
ruleNamestringRule name, captured at the time it fired
scopestringorg for organization rules, global for MintMCP global rules
actionstringThe rule's resolved outcome: block, mask, or allow
matchedTextstringText the rule matched; masked when the rule is marked sensitive
start, endnumberCharacter offsets of the match

Rule name, scope, and action are snapshotted when the rule fires, so renaming or deleting a rule later doesn't change what the record says was true at the time. A rule that matched without a specific text match (e.g., a tool-level rule) produces a metadata-only entry. The flat matched_rules attribute carries the same rule IDs for backward compatibility.

Access grant audit logs

Each grant or revoke of access to a Virtual MCP server produces a log record, so your SIEM holds an independent history of who could reach which server and when that changed.

Attributes:

AttributeTypeDescription
org.idstringOrganization ID
event.idstringUnique event ID
event.actionstringadmin_config.access-grant.granted or admin_config.access-grant.revoked
event.domainstringAlways admin_config
event.kindstringAlways audit
event.outcomestringAlways success
user.idstringAdmin who made the change (omitted for system-initiated changes)
mintmcp.audit_signaturestringJSON-encoded signature of the underlying audit row (see below)

Body:

{
"message": "admin_config.access-grant.granted",
"detail": {
"type": "admin_config",
"audit": {
"resourceType": "access-grant",
"object": "g_4X8kQm...",
"relation": "caller",
"subject": "directory_group_01XYZ...",
"action": "grant"
}
}
}
FieldDescription
objectThe Virtual MCP server the grant applies to
relationPermission granted: caller (can connect and call tools) or editor (can manage the server, which includes calling)
subjectWho received it: a user ID, a directory group ID, or all_organization_members
actiongrant or revoke

Access grant history rows are signed at write time with a per-record digital signature over the row's identity and payload. The signature ships in the mintmcp.audit_signature attribute, and the public verification key is published as JWKS at /.well-known/mintmcp/audit-signing/jwks.json, so you can verify offline that exported records match what MintMCP originally wrote.

Connector credential lifecycle events (credential created, updated, removed, admin-revoked, or system-invalidated) flow through the same audit schema with event.domain set to connector_credential and actions like connector_credential.credential_created. See Audit and observability for what these events cover.