Skip to main content
Glama
mentu-ai

monitor-protocol

Official
by mentu-ai

Monitor Protocol

npm version Node.js License CI

An epistemic layer over pub/sub. A monitor is an enduring daemon that observes something and emits evidence with provenance. It keeps a computed state that says what it knows and what it does not. People, AI sessions and other monitors subscribe with a durable cursor, acknowledge after processing, and may take exclusive leases to act. AI clients can configure monitors under declared capabilities. The daemon never performs inference.

This protocol does not invent transport, envelope, filter or delivery. It adopts them and owns only the epistemic objects and rules:

Concern

Adopted from

What this protocol adds

Event envelope

CloudEvents 1.0 JSON + HTTP binding

extension attributes sequence, tier, origin, verified, horizon, actor

Door for AI hosts

MCP 2026-07-28, as extension ai.mentu/monitors

tools, monitor:// resources, best-effort wake-up over resources/updated

Filter grammar

Nostr NIP-01 filter object

keys for tier, origin, horizon; #tag matching

Delivery

Kafka consumer offsets · Kubernetes watch + Lease

cursor never backwards, ack after processing, relist from state when compacted

Provenance

W3C PROV-DM terms

a tier ladder a machine cannot inflate

producers ──publish──► MONITOR log ──► STATE (computed, gaps as properties)
                          │
                          ├── SUBSCRIPTION (cursor, ack, lease) ◄── person / AI session / another monitor
                          └── wake-ups: MCP resources/updated · SSE · Claude Code Monitor arm

Quick start

Requires Node.js 20 or newer.

npx @mentu/monitor-protocol@latest serve --port 8130 --state ~/.monitor-protocol/state.json

Create a monitor, publish an observation, subscribe and pull:

curl -s localhost:8130/mp/v0/monitors -d '{"id":"ci","name":"CI watch","horizon":"minute","capabilities":["observe","act"],"visibility":"public","types":["com.example.ci.run"]}'
# → {"monitor":{…},"owner_token":"…"}   (shown once)
curl -s localhost:8130/mp/v0/monitors/ci/observations -H "Authorization: Bearer $OWNER" \
  -d '{"type":"com.example.ci.run","subject":"build-412","tier":"measured","origin":"probe","data":{"status":"failed"}}'
curl -s localhost:8130/mp/v0/subscriptions -d '{"monitor":"ci","subscriber":"agent:claude@ab12cd34","capabilities":["observe"]}'
# → {"subscription":{"id":"sub-…","cursor":0},"token":"…"}
curl -s "localhost:8130/mp/v0/subscriptions/sub-…/pull?wait=25" -H "Authorization: Bearer $TOKEN"
curl -s localhost:8130/mp/v0/subscriptions/sub-…/ack -H "Authorization: Bearer $TOKEN" -d '{"cursor":2}'

pull never advances the cursor; ack does, after processing, and never backwards. A pull after a crash redelivers with redelivered: true. That is the guarantee: at-least-once, in Kafka's words.

From Claude Code

One Monitor arm per session against the hub, instead of one watch per thing:

Monitor(command: "npx -y @mentu/monitor-protocol watch --base http://localhost:8130 --subscription sub-… --token $TOKEN --catch-up")

The loop prints the backlog first without acking, then one line per observation, acking after each line. Re-arm at the Monitor tool's 30-minute deadline; the cursor guarantees nothing was lost.

As an MCP server

{ "mcpServers": { "monitor-protocol": { "command": "npx", "args": ["-y", "@mentu/monitor-protocol@latest", "mcp", "--state", "~/.monitor-protocol/state.json"] } } }

Inspect the model-facing surface before configuring a client, exactly as MetaMCP does:

npx @mentu/monitor-protocol@latest tools
npx @mentu/monitor-protocol@latest tools --json

Related MCP server: AgentCloud MCP Server

The rules this protocol owns

Fourteen principles, each paid for by an incident in a running system: spec/00-principles.md. The ones people ask about first:

  • A machine cannot assert the top provenance tier. origin: agent with tier: src is refused, and the refusal is itself an observation.

  • State says what it does not know. A confidence with a missing input lists the input as missing; it is never defaulted to a number.

  • Delivery is a queue, not a notification. Wake-ups (MCP, SSE, a Claude Code Monitor) may be lost; the cursor may not.

  • Registration is not consumption. A subscription that never pulls is retired, with a will event, and keeps its cursor for when it returns.

  • Authority is an attribute of the horizon. A minute-level monitor observes and reacts; only a slower process writes beliefs or promotes rules.

  • The daemon never infers. Judgment happens in a subscribed interactive session.

Specification

Part

Content

spec/00-principles.md

P1–P14

spec/01-objects.md

Monitor · Observation (a CloudEvent) · State · Subscription · Configure · the Filter grammar

spec/02-methods.md

JSON-RPC methods, REST binding, error codes and their HTTP mapping

spec/03-bindings.md

CloudEvents, MCP extension, Claude Code Monitor, HTTP push, Nostr relay

spec/04-delivery.md

at-least-once, cursor, redelivery, leases, retention, retirement

spec/05-conformance.md

C01–C21 and the two runners

schemas/

JSON Schema 2020-12 for every object

docs/prior-art.md, docs/delivery-semantics.md, docs/decisions.md

why each binding was chosen

Conformance

npx @mentu/monitor-protocol@latest conform --self          # this package against itself
npx @mentu/monitor-protocol@latest conform --base http://127.0.0.1:8124   # any implementation
python3 conformance/python/run.py --base http://127.0.0.1:8124 --subjects a,b,c   # language-independent runner

Two implementations pass today: this reference server (22/22) and Atrio's bus (21 PASS, 1 SKIP — it retains everything, so cursor expiry is not exercisable). The Python runner was written against the second and passes unmodified against the first. See adapters/.

Library use

import { MemoryStore, MonitorService, createHttpServer, MonitorClient } from "@mentu/monitor-protocol";
const service = new MonitorService(new MemoryStore("state.json"));

Status

v0.1.0 — first public cut, 2026-09-21. The objects and methods are stable enough to implement against; the vendor prefix ai.mentu and the CloudEvents extension attribute names may still change before 1.0 and will be listed in CHANGELOG.md. Contributions: see CONTRIBUTING.md.

Related MCP Connectors

Related MCP Servers