xenia
Xenia is a local MCP server for auditing and debugging how coding agents work on your machine.
Use
xenia_reportto view tasks, instructions, failure patterns, repeats, tool metrics, and disk writes, with filters for time, repo, agent, session, tool, status, and more.Use
xenia_callsto drill into the individual calls behind any report row, filtering by signature, tool, status, session, and other dimensions.Use
xenia_traceto see one action's full context, its task outcome, and every step between a failure and its fix.Group and sort results by signature, repo, agent, channel, environment, or cost metrics to surface waste and recurring failures.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@xenia show me failures in the last 24 hours"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
xenia
Xenia helps agents work better on your computer by providing a local MCP for them to:
check for repeated mistakes from agents on this computer
request actions requiring credentials without revealing the credentials to the agent
register work that may impact others so they can coordinate on it
It runs with a tray icon and gives you an overview page. Install and run on linux or mac with:
./bin/xeniaNeeds Python 3.11+
MCP tools
xenia_report
| One row is |
| What an agent set out to do, in its own words, and whether it got there. The label comes from its plan where it kept one and the outcome is read off the calls made under it. Ordered by what went wrong, not by the clock — pass |
| Something the user asked for, and how it turned out. |
| A kind of work that has failed more than once, worst first, grouped across sessions and repos — or, with |
| Work a session did again soon after it had already attempted the same thing. |
| Counts, failure rates, latency and reply size, per tool, broker, channel, host, repo or signature. |
| What was written, how often each file was rewritten, and how much of that hashed to what was already there. |
| Name of a credential the user has stored in a keychain that xenia can use |
| List of shared resource claims |
xenia_calls
Breaks a xenia_report row into its calls.
xenia_trace
The actions between an action_id failure and the fix, including how long it took.
xenia_claim
For posting, updating or releasing a claim on a resource.
| no | live work, held by a running session |
| ask | past the expiry but the holder is alive has not deregistered |
| yes | past the expiry and the owner is gone |
Arguments
since (24h, 7d, or a date)
repo (work outside any checkout is filed under general)
limit applies to every view. Every reply starts with now and now_local because the record is UTC and the logs it gets lined up against usually are not.
Where tool, via, channel, session and signature are accepted they match exactly or as a glob (via: "acme-*"), and a signature from any view drills straight into the calls behind that row.
See ARCHITECTURE.md.
Custom request signing can be supplied by an executable using the signing provider protocol.
Available Tools
3 toolsxenia_callsA
Individual calls, for the one question every xenia_report view raises and cannot answer: which call was that. A 'tools' row reporting a 33KB maximum does not say which call returned it, and one signature covering six journalctl runs is one row on purpose. Deliberately thin — action id, time, tool, status, duration, reply size and a short command, and nothing that repeats identically down the rows. Defaults to the heaviest replies first; pass the 'signature' or 'tool' from a report row to drill into it, and the 'action_id' it returns to xenia_trace. 'detail' is cut to 120 characters so a page of rows stays readable — xenia_trace on the same action id is where the whole command is, for any call and not only a failed one.
Inputs: via, kind, repo, tool, +9 more.
xenia_reportA
How coding agents have been getting on with their work on this machine. One record, six views of it — choose what a row should be with 'view':
tasks one unit of work an agent named for itself, and whether it got there: achieved, partial, failed, abandoned or no_action. The outcome is read off the calls made under the task, never off the agent's claim about it; where the two disagree 'overstated' is 1 and 'declared' is what the agent said. Start here. instructions the same question one level up: one thing the user asked for, and how it turned out. The only view that carries whole prompts, which is why the rest carry a 'goal_id' — pass one back as 'goal_id' for the full text of that instruction. failures one kind of work that keeps failing, worst first, grouped across sessions. 'repos' names the checkouts it failed in, because that is where a fix goes; 'previously' is the same count over the window before this one, so a row failing 8 times against 0 is new and one against 12 is already getting better. 'recovered' is how often a later call put it right; many failures and few recoveries is a gap in the environment or the instructions, and the most actionable row here. Refusals split by who did the refusing: 'refused_by_rule' is a hook or a permission rule, and the reason is in 'example_error' — a config or code fix; 'declined_by_user' is a person saying no at the prompt, which is not yours to change. Pass 'example_action_id' to xenia_trace. repeats one piece of work a session did again minutes after it had already succeeded. This is the waste 'failures' cannot show, since none of it failed. Cost it in 'repeated_bytes' rather than 'repeated_ms': redoing work is rarely slow, but every repeat puts its whole reply back into a context. tools one tool, broker, host, repo or signature, with calls, failure rate, latency and reply bytes. Ask this rather than totalling rows yourself; order by 'total_bytes' for what floods a context rather than what takes time. disk one file (or repo, tool, session) with what was written to it, how often it was rewritten, and how much of that hashed to what was already there — 'unchanged' is bytes that reached the drive and changed nothing.
Rows come back under 'rows'. The tasks view also returns 'instructions', the text of each instruction its rows sat under, keyed by 'goal_id' — one entry per instruction rather than the same sentence repeated down every row. 'since', 'repo' and 'limit' apply to every view; each other parameter names the views that read it, and passing one to a view that does not is an error rather than a filter that quietly does nothing. For the individual calls behind any row, take its 'signature' to xenia_calls.
Inputs: view (required), via, kind, path, +18 more.
xenia_traceA
One action, the task it was working towards, its outcome, and — when a later action fixed it — every action in between, from that one session. This is how a failure was actually recovered from. A fix in a later session gives the two endpoints only: the work between them belongs to two sessions and threading it into one list by clock time would not be a reading of anything. Takes ANY action id, not only a failed one: it is also the way to read one call's arguments in full, since xenia_calls shortens them to keep its rows scannable and a recovery series is simply absent when there was nothing to recover from.
Inputs: action_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
The three tools are clearly distinct: xenia_report provides aggregated views, xenia_calls provides individual call details, and xenia_trace provides a recovery trace. Each tool addresses a different level of analysis, with no overlapping purposes.
All tool names follow a consistent 'xenia_' prefix followed by a noun (report, calls, trace), forming a predictable pattern. The naming is uniform and intuitive.
With only 3 tools, the set is well-scoped for an observability server. Each tool earns its place, and the xenia_report tool consolidates multiple views without unnecessary fragmentation, keeping the surface focused.
The tool set covers the full observability workflow: aggregated reports (xenia_report), per-call inspection (xenia_calls), and detailed action tracing (xenia_trace). There are no obvious gaps, as the three tools enable a complete drill-down from summary to individual action.
Maintenance
Related MCP Connectors
AI agent observability for production traces, natural-language insights, and improvement loops.
AI agent run monitoring with incident replay and SLA receipts.
Evaluate agent workflows and LLMs on your own data: find wasted steps, pick models, catch drift.
Data + AI observability — monitor and troubleshoot production-grade agents and the context they use.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides observability for multi-agent workflows by tracking hierarchical task structure, architectural decisions, reasoning, encountered problems, code modifications with Git diffs, and temporal metrics.44 npmMIT
- AlicenseBqualityDmaintenanceEnables AI assistants to query and analyze AI agent sessions from observability providers like Shepherd (AIOBS) and Langfuse, allowing users to debug agent runs, compare sessions, track performance, and analyze LLM usage patterns.18MIT
- AlicenseNot gradedqualityFmaintenanceEnables comprehensive collection and analysis of ClaudeCode development sessions, including agent tracking, tool usage analytics, and performance metrics.MIT
- AlicenseNot gradedqualityDmaintenanceTracks and analyzes AI agent tool calls with event logging, dashboard, per-tool and per-agent analytics, and error monitoring.28 PyPIMIT