GreyCat Explorer
A web app to look inside a running GreyCat server: its graph, tasks, schedule, files, users,
logs and ABI, and how it performs over time. Any project that installs the library serves it at
/explorer/.
@library("explorer", "<version>");
Run greycat install, start the server, and open http://localhost:8080/explorer/. Sign in
with a user of the project.
Pages
| Page | Shows | Needs |
|---|---|---|
| Dashboard | Workers, the last hour, memory, the host, the schedule, the last deployment | debug for the server figures |
| Graph | Module variables, nodes and their values, functions to call | |
| Tasks | Running tasks and the history, with each task’s files and logs | |
| Performance | The server and every task over time, deployments, findings | debug |
| Scheduler | Periodic tasks, to pause or resume them | admin |
| Files | The files of the users you may read | |
| Users | Identities, their activity, roles, and who may open which folder | admin |
| Account | Your password, your activity, and who may open your folder | |
| Logs | The log stream, and error groups when the monitoring runs | admin |
| Abi | The types and functions of the program | |
| Settings | Server, theme, language, time zone, and the monitoring’s settings |
Performance monitoring
The library also ships GCL modules that read the server’s own log into time series. They stay
idle until the project starts them from its main:
fn main() {
explorer::Monitor::start();
}
Call it at every start, as the scheduler keeps its tasks in memory only. Host, task and HTTP
figures also need the server to record its metrics (http may be left out):
GREYCAT_METRICS=host,task,http greycat serve
Without them, only error groups and log levels are recorded.
What it records, from the streams of files/root/streams/ (log.ndjson, task_metrics.csv,
host_metrics.csv and http_metrics.csv):
- The host: CPU, memory, disk, store size and fragmentation, store reads against device reads, HTTP traffic, and the busy share, queue and memory of each worker class.
- Every task (endpoints, scheduled and spawned tasks,
awaitjobs): calls and failures, time on a worker and seen by the caller (p50, p95, p99), commit time, and the work of a call (blocks loaded, bytes read, memory against its worker’s budget, evictions, merge conflicts, caught exceptions). - Every HTTP request, grouped by route (a function called, a folder of user files, a top
folder of the pages): status classes, refusals, not found, cut-short exchanges, time to the
first and to the last byte, and bytes. Per user, the requests, refusals, and bytes downloaded
from and uploaded to
files/. The Explorer’s own requests are counted apart and left out unless asked for, except its calls toruntimefunctions, which a request does not tell apart from the application’s. - Deployments: a marker each time the runtime or the program version changes, and how each task fared under each one, the ten minutes after a restart left out.
- Errors, grouped by function, message and stack frame.
From these, the Performance page and the explorer::* endpoints tell which tasks got slower
after a deployment, and whether they do more work or run slower code, and they report sizing
findings: tasks that do not fit their worker, saturated worker classes, a disk filling up,
server errors and refusals over HTTP, and more.
Reading the figures takes the debug permission. Changing the settings and rebuilding the index
take admin.
Asking an LLM
The read endpoints are also MCP tools, so an LLM connected to the server can read the same
figures and reason over them: explorer.status, explorer.findings,
explorer.deployment_changes, explorer.deployments, explorer.task_by_deployment,
explorer.busiest_tasks, explorer.host_summary, explorer.top_errors,
explorer.http_traffic and, for an admin,
explorer.users. Their descriptions tell the model what each figure means, and their ranges
default to the last 24 hours. None of them changes anything.
GreyCat serves MCP over HTTP at the root of the server. Give the client a token of a user with the
debug permission in the Authorization header, with no Bearer prefix. A user without it sees
no tool.
To add the server to Claude Code, run this from the project directory while the server runs:
claude mcp add --transport http greycat http://localhost:8080/ \
--header "Authorization: $(greycat token --user=root --validity=24hour)"
--user names the user the token signs in as, and --validity how long it lasts (24hour,
30day). Once it expires, remove the server with claude mcp remove greycat and add it again.
claude mcp list shows the server as connected. The server is added for this project only:
Claude Code keeps it in ~/.claude.json under the project’s directory, so sessions started
elsewhere do not see it. Add --scope user to reach it from every project. The same server as a
--mcp-config file, for a one-off session or another client:
{
"mcpServers": {
"greycat": {
"type": "http",
"url": "http://localhost:8080/",
"headers": { "Authorization": "<token>" }
}
}
}
Any token of that user works, the one runtime::Identity::login returns included.
For coding agents, the library ships a skill, lib/explorer/skills/SKILL.md once installed, on
enabling the monitoring and reading its endpoints, regressions and findings.
Cost
The ingestion runs every minute as a scheduled task. Once it has caught up with the log, a run takes about a millisecond. On a server with a long log, the first runs read it 64 MB at a time.
Figures are kept by the minute for 7 days (30 for the host), then by the hour for a year. These durations are set in Settings. A task called every minute takes about 100 bytes of store per minute it runs.
Working on the Explorer
The app is built with Vite+ (vp) over @greycat/web, and the sample/ modules give it data
to show, including a workload that keeps the monitoring busy.
greycat install
greycat dev # serves on :8080 and rebuilds the pages, metrics on from .env
vp run codegen # after a .gcl change, regenerates project.d.ts
vp check # format, lint and types
greycat test # the GCL tests in test/
Sign in as root / root, which the sample sets up. CLAUDE.md holds the
conventions of the code base.