@getmarrow/mcp 3.9.99 → 3.9.101

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 CHANGED
@@ -10,6 +10,25 @@ Marrow AI is the runtime control and proof layer for teams running AI agents. It
10
10
 
11
11
  Use `@getmarrow/mcp` when your agent client supports the Model Context Protocol and you want Marrow available inside the agent's normal workflow. It works with Claude Code, Claude Desktop, Cursor and other MCP-compatible clients without replacing the model or harness.
12
12
 
13
+ ## Quick start
14
+
15
+ 1. **Create a key.** Sign up at [getmarrow.ai/signup](https://getmarrow.ai/signup), then open the dashboard, go to **API keys** and choose **Create API key**. The key is shown once.
16
+ 2. **Activate.** Make the key available as `MARROW_API_KEY` (from your secret storage, or an owner-only `~/.marrow/env`), then run the installer from a terminal:
17
+
18
+ ```bash
19
+ npx -y @getmarrow/install@latest activate
20
+ ```
21
+
22
+ Fallback if you cannot set the key first (a key typed on a command line stays in your shell history): `MARROW_API_KEY=<your_key> npx -y @getmarrow/install@latest activate`.
23
+ 3. **Restart** the agent host and review/enable its hook trust.
24
+ 4. **Verify:**
25
+
26
+ ```bash
27
+ npx -y @getmarrow/install@latest doctor --self-test
28
+ ```
29
+
30
+ **What is enforced.** On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks let actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it. Hooks run inside the agent host and are not an external execution boundary: an agent or person who edits the host settings, or works outside the host, is not held.
31
+
13
32
  ## Agent Discovery
14
33
 
15
34
  - **Publisher:** Marrow AI. Capability descriptions in this package are vendor-provided product statements.
@@ -60,14 +79,22 @@ Verify current claims through the [public evidence manifest](https://getmarrow.a
60
79
 
61
80
  ## Install
62
81
 
82
+ For most installations, follow the [Quick start](#quick-start): the universal installer's `activate` command. The steps below are the manual, MCP-only route.
83
+
84
+ Get a key at [getmarrow.ai/signup](https://getmarrow.ai/signup) and keep it in an owner-only key file: put `MARROW_API_KEY=<your_key>` in `~/.marrow/env`, then run `chmod 700 ~/.marrow && chmod 600 ~/.marrow/env` (Marrow rejects a key file whose folder others can write):
85
+
63
86
  ```bash
64
- npx -y --package=@getmarrow/mcp@latest marrow-mcp setup
87
+ mkdir -p ~/.marrow && chmod 700 ~/.marrow
88
+ # put MARROW_API_KEY=<your_key> in ~/.marrow/env
89
+ chmod 600 ~/.marrow/env
65
90
  ```
66
91
 
67
- Set the key through trusted secret storage:
92
+ Fallback if you cannot use the key file (a key typed on a command line stays in your shell history): set it through trusted secret storage, or `export MARROW_API_KEY=<your_key>` for the session.
93
+
94
+ Hooks-only setup (`marrow-mcp setup` writes hooks and `CLAUDE.md` instructions, and adds no MCP server). It needs the key first: without one it prints how to get it and exits 2 before writing anything.
68
95
 
69
96
  ```bash
70
- export MARROW_API_KEY=mrw_live_...
97
+ npx -y --package=@getmarrow/mcp@latest marrow-mcp setup
71
98
  ```
72
99
 
73
100
  For Claude Code's cooperative pre-action hook, Marrow accepts the process environment or an owner-controlled `~/.marrow/env` file with owner-only permissions. Repository-local `.env` files are intentionally ignored so project content cannot replace the account, agent, or API endpoint used for guidance. The public hook callback is still a client self-report, not certified host provenance or an external enforcement boundary.
@@ -85,12 +112,6 @@ Then configure the MCP server:
85
112
  }
86
113
  ```
87
114
 
88
- For most new installations, start with the universal installer instead:
89
-
90
- ```bash
91
- npx @getmarrow/install activate
92
- ```
93
-
94
115
  After setup writes MCP configuration or hooks, restart the agent host and review/enable its hook trust. Then verify the reloaded environment:
95
116
 
96
117
  ```bash
@@ -134,20 +155,25 @@ A direct `marrow_think` can receive a durable pending response before the backen
134
155
 
135
156
  A saved `observed_unverified` outcome is terminal observation evidence, not a committed outcome. Receipt expiry cannot retroactively authorize completed work. Preserve the original decision, receipt, proof and key; an already authorized durable checkpoint may finish through its existing exact recovery path. Do not repeat the action merely to obtain a fresh receipt.
136
157
 
137
- ## What's New in v3.9.99
158
+ ## Hook behavior details
159
+
160
+ These behaviors shipped in 3.9.100 and still apply.
138
161
 
139
- v3.9.99 lets people approve held actions where they already work, and nobody has to log in. See [Approvals in the Host Prompt](#approvals-in-the-host-prompt).
162
+ - **One Marrow entry per hook event:** `marrow-mcp setup` recognizes the installer's local-runtime hook commands exactly (same version throughout, no additions), keeps whichever form is there (local runtime or npx), and never adds a second entry. Your own hooks stay as they are.
163
+ - **Plain words without a key:** a protected action with no Marrow key is denied with "Marrow has no API key on this machine. Owner: create one at getmarrow.ai/signup, then run the installer activate command in a terminal. Do not retry this action." The hooks read the key from `MARROW_API_KEY` or an owner-only `~/.marrow/env.local` or `~/.marrow/env`, never from a file others can read.
164
+ - **First-prompt briefs say so:** the prompt hook marks its brief `context.prompt_brief: true`; a brief authorizes nothing.
165
+ - **Deploy text only word for word:** the exact command text is sent only for `sst deploy --stage <stage>` (optionally `--verbose`, optionally after one `npx` or `bunx`), with a stage of lower-case letters, digits and dashes, in a single clause with nothing else in it, so Marrow can judge the stage itself. Every other command, including other deploy tools, sends only the hash; no free-text word leaves the machine.
166
+ - **No lifecycle event id with two payloads:** an event id names its payload, so a later run is a new record and a resend carries the same bytes.
140
167
 
141
- These approvals turn on when the Marrow service update ships; until then held actions work as in 3.9.98: Claude Code asks in its dialog and other hosts hold for the account owner.
168
+ ## What's New in v3.9.101
142
169
 
143
- - **Approvals in the host prompt:** one click in the host's own permission prompt, a short typed reply where a host has no dialog, or no ask at all for routine work. `marrow-mcp setup` adds Claude Code's `PermissionRequest` and `PostToolBatch` hooks.
144
- - **Quiet holds:** unattended runs, and hosts that cannot ask, hold the action without emailing anyone; the person sees the waiting actions at their next interactive session.
145
- - **The exact action, never its text:** `normalized_action` binds an approval to the exact command; only program names and a SHA-256 of a normalized, secret-free form leave the machine.
146
- - **Slow is not down:** a slow Marrow keeps holdable actions held, within each host's hook time limit.
147
- - **`marrow_auto`** waits on the approval status and resumes on the same gate receipt. New `request_owner_link` parameter.
148
- - **Plain fixes:** a refused protected action names what to do next, and a `marrow_commit` retry that conflicts with the stored outcome lists the proof that is still missing.
149
- - **New registry name:** the MCP Registry name moves from `io.github.getmarrow/marrow` to `ai.getmarrow/marrow`, with a title, website and icon. The npm package name `@getmarrow/mcp` and its commands are unchanged, so existing `npx` configurations keep working.
150
- - On a service without host approvals, Claude Code asks in its dialog as 3.9.98 did. SDK `3.7.65`.
170
+ - **Setup with no key stops:** `marrow-mcp setup` with no key, or with a key only in an untrusted place such as a project `.env`, now stops, writes nothing and tells you how to get a key.
171
+ - **Keys are read from trusted places only:** setup reads a key only from the environment or an owner-only `~/.marrow/env`.
172
+ - **Key-file steps are safer:** they now include `chmod 700 ~/.marrow` before `chmod 600 ~/.marrow/env`.
173
+ - **Hold messages say where to approve:** a held action now says how to approve it where your host really asks.
174
+ - **One enforcement sentence:** the "what is enforced" wording now matches the public site.
175
+
176
+ The 3.9.100 behaviors are kept under [Hook behavior details](#hook-behavior-details). v3.9.99 brought approvals in the host prompt; see [Approvals in the Host Prompt](#approvals-in-the-host-prompt).
151
177
 
152
178
  Earlier release notes moved from this README to [CHANGELOG.md](https://github.com/getmarrow/marrow-mcp/blob/master/CHANGELOG.md).
153
179
 
@@ -165,7 +191,7 @@ Direct `marrow_model_usage` and Commit `model_usage` also accept billing host, t
165
191
 
166
192
  With `MARROW_TOOL_PROFILE` unset, the default primary profile uses `marrow_agent_runtime` followed by `marrow_commit`. It exposes 17 tools; `marrow_auto` is available only after an explicit `core` or `full` selection and MCP restart. Primary status and lessons use `marrow_agent_status` and `marrow_fleet_lessons`.
167
193
 
168
- Configured hooks can provide cooperative telemetry and context, but they are not a certified execution boundary. Before deploys, merges, publishes, migrations, credential changes, financial operations, or customer-impacting work:
194
+ On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks let actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it. Hooks run inside the agent host, so a host edited or bypassed by an agent or person is not held. Before deploys, merges, publishes, migrations, credential changes, financial operations, or customer-impacting work:
169
195
 
170
196
  1. Call `marrow_agent_runtime` or `marrow_decision_brief`.
171
197
  2. Stop when the returned decision is `block` or `review_required`; otherwise follow its prior lesson and proof contract.
@@ -282,8 +308,6 @@ it does not run models, retain prompts, or infer a winner from labels.
282
308
 
283
309
  ## Approvals in the Host Prompt
284
310
 
285
- These approvals turn on when the Marrow service update ships; until then held actions work as in 3.9.98: Claude Code asks in its dialog and other hosts hold for the account owner.
286
-
287
311
  When Marrow holds an action for approval (`review_required`), the person approves it where they already work, and nobody has to log in. The hooks record the answer with Marrow; the agent never reports or claims an approval. The Marrow dashboard shows receipts and history; it is not where approvals happen.
288
312
 
289
313
  | Host and session | What the person does |
@@ -293,7 +317,7 @@ When Marrow holds an action for approval (`review_required`), the person approve
293
317
  | Codex and Gemini CLI, local interactive session with their own approval prompt on | Types the reply the hook showed them only, such as `marrow approve CODE` |
294
318
  | MCP clients with elicitation (`marrow_auto`) | Answers the client's own dialog (client-attested) |
295
319
  | Codex TUI before its prompt hook, Cline and Windsurf in the editor | Uses the host's own approval step, if they have it on: the hook answers neutrally, never with an explicit allow, and Marrow records the result as not observed by Marrow |
296
- | Grok, Gemini without its prompt hook, Cursor at `preToolUse` and Cursor's other tools, Codex with its approval prompt off, Gemini CLI in YOLO mode (`--yolo`, `-y`, `--approval-mode yolo`), or no evidence of a person | No typed reply and no code (the agent could answer one itself); the action waits quietly for the owner |
320
+ | Grok, Gemini without its prompt hook, Cursor at `preToolUse` and Cursor's other tools, Codex with its approval prompt off, Gemini CLI in any mode but `default` (`--yolo`, `-y`, `--approval-mode`, or `general.defaultApprovalMode` in its system, user or project `settings.json`, or shell commands allowed without asking, or a settings file it cannot read), or no evidence of a person | No typed reply and no code (the agent could answer one itself); the action waits quietly for the owner |
297
321
  | Unattended runs (headless Claude Code, `codex exec`, `gemini -p`, Cursor cloud) | Nothing in the run: the action waits quietly and the agent carries on |
298
322
  | Arbitration review | The account owner picks one proposal through a one-tap link |
299
323
 
package/dist/cli.d.ts CHANGED
@@ -4,9 +4,8 @@
4
4
  * Exposes pre-action governance, intent capture, outcome closure, and fleet evidence.
5
5
  *
6
6
  * Usage:
7
- * npx @getmarrow/mcp (reads MARROW_API_KEY from env)
8
- * npx @getmarrow/mcp --key mrw_abc123 (pass key via CLI flag)
9
- * MARROW_API_KEY=mrw_abc123 npx @getmarrow/mcp
7
+ * npx @getmarrow/mcp (reads MARROW_API_KEY from env or an owner-only ~/.marrow/env)
8
+ * npx @getmarrow/mcp --help
10
9
  */
11
10
  export {};
12
11
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
package/dist/cli.js CHANGED
@@ -5,9 +5,8 @@
5
5
  * Exposes pre-action governance, intent capture, outcome closure, and fleet evidence.
6
6
  *
7
7
  * Usage:
8
- * npx @getmarrow/mcp (reads MARROW_API_KEY from env)
9
- * npx @getmarrow/mcp --key mrw_abc123 (pass key via CLI flag)
10
- * MARROW_API_KEY=mrw_abc123 npx @getmarrow/mcp
8
+ * npx @getmarrow/mcp (reads MARROW_API_KEY from env or an owner-only ~/.marrow/env)
9
+ * npx @getmarrow/mcp --help
11
10
  */
12
11
  Object.defineProperty(exports, "__esModule", { value: true });
13
12
  const node_crypto_1 = require("node:crypto");
@@ -42,6 +41,9 @@ function parseArgs() {
42
41
  result.apiKey = args[i + 1];
43
42
  i++;
44
43
  }
44
+ if (args[i] === '--help' || args[i] === '-h') {
45
+ result.help = true;
46
+ }
45
47
  if (args[i] === 'setup' || args[i] === '--setup') {
46
48
  result.setup = true;
47
49
  }
@@ -221,10 +223,43 @@ async function runSpoolCommand(drain) {
221
223
  if (outcome.exitCode !== 0)
222
224
  process.exitCode = outcome.exitCode;
223
225
  }
226
+ const GET_A_KEY_URL = 'https://getmarrow.ai/signup';
227
+ const ACTIVATE_COMMAND = 'npx -y @getmarrow/install@latest activate';
228
+ const ENFORCEMENT_SENTENCE = 'On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks let actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it.';
229
+ const HELP_TEXT = `Marrow MCP server and hook commands (@getmarrow/mcp)
230
+
231
+ Day one:
232
+ 1. Create a key at ${GET_A_KEY_URL} (dashboard -> API keys).
233
+ 2. Make the key available as MARROW_API_KEY (environment or an owner-only ~/.marrow/env), then run:
234
+ ${ACTIVATE_COMMAND}
235
+ Fallback if you cannot set it first (a key typed on a command line stays in shell history):
236
+ MARROW_API_KEY=<your_key> ${ACTIVATE_COMMAND}
237
+ 3. Restart the agent host and review/enable its hook trust.
238
+ 4. Verify: npx -y @getmarrow/install@latest doctor --self-test
239
+
240
+ Commands:
241
+ (none) start the MCP server on stdio (needs MARROW_API_KEY)
242
+ setup hooks-only setup; needs the key first and writes nothing without it
243
+ ping check live read latency, last success and local backlog
244
+ spool-status show the local lifecycle spool
245
+ drain-spool deliver the local lifecycle spool
246
+ loop-guard-self-test offline check of the local session loop guard
247
+ keys <create|list|get|rotate|revoke|audit> manage API keys
248
+ --help, -h show this text (works without a key)
249
+
250
+ ${ENFORCEMENT_SENTENCE}
251
+ Hooks run inside the agent host and are not an external execution boundary: an agent or person who edits the host settings or runs outside the host is not held.
252
+ `;
224
253
  // ─── Setup command: inject Marrow instructions into CLAUDE.md ───
225
254
  function runSetup() {
226
255
  const fs = require('fs');
227
256
  const path = require('path');
257
+ // Hooks without a key deny protected actions, so write nothing until a key exists.
258
+ // Same trusted resolution the installed hooks use: project .env files and non-private owner files cannot supply the key.
259
+ if (!(0, env_1.resolveMarrowEnv)({ trustedOnly: true }).apiKey) {
260
+ process.stderr.write(`Marrow needs your API key before setup can write hooks, so nothing was written.\nCreate a key at ${GET_A_KEY_URL}, make it available as MARROW_API_KEY (environment or an owner-only ~/.marrow/env), then run:\n ${ACTIVATE_COMMAND}\nFallback: MARROW_API_KEY=<your_key> ${ACTIVATE_COMMAND} (a key typed on a command line stays in shell history)\n`);
261
+ process.exit(2);
262
+ }
228
263
  const MARROW_BLOCK_START = '<!-- marrow:start -->';
229
264
  const MARROW_BLOCK_END = '<!-- marrow:end -->';
230
265
  const marrowInstructions = `${MARROW_BLOCK_START}
@@ -341,6 +376,11 @@ ${MARROW_BLOCK_END}`;
341
376
  process.exit(0);
342
377
  }
343
378
  const cliArgs = parseArgs();
379
+ // Never for a hook entrypoint: a hook that sees -h must still run its check.
380
+ if (cliArgs.help && !(cliArgs.hook || cliArgs.contextHook || cliArgs.preActionHook || cliArgs.sessionHook || cliArgs.permissionRequestHook || cliArgs.backgroundNudge)) {
381
+ process.stdout.write(HELP_TEXT);
382
+ process.exit(0);
383
+ }
344
384
  function formatKeyMaterialWarning() {
345
385
  return 'Copy this key now. Marrow will only show the full plaintext key once.';
346
386
  }
@@ -488,8 +528,7 @@ if (process.argv[2] !== 'keys') {
488
528
  if (!API_KEY) {
489
529
  process.stderr.write('Error: MARROW_API_KEY environment variable is required\n');
490
530
  process.stderr.write(`${resolvedEnv.exactFix}\n`);
491
- process.stderr.write('Usage: MARROW_API_KEY=mrw_yourkey npx @getmarrow/mcp\n');
492
- process.stderr.write(' or: npx @getmarrow/mcp --key mrw_yourkey\n');
531
+ process.stderr.write(`Get a key: ${GET_A_KEY_URL}. Day-one steps and commands: npx @getmarrow/mcp --help\n`);
493
532
  process.exit(1);
494
533
  }
495
534
  // [SECURITY #12] Warn if API key is visible in process args