Claude Code and MCP
There are two ways to use the Monitor Protocol from Claude Code. They do different jobs, and you can use both.
| Use | What it gives you |
|---|---|
| The MCP server | Tools to create monitors, publish, subscribe, pull and acknowledge, from Claude Code or any other MCP client |
The watch command inside a Monitor |
A live feed of one subscription in a session, one line per observation, that never loses its place |
Add the MCP server
claude mcp add -s user monitor-protocol -- npx -y @mentu/monitor-protocol mcp --state ~/.monitor-protocol/mcp-state.json-s user makes the server available in every project. The MCP server runs its own monitor server over standard input and output, and keeps its monitors and subscriptions in the --state file.
For other MCP clients, add it to the client's configuration file:
{
"mcpServers": {
"monitor-protocol": {
"command": "npx",
"args": ["-y", "@mentu/monitor-protocol@latest", "mcp", "--state", "~/.monitor-protocol/mcp-state.json"]
}
}
}Version 0.1.2 and newer expand a leading ~ in --state. With an older version, write the full path, because a JSON configuration does not go through a shell.
Each server writes its state file on its own. Do not point an mcp server and a serve server at the same file at the same time. Give each one its own file.
To see the tools a model will get, without starting anything:
npx @mentu/monitor-protocol toolsThe tools
| Tool | What it does |
|---|---|
monitor_discover |
Protocol version, capabilities, limits and server identity |
monitor_list |
The monitors you can see. Private ones need their owner token. |
monitor_get |
One monitor's definition |
monitor_create |
Create a monitor. The reply carries the owner token once. |
monitor_configure |
Update, pause, resume or retire a monitor. The change is recorded as an observation, with its reason. |
monitor_publish |
Publish one observation. An agent working for the monitor's owner names them in on_behalf_of. |
monitor_state |
The computed state, with its missing inputs and gaps |
monitor_subscribe |
Create a subscription with its own cursor. The reply carries the token once. |
monitor_pull |
Read observations after the cursor. It does not move the cursor. |
monitor_ack |
Commit the cursor after handling what you read. It never moves backwards. |
lease_claim |
Take an exclusive, time-limited lease on one piece of work. One holder wins. |
lease_complete |
Finish the work and release the lease, citing the evidence |
lease_release |
Give the work back without finishing it, with a reason |
The server also exposes two resources per visible monitor, monitor://<id>/definition and monitor://<id>/state. When a monitor records something new, the server sends a resource update notification for its state. Treat that notification as a doorbell: it tells a client to look, and the subscription's cursor is what guarantees nothing is missed.
The protocol's MCP extension is named ai.mentu/monitors. Until MCP SDKs carry the extensions capability, the server announces it under experimental.
Follow a subscription from a session
The Monitor tool runs a command in the background and turns each line it prints into a message for the session. The watch command is made for it: it follows one subscription on a running serve server and prints one line per observation.
First create a subscription, as in the quickstart, and note its id and token. Then ask Claude Code to start a Monitor with this command:
Monitor(command: "npx -y @mentu/monitor-protocol watch --base http://localhost:8130 --subscription sub-8f2a91c0 --token $READER_TOKEN --catch-up")What the session sees:
- With
--catch-up, the backlog is printed first as context, without acknowledging it. - Then each observation is printed as a line starting with
OBS, and each batch is acknowledged once its lines are printed. - When nothing arrives for a while, a
HEADline reports the log's head and how much is waiting. - If the server stops answering, a
DOWNline says so once. The watch waits, one second at first and at most ten, and printsUPwhen the server is back. Nothing is lost while it waits.
A Monitor runs for thirty minutes at most. When it ends, start it again with the same command. The subscription kept its place, so the new watch starts exactly where the old one stopped.
| Flag | What it does |
|---|---|
--catch-up |
Print what is waiting before following new observations |
--wait 25 |
How long each pull waits for something new, in seconds |
--limit 50 |
The most observations per pull |
--once |
Pull one batch and exit |
Let an agent act for you
When an agent publishes for a person, it names that person in on_behalf_of. The person must be the monitor's owner. Called through MCP, the arguments look like this:
{
"id": "ci",
"bearer": "<owner token>",
"type": "com.example.ci.review",
"subject": "release-0.1.2",
"actor": "agent:claude",
"on_behalf_of": "human:you",
"origin": "human",
"tier": "src",
"data": { "status": "approved" }
}The observation keeps both names: agent:claude saw it, for human:you. If the agent names anyone other than the owner, the call is refused with PROVENANCE_CEILING, and the refusal is recorded. Agents acting for people explains the whole rule.