@geonosis/mcp
v3.0.0
Published
The geonosis command registry served over MCP — one registry, another door, with a preview→confirm gate on every write.
Maintainers
Readme
@geonosis/mcp
The geonosis command registry, served over MCP. One registry, another door.
// .mcp.json / the editor's MCP config
{ "mcpServers": { "geonosis": { "command": "npx", "args": ["geonosis-mcp"] } } }This server holds no tool of its own. Every tool is a @geonosis/cli command, so an agent and
the operator's terminal cannot disagree about what a command did — geonosis --json doctor and the
doctor tool return the same bytes, and a test proves it over
InMemoryTransport.createLinkedPair(), which is exactly how Midday's in-app assistant reaches the
same McpServer its external clients do.
Generated instructions
The server introduces itself with a preamble computed from the repo it is bound to: the law's
length, the rules the repo's .oxlintrc.json actually enables (not the ones it turned off), the
counters gate-baseline.json holds, and the read/write kind of every tool. Midday's mechanic — a
generated preamble means no tool spends a call establishing the facts every call needs.
When a repo has none of those files yet, the preamble says so rather than inventing a number.
The root is the server's
No tool takes a directory. The root is the working directory the server was started in, and nothing over the wire can change it: a tool that took a path would let a client point a gate at any tree on the machine and the answer would still look like this repo's.
The write gate — preview, then confirm
A tool whose command can change a file the repo tracks is a write. Its first call runs nothing: it answers with a PREVIEW, the arguments as read, and a token.
PREVIEW — init can change a file this repo tracks, so nothing has been run.
…
token: 9c1f2a0b7d4e6531The second call carries the same arguments plus confirm: true and that token. A Medusa storefront's Trench
gate, kept stateless: the token is a hash of the tool id and the arguments, so nothing is
remembered between calls, one client's preview is not another client's authority, and a confirm
carrying a token for different arguments is refused rather than run.
Write tools today: ratchet, verify, ledger, visual-diff, review, observability, init,
sync, skills, update. A write is anything a reviewer would want to have approved — a file the repo
tracks, or a send to a third party: observability prove --sink posthog reaches somebody's project.
Layer
mcp may import cli, and nothing else the kit ships. The day it reaches past the registry for a
gate is the day the two doors can disagree; three walls and one door are planted against in the
plugin's dogfood.bin.test.ts.
Value vocabularies, not just field names (#135)
A tool catalog that publishes a filter's NAME but not its VALUE vocabulary produces the worst wrong
answer available: a Medusa storefront's assistant filtered status: 'PENDING' — a value no state machine there
emits — got an empty result, and reported "0 production orders pending" as fact, when the truth was
11. A zero from a wrong filter reads as good news.
The contract this server inherits from that incident, for any tool surface built on it:
- enum-shaped inputs carry their values in the schema, IMPORTED from where the code branches — never retyped beside it;
- an unknown value is a REFUSAL naming the vocabulary, and the refusal says verbatim that it must not be read as a count of zero;
- a trace that records the filters beside the result turns a chat anecdote into a diagnosable defect.
