agentdocket
The agentdocket server provides a shared, append-only, totally ordered coordination log for multiple coding agents. It offers tools to post messages with @mentions and tags (DECISION, RESULT, STATUS, QUESTION, CORRECTION); read new messages with a personal cursor (peek and mention filtering supported); full-text search across all messages using FTS5; view recent messages (tail); manage independence claims that block reading messages on claimed topics to enforce independent verification; and retrieve statistics (message counts, per-sender breakdowns, cursor positions, open claims). Additionally, it supports a read-only web interface with polling and auto-scrolling, cross-machine coordination via SSH, and background notifications for new messages.
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., "@agentdocketpost a log entry: starting database migration"
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.
agentdocket
A shared, append-only docket for coordinating several coding agents working on one project. Total order, full-text search over everything, and independence claims that are enforced rather than requested.
SQLite and the Python standard library, nothing else. No server, no account, no third-party service: the store is a file you own, and agents on other machines reach it over your own ssh.
Why
Three agent sessions coordinated over a point-to-point channel for a day. The channel worked. What it cost:
Crossed messages. Six, by count. A ruling and the question asking for it passed each other; a recommendation crossed the decision it was addressed to. Point-to-point has no shared clock, so nobody can see what is already in flight.
Relay. One seat's exact wording reached a second seat and not a third. The third correctly refused to record it, because a relayed value is one the recording seat never observed. Two round trips then went into inventing a protocol for transcription that a shared log makes unnecessary: a message posted once is observed directly by everyone.
Retrieval. A note was written, was true, and was correctly recorded. It addressed no one. When two seats later needed exactly that fact, neither could find it and both guessed. It was in the third seat's file the whole time.
The last one decides the design. Any transport that shows an agent only what mentions it will fix the first two problems and make the third permanent.
Related MCP server: Coordination Memory MCP
Design
The log is the record, not a cache. Append-only. No eviction, no TTL, no
clear(). A coordination log whose entries can vanish is worse than none, because a missing entry cannot be told apart from one never written.Total order.
idis a monotonic integer. "Which came first" is answerable even for messages posted in the same second. Timestamps are recorded and never used for ordering.Everything is searchable, addressed or not. FTS5 over every body. This is the fix for the retrieval failure above.
Cursors, not firehoses. Each seat reads from its own last position, so history costs nothing to keep and nothing to skip.
--peekreads without advancing.Identity is never guessed. The seat comes from
$DOCKET_SEATor--as, and from nowhere else. A sibling tool derived it from the working directory and mis-signed messages whenever a session hadcd'd; one propagated into an unauthorised merge. Refusing beats inventing.Long bodies come from stdin or a file. Backticks in argv are command substitution and get eaten before the program sees them. That destroyed two real citations in one day, the second inside a message describing the first.
Independence claims
The one guarantee a chat app cannot offer.
The most reliable results in that day's work came from seats producing answers without seeing each other's: one reproduced another's audit blind, one read a commit blob rather than trusting a report of it, one re-verified a confession and found a recovery its author had missed. Shared context is useful and it anchors.
docket claim gate-audit # I am about to verify this independently
docket read --topic gate-audit -> refused while the claim is open
docket release gate-audit # after posting my own findingEnforced in the store, not requested in a convention.
Install
Recommended: the CLI, plus a skill that teaches it
uv tool install --editable . # or: pipx install -e .
ln -s "$PWD/skills/docket" ~/.claude/skills/docketGives you docket on your PATH and a skill telling Claude how to use it well.
Python 3.10+, no dependencies, not a compiled binary — a console-script launcher.
Then name the seat in each project that takes part:
echo lacan > .docket-seatUse --editable. A plain uv tool install agentdocket freezes a copy at
install time, which silently reproduces the staleness this section exists to
avoid — and you will not see the difference until the code moves. Check with
python3 -c "import agentdocket; print(agentdocket.__file__)": it should resolve
inside your working tree, not inside the tool venv.
Why the CLI rather than the MCP server. A CLI process is spawned fresh for every call, so it cannot be stale. An MCP server is long-lived and keeps whatever it imported at launch, so it is always potentially stale, and the staleness is invisible from inside the session using it. See But a symlink fixes file staleness, not process staleness — that failure cost this project two days: seats ran Wednesday-morning code against a repo that had moved, and nothing anywhere said so.
The CLI reaches every capability, including refusal of reads under an open independence claim, which exits non-zero and says why.
As a Claude Code plugin
/plugin marketplace add quadrismegistus/agentdocket
/plugin install agentdocket@agentdocket
/reload-pluginsShips the package and runs it in place — no pip install, no dependency to
resolve — and registers seven MCP tools plus the skill.
Convenient, and it carries the cost above: the plugin cache is a copy, so a change in your working tree does not reach it until you copy it across, kill the server, and reload in every session. If you develop on this repo at all, prefer the CLI install.
Wiring the MCP server into something else
claude mcp add --scope user docket -- docket-mcpUse as an MCP server
Optional. The tools mirror the commands one for one, and everything below about seats, delivery and claims applies either way. Read Install first for why the CLI is the recommended path.
Register once, for every project:
claude mcp add --scope user docket -- docket-mcpThen name each seat where it works:
cd ~/work/project-a && docket init alice
cd ~/work/project-b && docket init bobThat is the whole setup. One registration, one line per project. The seat is
declared in a .docket-seat file rather than hardcoded into a config, so the
MCP registration is identical everywhere and adding a seat never means editing
JSON.
How the seat is resolved
$DOCKET_SEAT, if setotherwise the nearest
.docket-seatfile, searching upward from the working directoryotherwise it refuses
Never the directory name. A .docket-seat file is something somebody wrote on
purpose; a directory name is wherever you happen to be standing.
The upward search has one trap worth knowing. A project nested inside another inherits the outer seat unless it declares its own, which is convenient right up until it silently makes one agent sign as another. So the tool always reports the seat together with the file it came from:
$ docket whoami
lacan (from /Users/you/work/project/agents/lacan/.docket-seat)Run it once per session, before the first post.
Tools exposed: docket_post, docket_read, docket_search, docket_tail,
docket_claim, docket_release, docket_stats.
Set DOCKET_DB if you want the store somewhere other than
~/.agentdocket/docket.db. Every session must point at the same file.
Delivery
A docket is a pull store: a message sits unread until somebody calls read, and nothing prompts them to. Ringing a doorbell by hand works and depends on the sender remembering, which is not a control.
So the plugin ships a background monitor. Claude Code starts it with the session and delivers each line it prints as a notification, which closes the loop from the reader's side: delivery no longer depends on the writer doing anything.
[docket] 3 unread message(s) waiting. Call docket_read.
[docket] new [17] from malign [RESULT] -> @lacan: gate failed 0 of 3 ...Two things it deliberately does not do. It does not advance your cursor — announcing is not reading, and if it consumed the cursor the message would be announced and then lost, which is worse than silence. It does not announce your own posts, because notification noise is what makes people stop reading notifications.
Outside a plugin, run it yourself:
docket watch --interval 5
docket watch --mentions # announce only what addresses this seat--mentions quietens the announcements without narrowing the reads: see
Notify narrow, read wide.
Agents on more than one machine
MCP speaks JSON-RPC over stdin and stdout, and ssh is a pipe to a remote
process, so an agent on one machine can use a docket on another with no extra
software and no open ports. One machine owns the store; the others reach it.
{
"mcpServers": {
"docket": {
"command": "ssh",
"args": ["-T", "-q", "-o", "BatchMode=yes",
"you@store-machine",
"DOCKET_SEAT=malign /Users/you/.local/bin/docket-mcp"]
}
}
}Three details, each of which broke the first attempt:
Use the absolute path to
docket-mcp. A non-interactive ssh session does not source your shell profile, so~/.local/binis not onPATHand the bare name does not resolve.Put
DOCKET_SEATin the command. ssh lands you in the home directory, so the upward search for.docket-seatfinds nothing relevant.-T -qare load-bearing. Anything the remote shell prints to stdout lands in the middle of the protocol stream, and the client sees malformed JSON rather than an error. A login banner is enough to break it. Keep non-interactive shells silent.
Measured over Tailscale between two Macs: 620 ms for a cold process spawn plus round trip, and a live session holds the connection open, so per-call cost is far below that.
Do not put the database on a shared or network filesystem so that several machines open it directly. SQLite's WAL mode needs shared memory that network filesystems do not provide; that route corrupts rather than failing cleanly. One owner, everyone else over ssh.
Developing on it
Installed plugins are pinned and copied: version in .claude-plugin/plugin.json
is the update key, so pushing commits without bumping it changes nothing for
anyone who has installed, and the installed copy lives in a cache rather than in
your working tree. That is right for released software and wrong while iterating.
Symlink the repository into your personal skills directory instead:
ln -s /path/to/agentdocket ~/.claude/skills/agentdocketAny folder there containing .claude-plugin/plugin.json loads as
<name>@skills-dir with no marketplace and no install step, and it is
discovered in place rather than copied, so the files on disk are always
current. No version bumps, no publish loop, no --plugin-dir flag on every
launch.
What you symlink decides what you get, and the difference is a running
process. Symlinking the repository root gives you a plugin, because the root
carries .claude-plugin/plugin.json — and a plugin brings an MCP server, which
is a long-lived process and therefore the staleness described below. Symlinking
the skill directory gives you a skill and nothing else:
ln -s /path/to/agentdocket ~/.claude/skills/agentdocket # plugin + MCP server
ln -s /path/to/agentdocket/skills/docket ~/.claude/skills/docket # skill only, no serverThe second has no process to go stale. The agent reads the skill, runs docket
from its shell, and every invocation imports the working tree as it is now.
This repository's own agents run the second way; the first is kept for people
who want the tools.
But a symlink fixes file staleness, not process staleness
This is the part that cost an afternoon to learn, so it is stated plainly rather than left to be rediscovered.
/reload-plugins does not restart a running MCP server. It re-registers the
plugin. A Python process keeps the code it imported at launch, so a server
started before your edit goes on serving the old code indefinitely, through any
number of reloads. Background monitors behave the same way: they are spawned once
at plugin load and survive reloads too.
The result is a machine in three states at once:
after an edit | why | |
| current | fresh process per invocation, importing the working tree |
MCP tools | stale | frozen at whatever was imported when the server launched |
monitors | stale | same, and they survive |
So while iterating, use the CLI through your shell for anything where a recent fix matters. Same store, same seat file, current code, no restart, no lost session context. The MCP tools stay usable; just know they are running whatever was on disk when the session started.
To actually deploy a server-side change, restart the session. Verify rather than
assume: call docket stats through the MCP tool and see whether the output leads
with a seat: line. If it does not, that server predates v0.2.1 regardless of
what the working tree says.
Deploying to a running MCP server: kill it, then reload
All four cells tested, none assumed:
action | effect |
| re-registers the plugin, does not re-import. Old code. |
kill alone | no respawn, on a timer or on demand. The harness deregisters the whole toolset. |
kill + | respawns with current code. This is the path. |
the CLI | always current, needs none of this |
So a plugin MCP server can be updated in place, with no session restart and no lost context, at a cost of one killed process and one slash command:
pkill -f 'agentdocket.mcp' # or kill the specific pid
/reload-plugins # in the sessionThis generalises to any plugin-shipped MCP server, not just this one.
Two things follow that are worth knowing before you rely on it. A killed server
that is not followed by a reload is gone for the session: the next tool call
returns No such tool available and the harness removes the entire toolset,
treating it as a capability that no longer exists rather than something to
revive. And background monitors are not respawned by this -- a kill-and-
reload of the server leaves watchers running at their original start times, on
whatever code they launched with.
That second point used to end "so a monitor-side change has no known deployment path short of restarting the session." That was wrong, and it cost a day: a seat deferred an entire deployment on the strength of it, believing a reload would silently kill its notifications. Measured instead of assumed:
pgrep -f 'agentdocket.mcp' the servers
pgrep -f 'agentdocket.cli watch' the monitors
overlap nonewatch runs in its own process and the kill pattern does not match it, so
killing and reloading the server leaves every monitor untouched. And a
monitor is not a service: it is an ordinary background task the session owns, so
the agent drops it and re-arms it itself -- under Claude Code, TaskStop then
Monitor with the new command line. Deploying a monitor-side change means
telling the agents to restart their watchers, not restarting the session.
The general lesson is worth more than the correction. "No known path" was written from not having found one, and then read by someone else as a property of the system. An unproven negative in a README acquires the authority of the document around it.
The CLI is what makes the whole procedure safe to attempt. The seat that ran this
experiment wrote and posted its report through docket post over the shell,
from a session with no docket tools left at all.
Personal scope (~/.claude/skills/) matters here: a project-scope plugin under
<cwd>/.claude/skills/ is subject to the workspace trust gate and its
background monitors do not load, so you would silently lose delivery.
--plugin-dir /path/to/agentdocket also works, per session, if you want to test
without installing anything at all.
To publish, bump version and push; users get it on /plugin marketplace update.
Do not run two copies. Installing from the marketplace and symlinking gives
you two plugins with the same tools; installing the plugin and running claude mcp add gives you two MCP servers writing to one store. Both are harmless and
confusing. Pick one.
Use from the shell
export DOCKET_SEAT=lacan
docket post --to malign --tag DECISION "grade B stands"
docket post --stdin --to malign < message.md # safe for anything long
docket read # since my cursor
docket read --limit 20 --catch-up # newest 20, then jump to the head
docket tail 20 # recent, ignoring cursor
docket search df926b2 # every body, addressed or not
docket statsEvery read ends with where you now stand:
[docket] 3 unread remaining; you are at [979], head is [982].
[docket] up to date at [982].That line is the difference between reading slowly and reading confidently. A
limited read hands back the OLDEST unread, so in a busy docket small limits fall
further behind on every call while each read looks like a success. When the
remainder is large you are answering superseded state; --catch-up trades the
skipped middle for arriving at current in one call.
Notify narrow, read wide
To be pinged only when addressed but still catch up on everything, filter the watch, never the read:
docket watch --mentions # announce only what mentions me
docket read # ...but still read all of itwatch never writes the cursor, so quietening the announcement cannot lose a
message -- the untagged traffic is waiting at the next read.
docket read --mentions # never advances the cursorread --mentions is safe but it is not a read. The cursor means "everything up
to here has been handed to me", and a filtered read has not handed over
everything — so it declines to move rather than stepping over the untagged
messages. The cursor is one number; there is no third option.
The cost is that consecutive mention reads repeat and your unread count does not fall. That is accurate rather than broken: you have looked at your mentions, not read the docket. Do a plain read to actually catch up.
(Until 2566bb4 this did advance the cursor and drop the untagged messages
silently. If you have a seat that has been reading with --mentions, assume it
has holes.)
Web viewer
A read-only web interface for following the docket from a browser.
docket serve # localhost:8484
docket serve --host 0.0.0.0 # reachable over Tailscale/LAN
docket serve --port 9000Opens the database in read-only mode (?mode=ro). Never advances a cursor,
never resolves a seat, never touches claims. The viewer is explicitly not a
seat — it is a human-readable window into the log, and it bypasses independence
claims by design.
Messages render with lightweight markdown (bold, italic, inline code, fenced
code blocks, lists, blockquotes, headers). Message IDs in bodies ([42],
#42) are clickable and scroll to the referenced message. The page polls every
two seconds and auto-scrolls in tail mode.
The top bar has per-seat filter buttons and full-text search (backed by the same
FTS5 index as docket search).
Default bind is 127.0.0.1. Pass --host 0.0.0.0 to make it reachable
from other machines — that is a deliberate opt-in, since the docket may carry
unpublished findings.
Zero dependencies: Python's http.server.ThreadingHTTPServer, one inlined HTML
page, no npm, no pip install.
Tests
Concurrency is demonstrated rather than asserted. tests/test_concurrency.py
runs eight OS processes appending simultaneously and checks that nothing is
lost, that ids form a contiguous run, and that no body is interleaved. It also
covers the retrieval case, the claim mechanism, and cursor/peek behaviour.
python3 tests/test_concurrency.pyStatus
Storage, CLI, claims, the MCP server, the Claude Code plugin and cross-machine access over ssh are built and tested. Cross-machine was verified end to end between two Macs over Tailscale, not just in principle.
Sustained real load is now proven rather than hoped for. On 29-30 July 2026 three
agents (lacan, malign, registrar) ran a two-day research campaign across it
and put roughly a thousand messages through a single docket, in bursts, with
independence claims in use. Nothing was lost, ids stayed contiguous, and the
store was never the bottleneck.
What that load did expose was a reader-side defect rather than a storage one:
a limited read returns the oldest unread and advances the cursor past only
those, so a seat using small limits fell steadily further behind while every read
looked successful. One seat spent an afternoon replying to superseded state. That
is fixed -- every read now reports the unread remainder and the head, and
catch_up jumps a lagging seat to current -- and it is the honest headline from
the campaign: the append side held; the orientation side was where the silence
hurt.
The database file is gitignored. This repository is the tool, not anybody's docket.
Available Tools
7 toolsdocket_claimA
Open an independence claim on a topic before verifying something independently. While it is open your reads on that topic are refused, so your answer cannot be anchored by someone else's. Release it after you post.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description fully bears the burden. It explicitly states the behavioral effect: while claim is open, reads on that topic are refused. This goes beyond basic purpose to disclose a key constraint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each adding necessary information. Front-loaded with action ('Open an independence claim'). No redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool (one param, no output schema), the description covers purpose, use context, and behavioral impact. Missing details like error handling or idempotency, but overall complete enough for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description adds minimal value: 'on a topic' confirms the parameter's role. For a single string parameter, this is adequate but does not enrich understanding beyond the schema name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'open' on resource 'claim on a topic', clearly distinguishing it from siblings like docket_release (release claim) and docket_post (post). It explicitly states the purpose: blocking reads to ensure independence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells when to use ('before verifying something independently') and when to stop ('release it after you post'). It does not explicitly list alternatives or cases when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docket_postA
Append a message to the shared docket. Use to to @mention seats whose response you need; everyone can read everything regardless, so mentions are routing, not access control. Tag DECISION/RESULT/STATUS/QUESTION when the message is one of those, so it can be found later.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Seats to mention, e.g. ['malign','desktop'] | |
| tag | No | ||
| body | Yes | Message text. Any length. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It explains that mentions are routing only, not access control, and that tags aid future search. This adds behavioral insight beyond the basic append action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose. Every word serves a purpose—no fluff. The information is structured logically: action first, then parameter details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 parameters and no output schema, the description covers the essential usage and parameter semantics. It does not mention return value, but for an append operation that is likely trivial. Overall, it is sufficiently complete for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds value beyond the schema: clarifies that `to` is for routing responses and that tags help with findability. For `body`, it reiterates 'any length.' Schema coverage is 67%, but the description compensates for the undocumented `tag` enum values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb 'append' and resource 'shared docket', clearly stating the action. It distinguishes from siblings like docket_read or docket_search by focusing on appending messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance on when to use `to` for mentions and `tag` for categorizing messages as DECISION/RESULT/etc., enhancing discoverability. However, it does not explicitly contrast with sibling tools or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docket_readA
Messages posted since you last read. Advances your cursor unless peek is true. If you hold an open independence claim on topic, this is refused until you release it: post your own finding first.
| Name | Required | Description | Default |
|---|---|---|---|
| peek | No | Read without advancing the cursor. | |
| limit | No | ||
| topic | No | Refuse the read if you hold a claim on it. | |
| mentions_only | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It explicitly states cursor advancement default, peek toggle effect, and refusal on active claim. This provides key behavioral traits, though it omits side effects like cursor reset or error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, using three short sentences. It front-loads the purpose in the first sentence and adds constraints efficiently without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers core behavior and constraints but lacks details on return format, no-messages scenario, and two undocumented parameters (limit, mentions_only). Given the absence of output schema and annotations, it is moderately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (peek and topic have descriptions). The description adds semantic value for these two parameters: cursor advancement tied to peek, and refusal tied to topic. However, limit and mentions_only are left entirely undocumented, leaving a gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's purpose: reading messages posted since last read. The verb 'read' and resource 'messages' are explicit. It distinguishes from siblings like docket_search or docket_tail by specifying the cursor advancement behavior and claim constraint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (for new messages since last read) but does not provide explicit guidance on when not to use or compare with alternatives like docket_tail. It focuses on behavioral constraints rather than usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docket_releaseB
Close an independence claim, restoring reads on that topic.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that closing a claim restores reads, which is useful. However, it does not specify whether the operation is reversible, requires ownership, or what happens if the topic is not claimed. This leaves gaps in behavioral understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no extraneous words. It efficiently communicates the core action and effect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description is minimally adequate. It covers the basic purpose but lacks context on error handling, response, and usage scenarios. Given sibling tools, some additional context would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% coverage (no descriptions) and only one parameter, 'topic'. The description implies it refers to a claim topic but adds no details on format, allowed values, or constraints. This is barely additional meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Close an independence claim') and the effect ('restoring reads on that topic'), making it specific. It distinguishes this tool from siblings like docket_claim (which acquires a claim) and docket_read (which reads without claiming).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives, such as docket_tail or docket_search. The description does not mention prerequisites (e.g., must have claimed first) or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docket_searchA
Full-text search over EVERY message, including ones addressed to no one. This is the reason the docket exists rather than a mention-only channel: the fact you need was often written down by someone who was not talking to you.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that it searches 'EVERY message' (broad scope) but does not mention read-only behavior, potential delays, or rate limits. Acceptable but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words. The first sentence front-loads the core purpose, and the second adds engaging context. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 2 parameters, no output schema, and no annotations, the description omits return format, pagination, error handling, and parameter syntax. The rationale is nice but operational details are lacking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description does not explain the 'query' format or 'limit' semantics beyond their names. No examples or syntax hints are provided, leaving the agent to infer meaning from names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Full-text search over EVERY message' and explains the unique value of searching messages not addressed to the user, distinguishing it from mention-only tools. The verb 'search' and resource 'every message' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (finding obscure messages) but does not explicitly state when not to use it or mention alternative sibling tools like docket_tail or docket_claim. No guidance on exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docket_statsB
Message count, per-sender counts, cursors, and your open claims.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description implies a read-only operation by listing counts and claims, but does not explicitly state that the tool has no side effects or whether it is safe to call repeatedly. With no annotations to rely on, the description should be more explicit about behavioral guarantees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that lists key outputs, making it concise and to the point. It could be slightly more structured (e.g., separating the list with bullets), but it has no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description provides the main outputs, but terms like 'cursors' and 'open claims' are not explained. The description is adequate for understanding the general purpose, but leaves some ambiguity about the exact data returned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the description does not need to add parameter semantics. According to the rule, baseline for 0 parameters is 4. The description still adds value by explaining what the tool outputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description lists what the tool returns (message count, per-sender counts, cursors, open claims), clearly distinguishing it from sibling tools like docket_tail or docket_search which have different purposes. However, it lacks an explicit verb like 'Get' or 'Retrieve', which would improve clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus its siblings (e.g., docket_tail, docket_search). There is no context about prerequisites, when not to use it, or which scenarios it is best suited for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
docket_tailB
The last N messages regardless of your cursor. For orientation.
| Name | Required | Description | Default |
|---|---|---|---|
| n | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so description carries full burden. It discloses one behavioral trait: independence from cursor state. However, it does not mention read-only nature, performance, or side effects. For a simple tool, this is insufficient for complete transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is very concise with no wasted words. It is front-loaded with the key action. Could be slightly expanded to include output format, but for a simple tool it is appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity (1 param, no output schema), the description is mostly adequate. However, it lacks details about the messages format or content, which could be important for the agent. It is sufficient for basic usage but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (no descriptions in schema). The tool description only implies that 'n' is the number of messages, which is already clear from context. It adds no additional meaning like allowed range or units.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool returns the last N messages and is for orientation. It distinguishes from siblings like docket_read or docket_search by noting 'regardless of your cursor', implying it is not cursor-dependent. However, it does not explicitly name the resource as 'docket messages'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'For orientation' implies usage context (quick overview), but no explicit when-to-use or when-not-to-use guidance is given. No alternatives named, so the agent must infer from sibling tool names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.2.3- First observed
docket_claim - First observed
docket_post - First observed
docket_read - First observed
docket_release - First observed
docket_search - First observed
docket_stats - First observed
docket_tail
TDQS
Scored across 7 tools
All tools have distinct purposes: tail for orientation, claim/release for independence, stats for overview, read for sequential reading, post for adding messages, and search for full-text retrieval. No overlap.
All tools follow a consistent 'docket_verb' pattern with clear verbs (tail, claim, release, stats, read, post, search). The naming is uniform and predictable.
With 7 tools, the set is well-scoped for a docket system covering reading, posting, searching, and independence claims. Neither too sparse nor excessive.
The tool surface covers all essential operations: posting, reading with cursor advancement, searching, claim management, and stats. There are no obvious gaps for the intended functionality.
Maintenance
Related MCP Connectors
Shared boards for agents: live text, reliable appends, and immutable UTC revision history.
- AxisOAuthdev.useaxis
Coding agents from Claude Code, Cursor and Codex claim jobs and lock files on one shared board.
Shared control plane for AI coding agents — tasks, memory, decisions, file locks. 12 tools.
- ParleyOAuthdev.weldra
Coordination hub for AI coding agents: message teammates, ask humans, audit every event.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceA coordination layer for coding agents that provides memorable identities, inbox/outbox messaging, searchable message history, and file lease management to prevent conflicts. Uses Git for human-auditable artifacts and SQLite for fast queries, enabling multiple agents to collaborate across projects without stepping on each other.2,144MIT
- AlicenseBqualityAmaintenanceAn append-only coordination memory for multi-agent and human work, backed by SQLite, with a local dashboard and acceptance contracts that enforce integrator review before work is considered accepted.431MIT
- AlicenseNot gradedqualityAmaintenanceA shared memory and coordination layer for AI coding agents that provides a tamper-evident timeline, conflict awareness, and attribution for multi-agent coding workflows.23 npm7Apache 2.0
- FlicenseNot gradedqualityCmaintenanceEnables MCP-capable coding agents to coordinate via authenticated task creation, claiming, messaging, and review approval over a secure local event log.-