jschoubben 9acc40145a A person's client: the mesh's tools from a workstation
Design 25 §7's second item. Two surfaces over one thing — a command line for somebody
at a terminal, an MCP server for an agent — and both are adapters over the same three
calls: what tools are there, what does this one take, call it. A second way of reaching
a tool would be a second thing to keep correct.

It uses the client a module's runtime uses. Not a bridge and not a second protocol: a
person connects as their own bus user and publishes on the tool subjects their account
permits, so "what may this person do" is answered by the same permission list that
answers it for a module, and an audit has nothing separate to read.

`mesh tools` lists what the *catalogue* has, not what this credential may call. The two
differ and the difference is the point: somebody seeing only their own tools cannot tell
"not installed" from "not yours", and those need different people to fix them.

A failed call says which of three things happened, because the remedies are in three
different places: nobody serves that tool, this credential may not call it, or the tool
itself was slow. Without that they are one timeout and a stack trace.

The MCP surface decides nothing. The tool names are the ones a person types, the schemas
are the modules' own, and an answer is passed through unshaped — an adapter that
summarised somebody else's answer would be deciding what matters in it. A tool that fails
comes back as a tool error rather than a protocol error, because the request was
well-formed and the mesh answered it.

Written against the protocol directly: it is three methods and one framing, and a
dependency here would be a dependency on every workstation.

Tests drive both surfaces against a real bus, including that a host's notification is
answered with nothing and an unknown method is refused. They run one file at a time,
because each stands up a module serving the same tool subjects and run together their
requests get split between them — which showed up as one test reading another's answer.
2026-09-27 17:03:13 +02:00

mesh-tools

The Novox Mesh tool runtime — the per-node process that makes a module's tools actually serve.

A module ships its tools (built on @novox/mesh-sdk); this runtime is what loads them and puts them on the mesh. It:

  1. connects the mesh broker (novox/hq ADR 0001) — a concrete AMQP implementation of the sdk's Broker contract;
  2. imports the assigned modules' compiled tool entrypoints, each of which registers its tools as it loads;
  3. serves them through the sdk's serveTools harness, answering tools.invoke over the broker.

Everything hard — dispatch, collection, duplicate-name safety — is the sdk's. This is the thin wrapper that binds the broker and loads the modules. Keeping the AMQP client here, out of the sdk, is deliberate: a broker-client change never rebuilds a module (ADR 0039).

Running it

MESH_BROKER_URL     amqp://…              the mesh broker
MESH_TOOL_MODULES   /a/tools/index.js,…   the assigned modules' compiled tool entrypoints

node dist/main.js, or the container (Dockerfile). On a node the host resolves both variables and starts it like any other supervised workload.

Verified

npm test stands up LavinMQ (the mesh's broker) and proves the whole path over real AMQP: the runtime serves a registered tool, a separate connection invokes it by name and gets the result, and an unknown tool is refused over the wire.

S
Description
Novox Mesh — the tool runtime. Binds the mesh broker (AMQP) and serves the assigned modules' tools through the sdk harness.
Readme
228 KiB
Languages
TypeScript 76.8%
JavaScript 18.8%
Dockerfile 4.4%