Observability
MCP requests appear in the same access logs, usage-event pipeline, and Prometheus metrics as model traffic. MCP-specific fields identify the JSON-RPC operation, called tool, discovery results, and tool-call outcome.
Use access logs to investigate individual requests, then use usage events and metrics to monitor tool-call traffic. Rate-limit and guardrail blocks appear in these signals. In AISIX Cloud, budget rejections appear there as well.
Access Logs
AISIX writes an access log after it finishes handling a request to /mcp or /mcp/{server}. Authentication failures occur before access logging. The standard fields provide the request's status, latency, caller API key ID, and request ID. The MCP-specific fields describe the operation:
| Field | When present | Value |
|---|---|---|
mcp_method | The body is a single JSON-RPC object with a method. | The method, such as initialize, tools/list, or tools/call, truncated to 256 bytes at a UTF-8 character boundary. AISIX records it even when an unsupported protocol version causes an early 400 response. |
mcp_tool | The method is tools/call and params.name is present. | The tool name as the client sent it, truncated to 256 bytes at a UTF-8 character boundary. |
tools_total | AISIX processes a tools/list request. | Number of tools returned by successfully queried upstream servers before access-policy filtering. The field is absent when an earlier check rejects the request. |
tools_returned | AISIX processes a tools/list request. | Number of tools returned to the caller after access-policy filtering. The field is absent when an earlier check rejects the request. |
Fields that AISIX cannot derive are omitted. For example, a batch or a body AISIX cannot parse has no mcp_method. Access logs never include tool arguments or results.
Diagnose an Empty Tool List
Compare the two tool counts and nearby warnings when tools/list returns no tools:
| What you see | Likely cause | What to check |
|---|---|---|
tools_total is greater than zero, tools_returned is zero, and a warning says no MCP access policy or key-level grant applies. | The caller has no access grant. | Add an access grant for the caller. |
tools_total is greater than zero, tools_returned is zero, and a warning says exclude every upstream tool. | A grant exists but filters out every discovered tool. | Correct the applicable allow, deny, or anonymous allowlist. |
A warning says skipping upstream in tools/list: list_tools failed. | The named upstream failed, but AISIX continued with the others. Its tools are excluded from both counts. | Check that server's reachability, authentication, and protocol configuration. |
| Both counts are zero and there is no upstream-failure warning. | No successfully queried upstream returned a tool. | Check that at least one upstream is enabled and exposes tools. |
For log collection, standard fields, and request-ID correlation, see Access Logs and Request Correlation.
Usage Events
Whether a tools/call request produces a usage event depends on how far AISIX processes it:
| Outcome | Usage event |
|---|---|
AISIX rejects the request before tool-call accounting, such as for failed authentication, an unknown scoped server, an unreadable or oversized body, invalid JSON, a params shape AISIX cannot parse, or an unsupported protocol version. | Not emitted. |
| The request reaches tool-call accounting. | Emitted even when params or the tool name is missing, or when access control, a rate limit, a guardrail, an AISIX Cloud budget, or the MCP protocol handler later rejects the call. |
A failure while AISIX reads or buffers the MCP response body can return before the event is emitted. Usage telemetry therefore covers the recognized outcomes above, not every recognized tool call. Handshake and discovery methods do not produce usage events.
The event identifies the caller, server, tool, outcome, and timing:
| Field | Value |
|---|---|
inbound_protocol | mcp |
mcp_server_name | The registered server the tool belongs to. |
mcp_tool_name | The upstream tool that was called. |
api_key_id | The caller API key that made the call. |
status_code | The call's outcome status. |
upstream_latency_ms | Time spent on the upstream tool call. |
downstream_latency_ms | Total time the caller waited for the tool call. |
guardrail_blocked | true when a guardrail blocked the call's input or output. |
request_id, occurred_at | Correlation id and timestamp. |
MCP tool calls do not carry model tokens, so token and cost fields remain zero. Use mcp_server_name and mcp_tool_name for per-tool call-volume attribution rather than token or spend analytics.
MCP currently makes a single upstream attempt that spans the request, so upstream_latency_ms and downstream_latency_ms report the same duration. The separate fields keep MCP records consistent with other gateway traffic, where retries and gateway processing can make the two values differ.
Base usage events do not include tool arguments or results. With full content capture, a tools/call that passes traffic-control and input-guardrail checks can export params.arguments after any data masking. If the response contains a JSON-RPC result, the exporter can capture that too. An output-guardrail block suppresses both fields, and other MCP methods are not captured. See Configure Content Capture.
MCP usage events follow the same delivery paths as model usage events. Any configured observability exporter receives them, so MCP traffic appears alongside the rest of your gateway traffic. In AISIX Cloud, they also flow to the control plane's usage sink.
Metrics
MCP requests appear in the gateway's Prometheus metrics with labels that distinguish them from model traffic. Use the labels below to filter the relevant metric series:
| Goal | Metric | Filter |
|---|---|---|
| Track active MCP requests. | aisix_proxy_in_flight_requests | inbound_protocol="mcp" |
| Check MCP usage-event emission. | aisix_usage_events_emitted_total | handler="mcp" and inbound_protocol="mcp" |
Metrics are exposed on GET /metrics through the dedicated metrics listener. For the full metric catalog and label semantics, see Metrics Reference.
Verify Metrics
To verify that MCP metrics are emitted, send one MCP tool call through the gateway, then scrape the dedicated metrics listener. The example below uses the default listener address and path. If your startup configuration sets a different observability.metrics.prometheus.addr, use that address instead.
Metric families register on first observation, so the MCP series appears only after a tool call is recorded:
curl -sS "http://127.0.0.1:9090/metrics" | grep 'inbound_protocol="mcp"'
The output should include metric samples with these labels:
| Metric | Label |
|---|---|
aisix_proxy_in_flight_requests | inbound_protocol="mcp" |
aisix_usage_events_emitted_total | handler="mcp" and inbound_protocol="mcp" |
Next Steps
You now know how to diagnose MCP requests in access logs and where tool calls appear in usage events and metrics. Use these guides to review the full metric catalog or adjust the traffic that produces those signals:
- Metrics Reference: review the full metric catalog and label semantics.
- Rate limits and budgets: apply request and concurrency limits, and configure AISIX Cloud budgets for MCP tool calls.
- Guardrails: inspect MCP tool arguments and results.