Audit MCP Endpoint Calls
Use this guide to enable audit on one Configuration Plan and verify the records produced by successful and rejected MCP requests. Audit is an endpoint policy: enabling Gateway telemetry alone does not cause every Exposition to emit audit events.
Audit events are OpenTelemetry log records marked with log.type=audit. The Gateway exports them through its OpenTelemetry Logs pipeline; storage, routing, retention, and access control belong to the configured Collector and telemetry backends.
Prerequisites​
You need:
- a reShapr Gateway and CLI at version
0.2.3; - Gateway OpenTelemetry logs configured with Observe the reShapr Gateway;
- a telemetry or audit backend where you can search exported records;
reshapr logincompleted for the target organization;- an imported Service, its backend endpoint, and a Gateway Group ID;
curlandjq.
Set the resource inputs:
export SERVICE_ID='<service-id>'
export BACKEND_ENDPOINT='https://api.example.com'
export GATEWAY_GROUP_ID='<gateway-group-id>'
Create an audited Configuration Plan​
Create an API-key-protected Plan with audit enabled. Keep the structured response only long enough to extract its ID and generated key:
CONFIG_JSON="$(
reshapr config create 'audited-endpoint-check' \
--serviceId "${SERVICE_ID}" \
--backendEndpoint "${BACKEND_ENDPOINT}" \
--apiKey \
--audit \
--output json
)"
export RESHAPR_CONFIG_ID="$(jq -er '.id' <<<"${CONFIG_JSON}")"
export RESHAPR_API_KEY="$(jq -er '.apiKey' <<<"${CONFIG_JSON}")"
unset CONFIG_JSON
The --audit option applies to every Exposition created from this Configuration Plan. It does not enable audit globally for other Plans.
Create a named Exposition and capture its ID:
export EXPOSITION_ID="$(
reshapr expo create \
--configuration "${RESHAPR_CONFIG_ID}" \
--gateway-group "${GATEWAY_GROUP_ID}" \
--name audited-endpoint-check \
--output json \
| jq -er '.id'
)"
reshapr expo get "${EXPOSITION_ID}"
export MCP_URL='https://<gateway-host>/mcp/<organization>/audited-endpoint-check'
Wait until the Exposition lists the expected Gateway endpoint before sending requests.
Generate audit events​
Send a successful discovery request with the generated key:
export MCP_DISCOVERY_REQUEST='{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"reshapr-audit-check","version":"0.2.3"},"io.modelcontextprotocol/clientCapabilities":{}}}}'
curl --fail --silent --show-error \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, text/event-stream' \
--header 'MCP-Protocol-Version: 2026-07-28' \
--header 'Mcp-Method: server/discover' \
--header "x-reshapr-key: ${RESHAPR_API_KEY}" \
--data "${MCP_DISCOVERY_REQUEST}" \
"${MCP_URL}" | jq '.result.supportedVersions'
Send the same request with an invalid key:
curl --silent --show-error --output /dev/null --write-out '%{http_code}\n' \
--header 'Content-Type: application/json' \
--header 'MCP-Protocol-Version: 2026-07-28' \
--header 'Mcp-Method: server/discover' \
--header 'x-reshapr-key: deliberately-invalid' \
--data "${MCP_DISCOVERY_REQUEST}" \
"${MCP_URL}"
The first request must return a JSON-RPC result and the second must return HTTP 401.
Inspect MCP call events​
Allow for Collector batching and export delay, then search the configured audit sink for log.type=audit and event.action=server/discover.
An MCP call event can contain:
| Attribute | Meaning |
|---|---|
log.type | Always audit for an audit record |
event.action | MCP method, such as server/discover or tools/call |
event.outcome | success or failure |
event.duration | Gateway call duration in milliseconds |
service.name, service.version | Service exposed through the Plan |
organization.id | Owning organization |
mcp.request.id | JSON-RPC request ID, when present |
mcp.session.id | MCP session ID for session-based protocols, when present |
mcp.target.name | Tool or Resource name, when applicable |
mcp.error.code | JSON-RPC error code for a failed call, when present |
mcp.response.size | Response size in bytes |
source.ip | Caller address, when available |
user.id | Authenticated JWT subject, when available |
trace.id | Active trace ID, when available |
The successful discovery request must have at least event.outcome=success, the Service and organization attributes, mcp.request.id, and event.duration.
Call one known read-only Tool from the same Exposition to produce event.action=tools/call. Use mcp.target.name, service.name, and trace.id when present to correlate its audit record with Gateway and backend spans.
Inspect authentication-failure events​
Search for log.type=audit, event.action=authentication, and the affected Service. Authentication-failure records can contain:
| Attribute | Meaning |
|---|---|
event.outcome | Always failure |
event.reason | Rejection reason, such as invalid_api_key, missing_bearer_token, invalid_token, or missing_scope |
http.response.status_code | HTTP rejection status |
service.id, service.name, service.version | Affected Service |
organization.id | Owning organization |
source.ip | Caller address, when available |
trace.id | Active trace ID, when available |
The rejected request in this guide must have event.reason=invalid_api_key and http.response.status_code=401.
Application logs explain runtime behavior, traces connect work across boundaries, and audit records answer which MCP action was attempted and with what outcome. Do not treat audit as a substitute for application diagnostics or distributed tracing.
Clean up​
Delete the temporary Exposition before its Configuration Plan:
reshapr expo delete "${EXPOSITION_ID}"
reshapr config delete "${RESHAPR_CONFIG_ID}"
unset RESHAPR_API_KEY MCP_DISCOVERY_REQUEST
Result​
The Configuration Plan enables audit for its Expositions, and the audit sink contains distinct successful-call and authentication-failure records marked with log.type=audit.
Limits​
- Audit must be enabled independently on every Configuration Plan that requires it.
- Audit records are emitted only when OpenTelemetry Logs are available and export succeeds.
- Optional identity, source, session, target, error, and trace attributes depend on the request and authentication mode.
- Audit records can contain identifiers and network metadata. Protect their transport, storage, access, retention, and deletion according to your security requirements.
- reShapr does not provide an audit database, SIEM, compliance policy, or immutable retention mechanism.
Next step​
Use Observe the reShapr Gateway to route records with log.type=audit to a dedicated sink. Use Security Capabilities and Limits to review endpoint authentication and audit boundaries.
The release-tagged audit implementation and public API contract remain the canonical references.