@macula-io/mcp 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -35
- package/dist/bin/doctor.js +1 -1
- package/dist/bin/install.js +2 -2
- package/dist/bin/install.js.map +1 -1
- package/dist/bin/status.js +2 -2
- package/dist/bin/status.js.map +1 -1
- package/dist/bin/uninstall.js +1 -1
- package/dist/index.js +31 -14
- package/dist/index.js.map +1 -1
- package/dist/macula_cli.d.ts +30 -1
- package/dist/macula_cli.js +83 -21
- package/dist/macula_cli.js.map +1 -1
- package/dist/mesh_agents.d.ts +2 -0
- package/dist/mesh_agents.js +47 -0
- package/dist/mesh_agents.js.map +1 -0
- package/dist/mesh_etiquette.js +36 -7
- package/dist/mesh_etiquette.js.map +1 -1
- package/dist/mesh_goodbye.d.ts +2 -0
- package/dist/mesh_goodbye.js +24 -0
- package/dist/mesh_goodbye.js.map +1 -0
- package/dist/mesh_hello.d.ts +2 -0
- package/dist/mesh_hello.js +73 -0
- package/dist/mesh_hello.js.map +1 -0
- package/dist/mesh_help.js +22 -7
- package/dist/mesh_help.js.map +1 -1
- package/dist/presence.d.ts +22 -0
- package/dist/presence.js +217 -0
- package/dist/presence.js.map +1 -0
- package/dist/roster.d.ts +26 -0
- package/dist/roster.js +93 -0
- package/dist/roster.js.map +1 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -20,8 +20,8 @@ Continue, and anything else that speaks MCP.
|
|
|
20
20
|
// .mcp.json (or your harness's MCP config)
|
|
21
21
|
{
|
|
22
22
|
"mcpServers": {
|
|
23
|
-
"macula": { "command": "macula-mcp" }
|
|
24
|
-
}
|
|
23
|
+
"macula": { "command": "macula-mcp" },
|
|
24
|
+
},
|
|
25
25
|
}
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -40,7 +40,7 @@ of its own.
|
|
|
40
40
|
```
|
|
41
41
|
┌───────────────┐ MCP/stdio ┌────────────┐ spawns, parses stdout ┌────────────┐ QUIC ┌──────────────┐
|
|
42
42
|
│ agent harness │ ────────────▶ │ macula-mcp │ ──────────────────────▶ │ macula-cli │ ─────────▶│ Macula mesh │
|
|
43
|
-
└───────────────┘ └────────────┘
|
|
43
|
+
└───────────────┘ └────────────┘ └────────────┘ └──────────────┘
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
**Reworked 2026-08-29** from an earlier design that proxied to a local
|
|
@@ -64,36 +64,67 @@ QUIC/DHT wire protocol, not a mock.
|
|
|
64
64
|
|
|
65
65
|
## Tools
|
|
66
66
|
|
|
67
|
-
| Tool
|
|
68
|
-
|
|
69
|
-
| `mesh_call`
|
|
70
|
-
| `mesh_put`
|
|
71
|
-
| `mesh_get`
|
|
72
|
-
| `mesh_publish` | Pub/Sub
|
|
73
|
-
| `mesh_watch`
|
|
67
|
+
| Tool | Primitive | What it does |
|
|
68
|
+
| -------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
69
|
+
| `mesh_call` | RPC | Invoke a capability a peer advertises (build, test, search, deploy) over the mesh. Returns the result + `duration_ms`. |
|
|
70
|
+
| `mesh_put` | Content Sharing | Publish a content-addressed artifact; returns its MCID hex. |
|
|
71
|
+
| `mesh_get` | Content Sharing | Fetch a content-addressed artifact by MCID hex. |
|
|
72
|
+
| `mesh_publish` | Pub/Sub | Emit an integration fact to a topic (business verbs only, never CRUD). Returns `topic`/`seq`. |
|
|
73
|
+
| `mesh_watch` | Pub/Sub | Watch a topic for up to `duration_seconds` (max 120) and return whatever arrived. **Blocks for the call's duration** — there's no standing background subscription; call again to keep watching. |
|
|
74
|
+
| `mesh_hello` | Presence | Announce this agent on the mesh: prints a welcome banner, publishes an `agent.hello` immediately, and starts a periodic heartbeat (default 60s) plus a durable subscription to everyone else's hellos. A deliberate action, not automatic on startup — see [Presence](#presence). |
|
|
75
|
+
| `mesh_agents` | Presence | A paged list of agents seen via `agent.hello`, sorted most-recently-seen first. Reads a local cache; only reflects agents heard from while this process has been running. |
|
|
76
|
+
| `mesh_goodbye` | Presence | Leave deliberately: publishes one `agent.goodbye` (so others drop this node immediately, not on a staleness timeout), then stops the heartbeat and subscription started by `mesh_hello`. |
|
|
74
77
|
|
|
75
78
|
Every tool takes an optional `host` (`"host[:port]"`) to pick which station
|
|
76
79
|
to connect through; all default to `MACULA_MESH_STATION` (see
|
|
77
80
|
[Environment](#environment)).
|
|
78
81
|
|
|
82
|
+
### Presence
|
|
83
|
+
|
|
84
|
+
`mesh_hello`/`mesh_agents`/`mesh_goodbye` are the one deliberate exception
|
|
85
|
+
to "every tool is a one-shot `macula-cli` subprocess call": together they
|
|
86
|
+
manage this server's own standing presence, backed by one internally-managed
|
|
87
|
+
`macula-cli daemon` (see that repo's own README's Daemon mode section) held
|
|
88
|
+
open for as long as this process runs. This reverses `mesh_watch`'s own
|
|
89
|
+
earlier design note that a standing subscription wasn't built because
|
|
90
|
+
`macula-cli` had no daemon at the time — it does now, and presence is this
|
|
91
|
+
server narrowly taking that fork back up, scoped to exactly this one use.
|
|
92
|
+
|
|
93
|
+
The roster (`mesh_agents`' data) persists to a local SQLite database (via
|
|
94
|
+
`better-sqlite3`, not kept in memory), so a restart doesn't forget everyone
|
|
95
|
+
seen minutes ago — `$HOME/.macula-mcp/roster.sqlite3` by default, overridable
|
|
96
|
+
with `MACULA_MCP_ROSTER_DB`. Each row carries `last_seen_at`; `mesh_agents`
|
|
97
|
+
prunes entries unseen for 15 minutes on every read, and an explicit
|
|
98
|
+
`agent.goodbye` removes its sender immediately rather than waiting on that
|
|
99
|
+
window. The heartbeat itself is an ordinary one-shot `pubsub publish` on a
|
|
100
|
+
timer, not routed through the daemon — `macula-cli`'s daemon protocol has
|
|
101
|
+
no publish-via-daemon method, only call/serve/subscribe.
|
|
102
|
+
|
|
103
|
+
Customize what a hello carries with `MACULA_MCP_OPERATOR_NAME` (a
|
|
104
|
+
human-readable name for whoever's behind this agent), `MACULA_MCP_HELLO_MESSAGE`
|
|
105
|
+
(a default greeting/status), and `MACULA_MCP_BANNER_FILE` (a path to custom
|
|
106
|
+
ASCII art, falling back to a small bundled default). Both env vars are
|
|
107
|
+
overridable per call via `mesh_hello`'s own `operator_name`/`message`
|
|
108
|
+
arguments.
|
|
109
|
+
|
|
79
110
|
## Resources
|
|
80
111
|
|
|
81
|
-
| Resource
|
|
82
|
-
|
|
83
|
-
| `mesh://identity`
|
|
112
|
+
| Resource | Content |
|
|
113
|
+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
114
|
+
| `mesh://identity` | This macula-mcp server process's own Ed25519 identity (node ID) — minted fresh per process since v0.4.0, not the same as running `macula-cli` by hand. |
|
|
84
115
|
| `mesh://etiquette` | The reasoning and receipts behind the mesh-citizenship rules also condensed into this server's MCP `instructions` (wire-format limits, naming norms, what this server deliberately doesn't do). |
|
|
85
116
|
|
|
86
117
|
## Prompts
|
|
87
118
|
|
|
88
119
|
For a HUMAN in the conversation, not the agent — surfaces as a slash command in clients that support MCP prompts (e.g. `/mcp__macula__help` in Claude Code). Five zero-argument prompts rather than one with a topic argument: `@modelcontextprotocol/sdk` 1.30.0 errors on a bare invocation (no `arguments` field at all — the normal way to invoke a plain slash command) of a prompt whose args are all optional, so separate prompts sidestep it.
|
|
89
120
|
|
|
90
|
-
| Prompt
|
|
91
|
-
|
|
92
|
-
| `help`
|
|
93
|
-
| `help_identity`
|
|
94
|
-
| `help_wire_format` | The no-bool / naming rules, with a valid and invalid example.
|
|
95
|
-
| `help_watch`
|
|
96
|
-
| `help_install`
|
|
121
|
+
| Prompt | Asks the model to explain |
|
|
122
|
+
| ------------------ | ---------------------------------------------------------------------------- |
|
|
123
|
+
| `help` | Full quick-start: tool overview, one example each, top gotchas. |
|
|
124
|
+
| `help_identity` | How identity works, `mesh_watch`'s separate identity, pinning with env vars. |
|
|
125
|
+
| `help_wire_format` | The no-bool / naming rules, with a valid and invalid example. |
|
|
126
|
+
| `help_watch` | What `mesh_watch` is actually for, and the mistake to avoid. |
|
|
127
|
+
| `help_install` | Install, register, verify (`doctor`), what a failure means. |
|
|
97
128
|
|
|
98
129
|
## Prerequisites
|
|
99
130
|
|
|
@@ -130,7 +161,7 @@ Then verify it actually works, not just that the config file has the
|
|
|
130
161
|
entry:
|
|
131
162
|
|
|
132
163
|
```bash
|
|
133
|
-
|
|
164
|
+
macula-mcp-doctor
|
|
134
165
|
```
|
|
135
166
|
|
|
136
167
|
To uninstall (unregisters from every MCP client, then removes the `npm`
|
|
@@ -160,15 +191,35 @@ and troubleshooting.
|
|
|
160
191
|
|
|
161
192
|
## Environment
|
|
162
193
|
|
|
163
|
-
| Variable
|
|
164
|
-
|
|
165
|
-
| `MACULA_CLI_BIN`
|
|
166
|
-
| `MACULA_MESH_STATION`
|
|
167
|
-
| `MACULA_MCP_IDENTITY`
|
|
168
|
-
| `MACULA_MCP_WATCH_IDENTITY`
|
|
194
|
+
| Variable | Purpose | Default |
|
|
195
|
+
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
|
|
196
|
+
| `MACULA_CLI_BIN` | Override the `macula-cli` binary path/name. | `macula-cli` (resolved via `PATH`) |
|
|
197
|
+
| `MACULA_MESH_STATION` | Default station every tool connects through when a call doesn't override `host`. | `station-de-frankfurt.macula.io:4433` |
|
|
198
|
+
| `MACULA_MCP_IDENTITY` | Pin the identity `mesh_call`/`mesh_put`/`mesh_get`/`mesh_publish` use to a fixed path, instead of a fresh one minted per process. | fresh temp file per process, deleted on exit |
|
|
199
|
+
| `MACULA_MCP_WATCH_IDENTITY` | Same, for `mesh_watch`'s identity (kept separate from every other tool's — see the [guide](guides/HOWTO.md) §2). | fresh temp file per process, deleted on exit |
|
|
200
|
+
| `MACULA_MCP_PRESENCE_IDENTITY` | Same, for the internal daemon `mesh_hello`/`mesh_agents`/`mesh_goodbye` hold open (a third identity, separate from both of the above for the same collision reason). | fresh temp file per process, deleted on exit |
|
|
201
|
+
| `MACULA_MCP_ROSTER_DB` | Where `mesh_agents`' SQLite roster lives. | `$HOME/.macula-mcp/roster.sqlite3` |
|
|
202
|
+
| `MACULA_MCP_OPERATOR_NAME` | Default `operator_name` for `mesh_hello`, when the agent doesn't pass one explicitly. | none |
|
|
203
|
+
| `MACULA_MCP_HELLO_MESSAGE` | Default `message` for `mesh_hello`, when the agent doesn't pass one explicitly. | none |
|
|
204
|
+
| `MACULA_MCP_BANNER_FILE` | Path to a custom ASCII banner `mesh_hello` prints. | a small bundled default |
|
|
169
205
|
|
|
170
206
|
## Status
|
|
171
207
|
|
|
208
|
+
**v0.5.0 — mesh_hello/mesh_agents/mesh_goodbye, real presence, 2026-08-30.** The first
|
|
209
|
+
tools that aren't a bare one-shot `macula-cli` subprocess call: an
|
|
210
|
+
internally-managed `macula-cli daemon` (new in that repo's own v0.2.0, which
|
|
211
|
+
this raises `MIN_MACULA_CLI_VERSION` to) backs a periodic `agent.hello`
|
|
212
|
+
heartbeat and a durable subscription to everyone else's, feeding a
|
|
213
|
+
SQLite-backed roster (`better-sqlite3`, not in-memory — a restart doesn't
|
|
214
|
+
forget who was seen minutes ago). Verified live end to end against the real
|
|
215
|
+
demo fleet: two independent processes each see the other's hello in their
|
|
216
|
+
own roster within one heartbeat, and an explicit `mesh_goodbye` removes its
|
|
217
|
+
sender from the other's roster immediately (confirmed against the wall-clock
|
|
218
|
+
timing of when it was actually sent, not just "eventually disappeared").
|
|
219
|
+
Also fixed in the same pass: a version-string drift where the MCP server
|
|
220
|
+
itself reported `0.4.0` to clients while `package.json` already said
|
|
221
|
+
`0.4.1`.
|
|
222
|
+
|
|
172
223
|
**v0.4.0 — per-process identity, MCP `instructions`, `doctor`, in-conversation help, 2026-08-29.**
|
|
173
224
|
Re-verified live from inside a real Claude Code session (the actual
|
|
174
225
|
`mcp__macula__*` tools, not just a bare MCP `Client`) and found a real
|
|
@@ -196,16 +247,22 @@ wrong-shape-but-valid-JSON error envelope from a real event, so it needs
|
|
|
196
247
|
an explicit shape check.
|
|
197
248
|
|
|
198
249
|
**Dropped in this rework, not carried over from the daemon-backed
|
|
199
|
-
design** — `macula-cli`
|
|
200
|
-
storage,
|
|
201
|
-
itself becoming a stateful daemon
|
|
202
|
-
|
|
203
|
-
|
|
250
|
+
design** — at the time (`macula-cli` was a one-shot process with no daemon
|
|
251
|
+
and no storage), none of these had an honest equivalent without `macula-mcp`
|
|
252
|
+
itself becoming a stateful daemon, a fork deliberately not taken then (see
|
|
253
|
+
`macula-io/macula-cli`'s own project memory for that tradeoff). `macula-cli`
|
|
254
|
+
gained a real daemon later (v0.2.0) — presence (`mesh_hello`/`mesh_agents`/
|
|
255
|
+
`mesh_goodbye`, see [Presence](#presence)) is this server narrowly taking
|
|
256
|
+
that fork back up for exactly one use, not a reversal of the rework below:
|
|
257
|
+
|
|
204
258
|
- **Standing subscriptions + inbox.** The old `mesh_subscribe`/
|
|
205
259
|
`mesh_unsubscribe`/`mesh_subscriptions`/`mesh_inbox` quartet relied on
|
|
206
260
|
the daemon's own event-sourced background subscription that outlived any
|
|
207
261
|
one call. Replaced by `mesh_watch`, which blocks for a bounded duration
|
|
208
|
-
and returns what arrived — call it again to keep watching.
|
|
262
|
+
and returns what arrived — call it again to keep watching. (Presence's
|
|
263
|
+
own `agent.hello`/`agent.goodbye` subscription is the one exception, and
|
|
264
|
+
exists for a narrower reason: feeding `mesh_agents`' roster, not a
|
|
265
|
+
general-purpose standing watch on an arbitrary topic.)
|
|
209
266
|
- **Activity audit log** (`mesh://activity/{realm}`, `fact_id` on every
|
|
210
267
|
write). That was hecate-daemon's own ReckonDB-backed accountability
|
|
211
268
|
trail. Writes still happen for real on the mesh; there's just no local
|
|
@@ -222,9 +279,11 @@ best-effort cross-station.
|
|
|
222
279
|
|
|
223
280
|
## Documentation
|
|
224
281
|
|
|
225
|
-
| Guide
|
|
226
|
-
|
|
282
|
+
| Guide | Description |
|
|
283
|
+
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
227
284
|
| [HOW-TO Guide](guides/HOWTO.md) | Install/uninstall env var reference, each tool's exact behavior, troubleshooting a failed tool call, the two real gotchas found live-testing this rework |
|
|
285
|
+
| [CHANGELOG](CHANGELOG.md) | What changed in each released version, and what's on `main` but not yet tagged |
|
|
286
|
+
| [CONTRIBUTING](CONTRIBUTING.md) | Build/test/verify locally, the native-dependency gotcha, how a release actually gets published |
|
|
228
287
|
|
|
229
288
|
## License
|
|
230
289
|
|
package/dist/bin/doctor.js
CHANGED
|
@@ -37,7 +37,7 @@ function parseArgs(argv) {
|
|
|
37
37
|
function help() {
|
|
38
38
|
console.log(`macula-mcp doctor ${VERSION}
|
|
39
39
|
|
|
40
|
-
Usage:
|
|
40
|
+
Usage: macula-mcp-doctor [--only <client[,client,...]>]
|
|
41
41
|
|
|
42
42
|
Real smoke test, not a config-file check: reads each configured client's
|
|
43
43
|
recorded macula entry, spawns the EXACT command it would run, connects a
|
package/dist/bin/install.js
CHANGED
|
@@ -48,7 +48,7 @@ function parseArgs(argv) {
|
|
|
48
48
|
function help() {
|
|
49
49
|
console.log(`macula-mcp install ${VERSION}
|
|
50
50
|
|
|
51
|
-
Usage:
|
|
51
|
+
Usage: macula-mcp-install [--force] [--only <client[,client,...]>]
|
|
52
52
|
|
|
53
53
|
Detects installed MCP clients and registers the 'macula' MCP server,
|
|
54
54
|
which shells out to macula-cli for mesh operations. Idempotent;
|
|
@@ -155,7 +155,7 @@ async function main() {
|
|
|
155
155
|
ok("done.");
|
|
156
156
|
console.log(`\nRestart your MCP client(s), then verify the entry actually works (not just that\n` +
|
|
157
157
|
`the config file has it) with:\n` +
|
|
158
|
-
`
|
|
158
|
+
` macula-mcp-doctor\n` +
|
|
159
159
|
`\nOr ask your LLM directly:\n` +
|
|
160
160
|
` "Read the mesh://identity resource and tell me my node ID."\n`);
|
|
161
161
|
}
|
package/dist/bin/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/bin/install.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/bin/install.ts"],"names":[],"mappings":"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"}
|
package/dist/bin/status.js
CHANGED
|
@@ -15,7 +15,7 @@ const VERSION = "0.4.0";
|
|
|
15
15
|
function help() {
|
|
16
16
|
console.log(`macula-mcp status ${VERSION}
|
|
17
17
|
|
|
18
|
-
Usage:
|
|
18
|
+
Usage: macula-mcp-status
|
|
19
19
|
|
|
20
20
|
Read-only diagnostic. Reports macula-cli availability and MCP-client
|
|
21
21
|
configuration state.
|
|
@@ -45,7 +45,7 @@ async function main() {
|
|
|
45
45
|
await reportClient(client);
|
|
46
46
|
}
|
|
47
47
|
console.log("\n\"registered\" above means the config file has the right entry -- it does not");
|
|
48
|
-
console.log("prove the entry actually runs. Run `
|
|
48
|
+
console.log("prove the entry actually runs. Run `macula-mcp-doctor` for a real check.");
|
|
49
49
|
}
|
|
50
50
|
async function reportClient(c) {
|
|
51
51
|
const installed = c.isInstalled();
|
package/dist/bin/status.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/bin/status.ts"],"names":[],"mappings":";AACA,6CAA6C;AAC7C,qDAAqD;AACrD,sCAAsC;AACtC,qDAAqD;AACrD,EAAE;AACF,kEAAkE;AAClE,gBAAgB;AAEhB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,GAAG,EAAsB,MAAM,iCAAiC,CAAC;AAE1E,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,SAAS,IAAI;IACX,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO;;;;;;CAMzC,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,IAAI,EAAE,CAAC;QACP,OAAO;IACT,CAAC;IAED,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1B,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAC;IACzB,IAAI,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAChC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;QACxC,IAAI,EAAE,CAAC,MAAM;YAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,KAAK,MAAM,MAAM,IAAI,GAAG,EAAE,CAAC;QACzB,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/bin/status.ts"],"names":[],"mappings":"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"}
|
package/dist/bin/uninstall.js
CHANGED
|
@@ -24,7 +24,7 @@ function parseArgs(argv) {
|
|
|
24
24
|
function help() {
|
|
25
25
|
console.log(`macula-mcp uninstall ${VERSION}
|
|
26
26
|
|
|
27
|
-
Usage:
|
|
27
|
+
Usage: macula-mcp-uninstall [--all]
|
|
28
28
|
|
|
29
29
|
Removes the 'macula' MCP server entry from every detected MCP
|
|
30
30
|
client's config. The macula-cli binary and your persisted identity
|
package/dist/index.js
CHANGED
|
@@ -3,22 +3,26 @@
|
|
|
3
3
|
// any agent harness (Claude Code, Cursor, Cline, Continue, ...).
|
|
4
4
|
//
|
|
5
5
|
// Topology: thin client. macula-mcp speaks MCP over stdio to the agent, and
|
|
6
|
-
// shells out to macula-cli (macula-io/macula-cli), a
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
6
|
+
// shells out to macula-cli (macula-io/macula-cli), a scriptable CLI built
|
|
7
|
+
// directly on macula-go. macula-mcp owns no mesh logic of its own -- macula-cli
|
|
8
|
+
// does the QUIC handshake/call/publish/watch/content transfer, either as a
|
|
9
|
+
// one-shot subprocess per tool call, or (mesh_hello/mesh_goodbye/mesh_agents
|
|
10
|
+
// only, via presence.ts) as one long-lived `macula-cli daemon` this server
|
|
11
|
+
// manages internally for as long as it runs.
|
|
10
12
|
//
|
|
11
13
|
// agent harness --MCP/stdio--> macula-mcp --spawns, parses stdout--> macula-cli --QUIC--> mesh
|
|
12
14
|
//
|
|
13
15
|
// Reworked 2026-08-29 from a hecate-daemon-backed design (HTTP over a
|
|
14
|
-
// local Unix socket) to
|
|
15
|
-
// abandoned local browser/UI plan and is no longer
|
|
16
|
-
// should depend on.
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
16
|
+
// local Unix socket) to a one-shot-subprocess-per-call one: hecate-daemon is
|
|
17
|
+
// a leftover of an abandoned local browser/UI plan and is no longer
|
|
18
|
+
// something this server should depend on. That rework's own doc comment
|
|
19
|
+
// (see mesh_watch.ts) explained why a standing subscription wasn't rebuilt
|
|
20
|
+
// on top of macula-cli: it had no daemon of its own at the time, so
|
|
21
|
+
// mesh_watch (bounded, synchronous) replaced the old subscribe/unsubscribe/
|
|
22
|
+
// subscriptions/inbox quartet instead. macula-cli gained a real daemon mode
|
|
23
|
+
// later (2026-08-30) -- presence.ts is this server narrowly taking that
|
|
24
|
+
// fork back up, scoped to exactly one use (agent-presence heartbeat +
|
|
25
|
+
// roster), not a wholesale return to the old design.
|
|
22
26
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
23
27
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
24
28
|
import { registerIdentity } from "./mesh_identity.js";
|
|
@@ -28,6 +32,9 @@ import { registerMeshCall } from "./mesh_call.js";
|
|
|
28
32
|
import { registerMeshArtifact } from "./mesh_artifact.js";
|
|
29
33
|
import { registerMeshPublish } from "./mesh_publish.js";
|
|
30
34
|
import { registerMeshWatch } from "./mesh_watch.js";
|
|
35
|
+
import { registerMeshHello } from "./mesh_hello.js";
|
|
36
|
+
import { registerMeshGoodbye } from "./mesh_goodbye.js";
|
|
37
|
+
import { registerMeshAgents } from "./mesh_agents.js";
|
|
31
38
|
// Surfaced by every MCP client at connect time (the SDK's own
|
|
32
39
|
// ServerOptions.instructions), not something a model has to think to go
|
|
33
40
|
// read -- this is the mechanism for baking mesh-citizenship norms into
|
|
@@ -45,8 +52,11 @@ a response.
|
|
|
45
52
|
- Read mesh://identity first so you know which node ID you're acting as. Read mesh://etiquette \
|
|
46
53
|
for the full reasoning behind these rules. A person in this conversation can also ask for \
|
|
47
54
|
help directly (/mcp__macula__help and friends -- help_identity, help_wire_format, help_watch, \
|
|
48
|
-
help_install -- if their client supports MCP prompts)
|
|
49
|
-
|
|
55
|
+
help_presence, help_install -- if their client supports MCP prompts).
|
|
56
|
+
- mesh_hello announces this agent's presence (a periodic heartbeat plus a live roster of other \
|
|
57
|
+
agents heard from) -- call it once if you want to be discoverable, then mesh_agents to see who \
|
|
58
|
+
else is around. Call mesh_goodbye to leave deliberately rather than just going quiet.`;
|
|
59
|
+
const server = new McpServer({ name: "macula-mcp", version: "0.5.0" }, { instructions: INSTRUCTIONS });
|
|
50
60
|
// Resources — read-only context an agent should consult before acting.
|
|
51
61
|
registerIdentity(server);
|
|
52
62
|
registerEtiquette(server);
|
|
@@ -58,6 +68,13 @@ registerMeshCall(server);
|
|
|
58
68
|
registerMeshArtifact(server);
|
|
59
69
|
registerMeshPublish(server);
|
|
60
70
|
registerMeshWatch(server);
|
|
71
|
+
// mesh_hello/mesh_goodbye are the one exception to "one-shot": together
|
|
72
|
+
// they manage this process's own standing presence (heartbeat +
|
|
73
|
+
// subscriptions), see presence.ts's own doc comment for why that's a
|
|
74
|
+
// deliberate, narrow departure from every other tool here.
|
|
75
|
+
registerMeshHello(server);
|
|
76
|
+
registerMeshGoodbye(server);
|
|
77
|
+
registerMeshAgents(server);
|
|
61
78
|
async function main() {
|
|
62
79
|
const transport = new StdioServerTransport();
|
|
63
80
|
await server.connect(transport);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,+EAA+E;AAC/E,iEAAiE;AACjE,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,+EAA+E;AAC/E,iEAAiE;AACjE,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,6CAA6C;AAC7C,EAAE;AACF,uGAAuG;AACvG,EAAE;AACF,sEAAsE;AACtE,6EAA6E;AAC7E,oEAAoE;AACpE,wEAAwE;AACxE,2EAA2E;AAC3E,oEAAoE;AACpE,4EAA4E;AAC5E,4EAA4E;AAC5E,wEAAwE;AACxE,sEAAsE;AACtE,qDAAqD;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,8DAA8D;AAC9D,wEAAwE;AACxE,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,iEAAiE;AACjE,MAAM,YAAY,GAAG;;;;;;;;;;;;;;sFAciE,CAAC;AAEvF,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,EACxC,EAAE,YAAY,EAAE,YAAY,EAAE,CAC/B,CAAC;AAEF,uEAAuE;AACvE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE1B,uEAAuE;AACvE,8DAA8D;AAC9D,YAAY,CAAC,MAAM,CAAC,CAAC;AAErB,+DAA+D;AAC/D,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE1B,wEAAwE;AACxE,gEAAgE;AAChE,qEAAqE;AACrE,2DAA2D;AAC3D,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE3B,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,6CAA6C;IAC7C,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC5C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/macula_cli.d.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
/** The station this server targets when a tool call doesn't override it. */
|
|
2
2
|
export declare function defaultStation(): string;
|
|
3
|
+
/** Name/path of the macula-cli binary; override for testing or a non-PATH install. */
|
|
4
|
+
export declare function binPath(): string;
|
|
5
|
+
export declare function onShutdown(fn: () => void): void;
|
|
3
6
|
/** Exported for mesh_identity.ts (the mesh://identity resource) and for tests. */
|
|
4
7
|
export declare function defaultIdentityPath(): string;
|
|
8
|
+
/**
|
|
9
|
+
* A THIRD identity, dedicated to presence.ts's own daemon (agent.hello/
|
|
10
|
+
* agent.goodbye subscriptions) -- separate from "default" and "watch"
|
|
11
|
+
* for the same reason those two are already separate from each other:
|
|
12
|
+
* two connections sharing one node ID get the second one kicked by the
|
|
13
|
+
* station (see watchIdentityPath's own doc). The presence daemon holds
|
|
14
|
+
* a connection open for as long as this process runs, so it must never
|
|
15
|
+
* share an identity with anything else that might connect concurrently.
|
|
16
|
+
*/
|
|
17
|
+
export declare function presenceIdentityPath(): string;
|
|
5
18
|
/** Exported for tests only -- no other module needs it, mesh_watch calls watch() directly. */
|
|
6
19
|
export declare function watchIdentityPath(): string;
|
|
7
20
|
export declare class MaculaCliUnavailable extends Error {
|
|
@@ -26,8 +39,12 @@ export declare class MaculaCliError extends Error {
|
|
|
26
39
|
* call -- exactly the shape `mesh_publish` uses -- with zero error
|
|
27
40
|
* surfaced anywhere. Bump this constant whenever a macula-cli fix this
|
|
28
41
|
* server's own tools depend on ships in a new release.
|
|
42
|
+
*
|
|
43
|
+
* Bumped to 0.2.0 for presence.ts: mesh_hello/mesh_goodbye/mesh_agents
|
|
44
|
+
* depend on `macula-cli daemon` and `pubsub watch -daemon`/-subscribe,
|
|
45
|
+
* both new in that release -- v0.1.x has no daemon subcommand at all.
|
|
29
46
|
*/
|
|
30
|
-
export declare const MIN_MACULA_CLI_VERSION = "0.
|
|
47
|
+
export declare const MIN_MACULA_CLI_VERSION = "0.2.0";
|
|
31
48
|
export interface CliVersionCheck {
|
|
32
49
|
ok: boolean;
|
|
33
50
|
/** The raw `macula-cli --version` output, or undefined if it couldn't be run at all. */
|
|
@@ -103,6 +120,18 @@ export interface WatchEvent {
|
|
|
103
120
|
* Exported standalone so this parsing can be unit-tested without
|
|
104
121
|
* spawning a real subprocess.
|
|
105
122
|
*/
|
|
123
|
+
/**
|
|
124
|
+
* Parses ONE line of `pubsub watch --json` output -- the same per-line
|
|
125
|
+
* shape parseWatchOutput batch-parses after a bounded watch's process
|
|
126
|
+
* exits, factored out so presence.ts's long-lived subscription (which
|
|
127
|
+
* never exits under normal operation, so there's no final stdout
|
|
128
|
+
* string to batch-parse) can apply it incrementally as lines stream
|
|
129
|
+
* in. Returns null for a blank line or a trailing {"ok":true,...}
|
|
130
|
+
* envelope (not expected in this format, but skipped rather than
|
|
131
|
+
* misparsed as an event); throws MaculaCliError on a trailing
|
|
132
|
+
* {"ok":false,...} failure envelope.
|
|
133
|
+
*/
|
|
134
|
+
export declare function parseWatchLine(line: string): WatchEvent | null;
|
|
106
135
|
export declare function parseWatchOutput(stdout: string): WatchEvent[];
|
|
107
136
|
/**
|
|
108
137
|
* Watches a topic for up to durationSeconds and returns whatever
|
package/dist/macula_cli.js
CHANGED
|
@@ -24,9 +24,25 @@ export function defaultStation() {
|
|
|
24
24
|
return process.env.MACULA_MESH_STATION ?? "station-de-frankfurt.macula.io:4433";
|
|
25
25
|
}
|
|
26
26
|
/** Name/path of the macula-cli binary; override for testing or a non-PATH install. */
|
|
27
|
-
function binPath() {
|
|
27
|
+
export function binPath() {
|
|
28
28
|
return process.env.MACULA_CLI_BIN ?? "macula-cli";
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Cleanup hooks run once, synchronously, before this process actually
|
|
32
|
+
* exits -- registered here rather than each module adding its own
|
|
33
|
+
* process.on(SIGINT/SIGTERM) listener, since Node calls every listener
|
|
34
|
+
* for the same signal in registration order and the FIRST one
|
|
35
|
+
* registered below already calls process.exit() itself. A second,
|
|
36
|
+
* independently-registered listener (e.g. presence.ts's own child
|
|
37
|
+
* process cleanup) racing to run before that exit actually happens is
|
|
38
|
+
* not something to depend on -- this registry makes the ordering
|
|
39
|
+
* deterministic instead: everything registered here is guaranteed to
|
|
40
|
+
* run first, regardless of which module imported this one when.
|
|
41
|
+
*/
|
|
42
|
+
const shutdownHooks = [];
|
|
43
|
+
export function onShutdown(fn) {
|
|
44
|
+
shutdownHooks.push(fn);
|
|
45
|
+
}
|
|
30
46
|
/**
|
|
31
47
|
* Per-server-process identities, freshly minted (temp dir, deleted on
|
|
32
48
|
* exit) rather than macula-cli's own shared machine-wide default.
|
|
@@ -89,8 +105,19 @@ process.on("exit", () => {
|
|
|
89
105
|
// Node doesn't fire "exit" on a bare SIGINT/SIGTERM unless the process
|
|
90
106
|
// actually exits; without this, Ctrl-C or a client-initiated shutdown
|
|
91
107
|
// would skip the cleanup above and leak a temp identity file per run.
|
|
108
|
+
// shutdownHooks run first and synchronously -- see onShutdown's own doc.
|
|
92
109
|
for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
93
|
-
process.on(sig, () =>
|
|
110
|
+
process.on(sig, () => {
|
|
111
|
+
for (const fn of shutdownHooks) {
|
|
112
|
+
try {
|
|
113
|
+
fn();
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// best effort -- a hook failing shouldn't block the others or the exit
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
process.exit(0);
|
|
120
|
+
});
|
|
94
121
|
}
|
|
95
122
|
let cachedDefaultIdentityPath;
|
|
96
123
|
/** Exported for mesh_identity.ts (the mesh://identity resource) and for tests. */
|
|
@@ -99,6 +126,21 @@ export function defaultIdentityPath() {
|
|
|
99
126
|
return process.env.MACULA_MCP_IDENTITY;
|
|
100
127
|
return (cachedDefaultIdentityPath ??= mintIdentityPath("default"));
|
|
101
128
|
}
|
|
129
|
+
let cachedPresenceIdentityPath;
|
|
130
|
+
/**
|
|
131
|
+
* A THIRD identity, dedicated to presence.ts's own daemon (agent.hello/
|
|
132
|
+
* agent.goodbye subscriptions) -- separate from "default" and "watch"
|
|
133
|
+
* for the same reason those two are already separate from each other:
|
|
134
|
+
* two connections sharing one node ID get the second one kicked by the
|
|
135
|
+
* station (see watchIdentityPath's own doc). The presence daemon holds
|
|
136
|
+
* a connection open for as long as this process runs, so it must never
|
|
137
|
+
* share an identity with anything else that might connect concurrently.
|
|
138
|
+
*/
|
|
139
|
+
export function presenceIdentityPath() {
|
|
140
|
+
if (process.env.MACULA_MCP_PRESENCE_IDENTITY)
|
|
141
|
+
return process.env.MACULA_MCP_PRESENCE_IDENTITY;
|
|
142
|
+
return (cachedPresenceIdentityPath ??= mintIdentityPath("presence"));
|
|
143
|
+
}
|
|
102
144
|
let cachedWatchIdentityPath;
|
|
103
145
|
/** Exported for tests only -- no other module needs it, mesh_watch calls watch() directly. */
|
|
104
146
|
export function watchIdentityPath() {
|
|
@@ -176,8 +218,12 @@ function execFile(bin, args) {
|
|
|
176
218
|
* call -- exactly the shape `mesh_publish` uses -- with zero error
|
|
177
219
|
* surfaced anywhere. Bump this constant whenever a macula-cli fix this
|
|
178
220
|
* server's own tools depend on ships in a new release.
|
|
221
|
+
*
|
|
222
|
+
* Bumped to 0.2.0 for presence.ts: mesh_hello/mesh_goodbye/mesh_agents
|
|
223
|
+
* depend on `macula-cli daemon` and `pubsub watch -daemon`/-subscribe,
|
|
224
|
+
* both new in that release -- v0.1.x has no daemon subcommand at all.
|
|
179
225
|
*/
|
|
180
|
-
export const MIN_MACULA_CLI_VERSION = "0.
|
|
226
|
+
export const MIN_MACULA_CLI_VERSION = "0.2.0";
|
|
181
227
|
/**
|
|
182
228
|
* Parses "X.Y.Z" (optionally "vX.Y.Z") out of an arbitrary string;
|
|
183
229
|
* undefined if none found. Exported standalone so this parsing can be
|
|
@@ -256,27 +302,43 @@ export const publish = (args) => run(argv(["pubsub", "publish"], ["--identity",
|
|
|
256
302
|
* Exported standalone so this parsing can be unit-tested without
|
|
257
303
|
* spawning a real subprocess.
|
|
258
304
|
*/
|
|
305
|
+
/**
|
|
306
|
+
* Parses ONE line of `pubsub watch --json` output -- the same per-line
|
|
307
|
+
* shape parseWatchOutput batch-parses after a bounded watch's process
|
|
308
|
+
* exits, factored out so presence.ts's long-lived subscription (which
|
|
309
|
+
* never exits under normal operation, so there's no final stdout
|
|
310
|
+
* string to batch-parse) can apply it incrementally as lines stream
|
|
311
|
+
* in. Returns null for a blank line or a trailing {"ok":true,...}
|
|
312
|
+
* envelope (not expected in this format, but skipped rather than
|
|
313
|
+
* misparsed as an event); throws MaculaCliError on a trailing
|
|
314
|
+
* {"ok":false,...} failure envelope.
|
|
315
|
+
*/
|
|
316
|
+
export function parseWatchLine(line) {
|
|
317
|
+
const trimmed = line.trim();
|
|
318
|
+
if (!trimmed)
|
|
319
|
+
return null;
|
|
320
|
+
let parsed;
|
|
321
|
+
try {
|
|
322
|
+
parsed = JSON.parse(trimmed);
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return null; // not JSON at all; ignore this line
|
|
326
|
+
}
|
|
327
|
+
if (parsed !== null && typeof parsed === "object" && "ok" in parsed) {
|
|
328
|
+
const envelope = parsed;
|
|
329
|
+
if (envelope.ok === false) {
|
|
330
|
+
throw new MaculaCliError(envelope.error?.message ?? "pubsub watch failed");
|
|
331
|
+
}
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
return parsed;
|
|
335
|
+
}
|
|
259
336
|
export function parseWatchOutput(stdout) {
|
|
260
337
|
const events = [];
|
|
261
338
|
for (const line of stdout.split("\n")) {
|
|
262
|
-
const
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
let parsed;
|
|
266
|
-
try {
|
|
267
|
-
parsed = JSON.parse(trimmed);
|
|
268
|
-
}
|
|
269
|
-
catch {
|
|
270
|
-
continue; // not JSON at all; ignore this line
|
|
271
|
-
}
|
|
272
|
-
if (parsed !== null && typeof parsed === "object" && "ok" in parsed) {
|
|
273
|
-
const envelope = parsed;
|
|
274
|
-
if (envelope.ok === false) {
|
|
275
|
-
throw new MaculaCliError(envelope.error?.message ?? "pubsub watch failed");
|
|
276
|
-
}
|
|
277
|
-
continue; // an {"ok":true,...} envelope line isn't expected here, but skip rather than misparse it as an event
|
|
278
|
-
}
|
|
279
|
-
events.push(parsed);
|
|
339
|
+
const evt = parseWatchLine(line);
|
|
340
|
+
if (evt)
|
|
341
|
+
events.push(evt);
|
|
280
342
|
}
|
|
281
343
|
return events;
|
|
282
344
|
}
|