Query production logs from Claude Code or Cursor
Your AI coding assistant can read your code, but it cannot see what that code is doing in production. So you copy log lines and stack traces into the chat by hand. ZipLogger runs an MCP (Model Context Protocol) server, so the assistant can search your logs and traces itself.
This post covers the connection config for Claude Code and Cursor, the tools the server exposes, and what it cannot do.
The server
- URL:
https://app.ziplogger.ai/mcp - Transport: Streamable HTTP. In Claude Code and Cursor config this is the
httptype. - Auth: OAuth, or an API key in the
X-Api-Keyheader. - Access: read-only. No tool can change or delete anything.
Every request is scoped to one workspace, taken from the OAuth token or the API key, and to one environment. An API key reads only its own environment. An OAuth connection starts in the default environment, and each tool takes an optional environment argument; list_environments lists them.
The tools
The server exposes seven tools, all read-only:
| Tool | What it returns |
|---|---|
list_environments | The workspace's environments, for choosing one over OAuth |
search_logs | The newest log lines matching a query, up to 100 per call |
list_error_patterns | Recent error logs grouped into templates, with counts and an example |
list_traces | Recent traces, one row per request or job, optionally only failing ones |
get_trace | One trace's full waterfall: spans, parents, durations, status, attributes |
get_services_status | Every service seen in the last 24 hours, its errors in the last 15 minutes, and health-check results |
list_regressions | Errors traced back to a suspect commit, with author, confidence and the AI root cause when analyzed |
search_logs uses the same query syntax as the Search page: plain words, "quoted phrases", field:value filters like severity:error, source:checkout-api or fields.userId:123, AND/OR/NOT, and wildcards. Most tools take an hours argument for how far back to look. The default is 24.
You do not call these yourself. The assistant reads the tool descriptions and picks.
Pick an auth method
OAuth is the easier one for a person at a keyboard. You add the URL with no key. On first use the assistant opens a ZipLogger page titled "Connect to ZipLogger". You sign in with your ZipLogger email and password and click Approve read-only access. Signing in there does not start a browser session. It only authorizes that assistant.
An API key is for setups where nobody can click through a browser page, like a CI job or a shared dev container. The key has to be allowed to read. Keys are ingest-only by default, and an ingest-only key is refused by the MCP server, because ingest keys end up in browser bundles where anyone can see them.
To make a read key, go to Settings → API keys (you need the Admin role), enter a name, tick Can read data, and click Create key. The key is shown once. Treat it like a password.
Claude Code
With OAuth:
claude mcp add --transport http --scope user ziplogger https://app.ziplogger.ai/mcp
Then start Claude Code, run /mcp, pick ziplogger and sign in when the browser opens. The consent page shows an extra warning that the redirect goes to an application on your own computer. That is expected for Claude Code, which receives the login on localhost.
With an API key:
claude mcp add --transport http --scope user ziplogger https://app.ziplogger.ai/mcp \
--header "X-Api-Key: YOUR_API_KEY"
--scope user registers the server for every project. Without it, the server is only added to the directory you ran the command from. Check it with claude mcp list. Servers connect when a session starts, so restart Claude Code before the tools show up.
If you want the server in a project's .mcp.json so the whole team gets it, keep the key out of the file. Claude Code expands environment variables in .mcp.json:
{
"mcpServers": {
"ziplogger": {
"type": "http",
"url": "https://app.ziplogger.ai/mcp",
"headers": { "X-Api-Key": "${ZIPLOGGER_API_KEY}" }
}
}
}
Each developer sets ZIPLOGGER_API_KEY in their own shell. Or leave out headers and everyone connects with OAuth under their own account.
Cursor
Cursor reads MCP servers from ~/.cursor/mcp.json (every project) or .cursor/mcp.json (one repository):
{
"mcpServers": {
"ziplogger": {
"url": "https://app.ziplogger.ai/mcp",
"headers": { "X-Api-Key": "YOUR_API_KEY" }
}
}
}
That file holds the key in plain text. Use the home-directory file, not the one inside the repository. A committed .cursor/mcp.json gives your workspace key to everyone who can read the repo. If a key leaks, revoke it under Settings → API keys.
Other MCP clients
Any client that speaks Streamable HTTP works with the same URL. Clients that support MCP OAuth find the login on their own: an unauthenticated request gets a 401 with a WWW-Authenticate header that points at the server's OAuth metadata. In Claude on the web or desktop, add it under Settings → Connectors → Add custom connector.
What to ask
These are the kinds of questions the tools are built for. The tool calls are what a typical assistant makes. It decides the order itself, and it may make more or fewer calls.
"What's breaking in my services right now? Cluster the errors and show me the top patterns from the last 24 hours."
The assistant calls list_error_patterns, maybe after get_services_status to see which services are unhealthy. The result is a short list of templates instead of hundreds of raw lines:
{
"errorPatterns": [
{
"pattern": "Payment declined for order <*> by <*>",
"count": 2,
"firstSeen": "...",
"lastSeen": "...",
"example": {
"message": "Payment declined for order 83140 by adyen",
"source": "...",
"release": "...",
"traceId": "...",
"stackTrace": "..."
}
}
]
}
That is the real shape of the response, with values cut. The <*> parts are where the lines differed. Log pattern clustering, explained with real output shows how the grouping works.
"Find the slowest failing request in the checkout service and walk me through its trace waterfall."
list_traces with only failing traces and the service name, then get_trace with the trace id it picked. The waterfall comes back as spans in start order with durations and status, so the assistant can point at the slow or failing span. If your logs carry trace ids, it can also go the other way: find an error with search_logs and pass its traceId to get_trace. OpenTelemetry traces over OTLP covers getting traces in.
"Were any recent production errors traced back to a specific commit? Who authored it and what's the suggested fix?"
list_regressions. This only returns something if you have connected a repository and regression analysis has run on your errors. See Find the commit that broke production.
The useful part is that the assistant has your code open at the same time. It can read the stack trace from search_logs, open the file it names, and suggest a fix in the same session.
Limits
- Read-only. The assistant cannot hide logs, change alerts or resolve anything through MCP.
list_error_patternsworks on a sample. It reads up to 3,000 lines at severityerrorin the time range and clusters those, so its counts are counts within that sample. Lines logged asfatalare not included.- Result sizes are capped.
search_logsreturns at most 100 lines per call and looks back at most 90 days.list_tracesreturns up to 50 traces.get_tracereturns up to 500 spans and shortens long attribute values.list_regressionsreturns the 25 most recent cases. Stack traces in log results are cut at 1,500 characters. - Tool calls count as API requests on your plan, the same as other programmatic access with a key.
- There is no page to list or revoke OAuth connections yet. An OAuth access token lasts 60 minutes and is refreshed for up to 30 days. If you need to cut off access on demand, use a read key, which you can revoke under Settings → API keys straight away.
- Your data goes to the assistant's model. Tool results land in the assistant's context, so log lines, trace attributes and stack traces are sent to whichever model the assistant uses. Keep secrets and personal data out of your logs for this reason as much as any other.
The full setup, with the same commands, is in the MCP section of the docs. If you do not have a workspace yet, sign up, send some logs, and then connect your assistant.