Apoxy

MCP Server

Model Context Protocol server reference for querying proxy logs with AI assistants.

Apoxy exposes an MCP server that lets AI assistants query your Envoy proxy access logs using PRQL. Any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.) can connect and use the tools described below.

For Claude Code users, the Apoxy Claude plugin provides the MCP connection plus a skill that teaches Claude effective query patterns. See the integration guide for setup instructions.

Endpoint

https://api.apoxy.dev/mcp

The server uses the StreamableHTTP transport.

Authentication

All requests require a Bearer token in the Authorization header:

Authorization: Bearer <api-key>

To create an API key, open the Apoxy console, click your avatar, go to Account Settings > API Keys, and create a new key. Keys are scoped to your project. You can have multiple active keys and set expiration dates.

Requests without a valid token receive 401 Unauthorized.

Tools

describe_schema

List all available log fields, their types, sources, and descriptions. Call this first to discover what you can query.

Parameters: None.

Response fields:

FieldTypeDescription
namestringField name to use in PRQL queries (e.g., http.response.status_code).
typestringOne of string, integer, float, uuid, timestamp.
sourcestringWhere the field lives: LogAttributes, ResourceAttributes, or empty for top-level columns.
descriptionstringHuman-readable description.

query

Execute a PRQL query against your proxy access logs.

Parameters:

ParameterTypeRequiredDescription
prqlstringYesPRQL query string. The table source is implicit — start with filter, select, derive, group, sort, or take.
start_timestringNoStart of time range (RFC 3339). Defaults to 24 hours ago.
end_timestringNoEnd of time range (RFC 3339). Defaults to now.
cursorstringNoPagination cursor from a previous response. Both start_time and end_time are required when using a cursor.

Queries without take default to 1000 rows. The maximum is 10000 rows. Use cursor pagination for larger result sets.

Response fields:

FieldTypeDescription
rowsarrayResult rows, each containing a fields map of column name to value.
columnsarrayColumn metadata (name, type) for each column in the result.
next_cursorstringPagination cursor. Empty if no more results.
total_rowsintegerNumber of rows returned in this page.
compiled_sqlstringThe SQL that was executed (useful for debugging).

Log fields

The logs are Envoy access log entries collected via OpenTelemetry. Fields fall into three categories:

Top-level columns — Standard OpenTelemetry log fields:

FieldTypeDescription
TimestamptimestampEvent timestamp (DateTime64).
TimestampTimetimestampTruncated timestamp (DateTime), useful for grouping.
BodystringLog message body.
ServiceNamestringService name.
SeverityTextstringLog severity text.
SeverityNumberintegerLog severity number (UInt8).
TraceIdstringTrace correlation ID.
SpanIdstringSpan correlation ID.
TraceFlagsintegerTrace flags (UInt8).
EventNamestringEvent name.

LogAttributes — Envoy access log fields (use backtick-quoted names in PRQL):

FieldTypeDescription
`http.request.method`stringHTTP request method.
`http.response.status_code`integerHTTP response status code.
`url.path`stringRequest URL path.
`client.address`stringClient IP:port.
`upstream.address`stringUpstream host address.
`upstream.cluster`stringEnvoy upstream cluster name.
`http.request.duration_ms`floatRequest duration in milliseconds.
`http.request.body.size`integerRequest body bytes.
`http.response.body.size`integerResponse body bytes.
`http.request.id`uuidRequest UUID.
`user_agent.original`stringUser-Agent header.
`network.protocol.name`stringProtocol (HTTP/1.1, HTTP/2).
`url.host`stringRequest host header.
`envoy.response_flags`stringEnvoy response flags.

ResourceAttributes — Infrastructure metadata:

FieldTypeDescription
`cluster_name`stringCluster identifier.
`log_name`stringLog source name.
`project_id`uuidProject UUID.
`node_name`stringNode UUID.
`service.name`stringService name.
`zone_name`stringZone identifier.

Additional fields may be discovered dynamically from the data. Use describe_schema to see the current full list.

How field rewriting works

Log attribute and resource attribute fields are stored as strings internally. The query engine automatically rewrites backtick-quoted field names to the appropriate storage-level access expressions and aliases them back to clean names in your results:

  • `url.path` → accessed from log attributes, returned as url.path
  • `cluster_name` → accessed from resource attributes, returned as cluster_name

Integer and float fields are automatically cast to their numeric types, so you can use numeric comparisons and aggregations directly. String literals in filter expressions (e.g., "/api/users") are left untouched.

The engine also injects WHERE conditions for project filtering and time range automatically — these appear in compiled_sql but don't need to be written in your query.

PRQL quick reference

Queries are pipelines of transforms. The table source is implicit — start directly with transforms.

# Filter 5xx errors in the last hour
filter `http.response.status_code` >= 500
select {Timestamp, `url.path`, `http.response.status_code`}
sort {-Timestamp}
# Count requests by status code
group {`http.response.status_code`} (aggregate {count = count this})
# Compute a derived column
derive {is_error = `http.response.status_code` >= 400}
select {Timestamp, `url.path`, is_error}
# Limit results
sort {-Timestamp}
take 10

See the PRQL language reference for the full syntax.

Rate limits

Rate limits apply per project. Contact support if you need higher limits.

On this page