@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 +48 -24
- package/dist/cli.d.ts +2 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +44 -5
- package/dist/cli.js.map +1 -1
- package/dist/hook-context.d.ts.map +1 -1
- package/dist/hook-context.js +7 -7
- package/dist/hook-context.js.map +1 -1
- package/dist/hook-contract.d.ts +10 -2
- package/dist/hook-contract.d.ts.map +1 -1
- package/dist/hook-contract.js +82 -8
- package/dist/hook-contract.js.map +1 -1
- package/dist/hook-pre-action.d.ts +4 -1
- package/dist/hook-pre-action.d.ts.map +1 -1
- package/dist/hook-pre-action.js +34 -36
- package/dist/hook-pre-action.js.map +1 -1
- package/dist/hook-session.js +3 -3
- package/dist/hook-session.js.map +1 -1
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +3 -7
- package/dist/hook.js.map +1 -1
- package/dist/host-session.d.ts +24 -2
- package/dist/host-session.d.ts.map +1 -1
- package/dist/host-session.js +172 -14
- package/dist/host-session.js.map +1 -1
- package/dist/lifecycle-spool.d.ts +17 -0
- package/dist/lifecycle-spool.d.ts.map +1 -1
- package/dist/lifecycle-spool.js +33 -4
- package/dist/lifecycle-spool.js.map +1 -1
- package/dist/normalized-action.d.ts +11 -0
- package/dist/normalized-action.d.ts.map +1 -1
- package/dist/normalized-action.js +96 -2
- package/dist/normalized-action.js.map +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
158
|
+
## Hook behavior details
|
|
159
|
+
|
|
160
|
+
These behaviors shipped in 3.9.100 and still apply.
|
|
138
161
|
|
|
139
|
-
|
|
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
|
-
|
|
168
|
+
## What's New in v3.9.101
|
|
142
169
|
|
|
143
|
-
- **
|
|
144
|
-
- **
|
|
145
|
-
- **
|
|
146
|
-
- **
|
|
147
|
-
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
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
|
|
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 --
|
|
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
|
|
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 --
|
|
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(
|
|
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
|