The Claude Code Monitor tool idea, taken out of the session and made durable, shareable and accountable.
Read the documentation · Try it in your browser · Quickstart · Package on npm
The Claude Code Monitor tool has the right instinct. You point it at something, it watches, and it tells you when something happens.
Its limits come from where it lives. It stops when the session stops. It runs for thirty minutes at most. Only the session that started it can see it. And it remembers nothing. So every session starts its own watches again, and whatever happened in between is gone.
The Monitor Protocol keeps the instinct and removes those limits. A monitor becomes something that exists on its own. Many people and agents can subscribe to it. It remembers what it saw. And an AI can set it up or change it through a defined interface, instead of editing a script.
There are five parts, and each one is small.
- A monitor is a definition: what is watched, how often, and with what authority.
- An observation is one thing the monitor saw. Each one says where it came from, who caused it, and how much it is worth believing.
- A state is the monitor's running summary, computed from its observations. It says out loud what it does not know, instead of filling the gap with a number.
- A subscription is a reader with its own place in the stream, called its cursor. It reads, does the work, and only then acknowledges. A reader that crashes gets the same items again instead of losing them.
- A lease is how two workers avoid doing the same job twice. It expires on its own if the worker holding it stops.
Configuration is not a sixth part. Pausing a monitor, changing its filter or retiring it is recorded as an observation too. Six months later, the question "why did this change?" has an answer.
A queue moves messages and forgets them. The Monitor Protocol keeps them as evidence.
A machine cannot claim a person's level of certainty. Every observation carries a rating, from src (a person checked it against the source) down to falsified (checked, and found untrue). A program can report what it measured. The top of the ladder needs a person behind the observation. An agent working for you reaches your level by naming you in one field, on_behalf_of, and the record keeps both names: the agent that saw it, and the person it worked for. It can only name the person who owns the monitor, so it cannot borrow anyone else's level. Anything that tries to climb higher is refused, and the refusal is kept as an observation.
An independent audit showed that the first version of this check could be fooled, because it read its answer from the same request it was judging. It is now enforced, and the conformance suite tests it from five different angles.
It does not lie by leaving things out. A confidence with a missing input lists the input as missing. A source that did not answer is reported as not answering, never as zero. The count of waiting items covers only what this reader would actually receive, so it can reach zero.
The fastest way is the playground: the real engine runs in your browser, and nothing leaves the page.
To run it yourself, you need Node.js 20 or newer. Start a server:
npx @mentu/monitor-protocol serve --port 8130Then, in use, it is four steps:
# 1. Define what is watched. The reply includes an owner token, shown once. Keep it.
curl -s localhost:8130/mp/v0/monitors \
-d '{"id":"ci","name":"CI","horizon":"minute","capabilities":["observe"],"visibility":"public","types":["com.example.ci.run"]}'
# 2. A producer records what it saw, using the owner token.
curl -s localhost:8130/mp/v0/monitors/ci/observations -H "Authorization: Bearer $OWNER_TOKEN" \
-d '{"type":"com.example.ci.run","subject":"build-412","actor":"probe:ci","tier":"measured","origin":"probe","data":{"status":"failed"}}'
# 3. A reader subscribes once, then takes what it has not seen yet.
curl -s localhost:8130/mp/v0/subscriptions -d '{"monitor":"ci","subscriber":"agent:claude","capabilities":["observe"]}'
curl -s "localhost:8130/mp/v0/subscriptions/$SUBSCRIPTION/pull" -H "Authorization: Bearer $READER_TOKEN"
# 4. It commits only after handling it. Send the "next" value from the pull reply.
curl -s localhost:8130/mp/v0/subscriptions/$SUBSCRIPTION/ack -H "Authorization: Bearer $READER_TOKEN" -d '{"cursor": 3}'Reading never moves the cursor. Only an acknowledgement does, and it never moves backwards. The quickstart walks through each reply.
From Claude Code, it is one watch per session against the monitor server, instead of one per thing. From any AI client, it is a set of tools over the Model Context Protocol (MCP).
Add it to Claude Code as an MCP server. It runs its own monitor server, so give it its own state file:
claude mcp add -s user monitor-protocol -- npx -y @mentu/monitor-protocol mcp --state ~/.monitor-protocol/mcp-state.jsonOr follow a subscription from a session with the Monitor tool:
Monitor(command: "npx -y @mentu/monitor-protocol watch --base http://localhost:8130 --subscription <id> --token <token> --catch-up")
The watch prints one line per observation and acknowledges each batch after printing it. When the Monitor's time runs out, start it again. The subscription remembers its place, so nothing is missed. If the server restarts, the watch prints DOWN, waits, and carries on when the server is back. The guide Claude Code and MCP covers both, and the tools.
A monitor server usually runs next to a web browser, so it assumes every web page you open can reach it.
- A web page is not you. Requests from a browser page are refused unless you allow that page with
--allow-origin. Command line tools are unaffected. - Nothing reaches it through a borrowed name. On your own machine it only answers to
localhost,127.0.0.1and::1, which stops DNS rebinding. - One request cannot exhaust it. Request bodies over 1 MiB are refused.
- Your state survives a bad day. Each write is flushed to disk before it replaces the last, the previous copy is kept, and a damaged file is set aside instead of overwritten.
- Only one server writes a state file. A second one refuses to start and says which process holds it.
- What is the Monitor Protocol?
- Introducing the Monitor Protocol: why we built it, and how it works
- Agents acting for people: the trust rules in plain words
- Concepts and Reference
- The fourteen principles, each one learned from something that went wrong in a running system
| Folder | What it holds |
|---|---|
spec/ |
The specification: principles, objects, methods, bindings, delivery and the conformance checklist |
schemas/ |
A JSON Schema for every object. Where the prose and a schema disagree, the schema wins. |
src/ |
The reference server, the command line tool, the MCP server and a client, in TypeScript |
conformance/ |
The conformance suite in Python, next to the TypeScript one in src/ |
adapters/ |
Known implementations, and what each one taught the specification |
docs/ |
Why each design choice was made, including a running decision log |
Read the principles, implement the five objects over HTTP, and run the conformance suite against your server:
npx @mentu/monitor-protocol conform --base http://127.0.0.1:8124
python3 conformance/python/run.py --base http://127.0.0.1:8124 --subjects a,b,cThe suite has 31 checks. The reference server in this repository passes all of them. Atrio, an event log, is the second implementation; it keeps everything, so the check that needs old entries deleted is skipped there.
To use the reference server as a library:
import { MemoryStore, MonitorService, createHttpServer, MonitorClient } from "@mentu/monitor-protocol";
const service = new MonitorService(new MemoryStore("state.json"));Version 0.1, published on npm. The objects and methods are stable enough to build on. Names such as the ai.mentu prefix may still change before version 1.0, and every change is listed in the changelog. Contributions are welcome: see CONTRIBUTING.md.