@getmarrow/mcp 3.9.42 → 3.9.44

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/dist/cli.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Marrow MCP stdio server — collective memory for Claude and MCP agents.
4
- * Exposes: marrow_orient (call first!), marrow_think, marrow_commit, marrow_status
3
+ * Marrow MCP stdio server - runtime control and proof for MCP-compatible agents.
4
+ * Exposes pre-action governance, intent capture, outcome closure, and fleet evidence.
5
5
  *
6
6
  * Usage:
7
7
  * npx @getmarrow/mcp (reads MARROW_API_KEY from env)
package/dist/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
  /**
4
- * Marrow MCP stdio server — collective memory for Claude and MCP agents.
5
- * Exposes: marrow_orient (call first!), marrow_think, marrow_commit, marrow_status
4
+ * Marrow MCP stdio server - runtime control and proof for MCP-compatible agents.
5
+ * Exposes pre-action governance, intent capture, outcome closure, and fleet evidence.
6
6
  *
7
7
  * Usage:
8
8
  * npx @getmarrow/mcp (reads MARROW_API_KEY from env)
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  const index_1 = require("./index");
14
14
  const hook_1 = require("./hook");
15
15
  const hook_context_1 = require("./hook-context");
16
+ const hook_session_1 = require("./hook-session");
16
17
  const env_1 = require("./env");
17
18
  const redact_1 = require("./redact");
18
19
  // Parse CLI args
@@ -33,6 +34,9 @@ function parseArgs() {
33
34
  if (args[i] === 'context-hook' || args[i] === '--context-hook') {
34
35
  result.contextHook = true;
35
36
  }
37
+ if (args[i] === 'session-hook' || args[i] === '--session-hook') {
38
+ result.sessionHook = true;
39
+ }
36
40
  }
37
41
  return result;
38
42
  }
@@ -43,18 +47,18 @@ function runSetup() {
43
47
  const MARROW_BLOCK_START = '<!-- marrow:start -->';
44
48
  const MARROW_BLOCK_END = '<!-- marrow:end -->';
45
49
  const marrowInstructions = `${MARROW_BLOCK_START}
46
- ## Marrow — Decision Memory (auto-injected by @getmarrow/mcp setup)
50
+ ## Marrow — Agent Control and Proof (auto-injected by @getmarrow/mcp setup)
47
51
 
48
52
  You have Marrow MCP connected. Use it on EVERY session automatically:
49
53
 
50
- 1. **Passive by default:** Marrow hooks auto-log meaningful tool use and auto-inject relevant warnings, patterns, and risky-work decision briefs into your prompt context.
51
- 2. **Session start:** Call \`marrow_orient\` FIRST before any work when you need an explicit status read.
52
- 3. **Before risky actions:** The prompt hook automatically calls \`marrow_decision_brief\` for deploys, publishes, merges, audits, patches, secret changes, and production work. If you need stronger control, call it explicitly.
53
- 4. **Before acting:** Still log intent with \`marrow_auto({ action: "what you're about to do" })\` or \`marrow_think\` when your runtime does not support hooks. The decision brief is guidance, not a replacement for the Marrow loop.
54
- 5. **After actions:** Hooks auto-log tool outcomes. For important final results, call \`marrow_auto({ action: "what you did", outcome: "what happened", success: true/false })\` or \`marrow_commit\`.
55
- 6. **To query history:** Call \`marrow_ask("plain english question")\` — ask what failed, what worked, what to avoid.
54
+ 1. **Passive by default:** Marrow hooks record compact lifecycle receipts and inject relevant policy, warnings, lessons, and risky-work decision briefs into your prompt context.
55
+ 2. **Before risky actions:** Respect the returned \`allow\`, \`warn\`, \`review_required\`, or \`block\` decision and its proof contract. Call \`marrow_agent_runtime\` explicitly when the passive hook cannot cover the action.
56
+ 3. **After meaningful work:** Record the real success or failure with \`marrow_commit\` or \`marrow_auto\`. A tool exit or session end is not proof that the business outcome succeeded.
57
+ 4. **Unfinished work:** Leave pending outcomes visible. Do not invent success to clear a closure item.
58
+ 5. **To explain a decision:** Use \`marrow_decision_trace\` to connect the prior failure, lesson, gate, proof, workflow, and outcome.
59
+ 6. **To query authorized history:** Call \`marrow_ask("plain english question")\` — ask what failed, what worked, and what policy should apply.
56
60
 
57
- Do NOT skip logging. Every decision you log compounds — failure rates drop, patterns emerge, the next session starts smarter. This is not optional overhead.
61
+ Do not skip the gate or outcome. Marrow's value comes from controlling the action before execution and preserving evidence afterward.
58
62
 
59
63
  For one-shot logging: \`marrow_auto({ action: "did X", outcome: "result Y", success: true })\` — one call, done.
60
64
  ${MARROW_BLOCK_END}`;
@@ -111,8 +115,15 @@ ${MARROW_BLOCK_END}`;
111
115
  else {
112
116
  process.stdout.write('UserPromptSubmit hook already installed — Marrow context and passive decision briefs are injected on matching prompts.\n');
113
117
  }
118
+ const sessionHookInstall = (0, hook_session_1.installSessionEndHook)(process.cwd());
119
+ if (sessionHookInstall.installed) {
120
+ process.stdout.write('Installed Stop hook — unfinished outcomes remain visible for reconciliation.\n');
121
+ }
122
+ else {
123
+ process.stdout.write('Stop hook already installed — unfinished outcomes remain visible for reconciliation.\n');
124
+ }
114
125
  process.stdout.write(`Hook settings: ${hookInstall.settingsPath}\n`);
115
- process.stdout.write('Set MARROW_AUTO_HOOK=false to disable both hooks.\n');
126
+ process.stdout.write('Set MARROW_AUTO_HOOK=false to disable passive hooks.\n');
116
127
  process.stdout.write('Set MARROW_PASSIVE_BRIEF=false to disable automatic decision briefs, or MARROW_PASSIVE_BRIEF=always to brief every prompt.\n');
117
128
  process.stdout.write('Set MARROW_HOOK_DEBUG=true for write-side hook diagnostics, or MARROW_CONTEXT_HOOK_DEBUG=true for prompt-context diagnostics.\n');
118
129
  process.stdout.write('Your agent will now use Marrow automatically — both writing decisions AND reading past intelligence — in every session.\n');
@@ -219,6 +230,9 @@ if (process.argv[2] !== 'keys') {
219
230
  else if (cliArgs.contextHook) {
220
231
  void (0, hook_context_1.runContextHookCommand)();
221
232
  }
233
+ else if (cliArgs.sessionHook) {
234
+ void (0, hook_session_1.runSessionHookCommand)();
235
+ }
222
236
  else if (cliArgs.setup) {
223
237
  runSetup();
224
238
  }
@@ -511,10 +525,10 @@ if (process.argv[2] !== 'keys') {
511
525
  const TOOLS = [
512
526
  {
513
527
  name: 'marrow_orient',
514
- description: '⚡ CALL THIS FIRST — every session, before any other tool. ' +
515
- 'Returns failure warnings from your history so you avoid known mistakes immediately. ' +
516
- 'If shouldPause=true, review lessons before acting. ' +
517
- 'orient() reads from the hive. think() writes to it. Both are required — this is what makes Marrow compound.',
528
+ description: 'Call at session start or before meaningful work. ' +
529
+ 'Returns authorized prior lessons and failure warnings for the current account or agent. ' +
530
+ 'If shouldPause=true, stop and review the lesson before acting. ' +
531
+ 'Use marrow_agent_runtime for the policy gate before a consequential side effect.',
518
532
  inputSchema: {
519
533
  type: 'object',
520
534
  properties: {
@@ -533,9 +547,8 @@ if (process.argv[2] !== 'keys') {
533
547
  },
534
548
  {
535
549
  name: 'marrow_think',
536
- description: 'Log intent and get collective intelligence before acting. ' +
537
- 'Call this before every meaningful action. ' +
538
- 'Returns pattern insights, similar past decisions, failure detection, and a recommendedNext field — follow it. ' +
550
+ description: 'Record intent and retrieve authorized governance intelligence before acting. ' +
551
+ 'Returns a decision_id for outcome closure plus relevant patterns, prior outcomes, and recommendedNext. ' +
539
552
  'Pass previous_outcome to auto-commit the last decision and open a new one. ' +
540
553
  'Response MAY include: onboarding_hint (new accounts), intelligence.collective (cross-account patterns), intelligence.team_context (recent decisions from other sessions).',
541
554
  inputSchema: {
@@ -566,9 +579,9 @@ if (process.argv[2] !== 'keys') {
566
579
  },
567
580
  {
568
581
  name: 'marrow_commit',
569
- description: 'Explicitly commit the result of an action to Marrow. ' +
570
- 'Optional — marrow_think() auto-commits if you pass previous_outcome. ' +
571
- 'Use when you need explicit control over commit timing.',
582
+ description: 'Close a recorded action with success/failure, a specific outcome, and required proof. ' +
583
+ 'Use the decision_id from marrow_think and the gate receipt from marrow_agent_runtime for consequential work. ' +
584
+ 'Outcome closure is required for accountable fleet learning.',
572
585
  inputSchema: {
573
586
  type: 'object',
574
587
  properties: {
@@ -1053,6 +1066,17 @@ if (process.argv[2] !== 'keys') {
1053
1066
  required: [],
1054
1067
  },
1055
1068
  },
1069
+ {
1070
+ name: 'marrow_decision_trace',
1071
+ description: 'Inspect the tenant-scoped path from a decision to prior failures, reused lessons, gate, proof, workflow, and observed outcome.',
1072
+ inputSchema: {
1073
+ type: 'object',
1074
+ properties: {
1075
+ decisionId: { type: 'string', description: 'Decision ID owned by this account and agent scope.' },
1076
+ },
1077
+ required: ['decisionId'],
1078
+ },
1079
+ },
1056
1080
  {
1057
1081
  name: 'marrow_buyer_proof',
1058
1082
  description: 'Return buyer-grade value proof: failures avoided, risky actions reviewed, proofs completed, token/time saved, failure classes, agent leaderboard, and reliability score.',
@@ -1295,7 +1319,7 @@ if (process.argv[2] !== 'keys') {
1295
1319
  success(id, {
1296
1320
  protocolVersion: '2024-11-05',
1297
1321
  capabilities: { tools: {}, prompts: {} },
1298
- serverInfo: { name: 'marrow', version: '3.9.12' },
1322
+ serverInfo: { name: 'marrow', version: '3.9.44' },
1299
1323
  });
1300
1324
  // Auto-enroll: emit enrollment notification on connection
1301
1325
  if (AUTO_ENROLL) {
@@ -1321,7 +1345,7 @@ if (process.argv[2] !== 'keys') {
1321
1345
  prompts: [
1322
1346
  {
1323
1347
  name: 'marrow-always-on',
1324
- description: 'Always-on Marrow memory loop. Instructs the agent to orient at session start, log intent before meaningful actions, and commit outcomes after completion. Install once — works automatically.',
1348
+ description: 'Always-on Marrow control and proof loop. Applies before-action guidance, records compact lifecycle receipts, and keeps unfinished outcomes visible.',
1325
1349
  arguments: [],
1326
1350
  },
1327
1351
  ],
@@ -1339,78 +1363,39 @@ if (process.argv[2] !== 'keys') {
1339
1363
  return;
1340
1364
  }
1341
1365
  success(id, {
1342
- description: 'Always-on Marrow memory loop — automatic, zero-config',
1366
+ description: 'Always-on Marrow control and proof loop — automatic, zero-config',
1343
1367
  messages: [
1344
1368
  {
1345
1369
  role: 'user',
1346
1370
  content: {
1347
1371
  type: 'text',
1348
- text: `You have Marrow — a memory layer that tells you what went wrong last time before you do it again.
1372
+ text: `You have Marrow — the agent control and proof layer around this workflow.
1373
+
1374
+ ## Passive operating contract
1349
1375
 
1350
- ## PRIMARY: Use marrow_auto for everything
1376
+ Installed hooks handle supported lifecycle capture automatically:
1377
+ - UserPromptSubmit requests relevant policy, warnings, lessons, and a decision brief before risky work.
1378
+ - PostToolUse records compact tool success or failure receipts.
1379
+ - Stop keeps unfinished outcomes visible instead of silently treating session exit as success.
1351
1380
 
1352
- One tool. Two calls max. Zero loop management.
1381
+ Hooks never make a blocked action safe. Before a consequential action, respect the returned allow, warn, review_required, or block decision and its required proof. Call marrow_agent_runtime explicitly when the passive hook cannot cover the action.
1353
1382
 
1354
- The minimum loop:
1355
- 1. Before any external action: \`marrow_auto({ action: "...what you are about to do" })\`
1356
- 2. After the action: \`marrow_auto({ action: "...", outcome: "...what happened", success: true/false })\`
1383
+ ## Outcome closure
1357
1384
 
1358
- If you only have time for one call: \`marrow_auto({ action: "did X", outcome: "result", success: true })\` — that's the whole loop.
1385
+ A successful command or tool exit is not proof that the business outcome succeeded. After meaningful work, close the real outcome with marrow_commit or marrow_auto and include success or failure plus the required evidence. If the result is unknown, leave it pending. Never invent success to clear a closure item.
1359
1386
 
1360
- You never need think + commit separately. \`marrow_auto\` handles everything.
1387
+ Use marrow_decision_trace when you need to explain why Marrow changed an action. It connects the relevant prior failure, proven lesson, gate, proof, workflow, and outcome without exposing another tenant's data.
1361
1388
 
1362
- All Marrow API calls run in the background — \`marrow_auto\` returns instantly with cached warnings so you never wait.
1389
+ ## Owner-visible value
1363
1390
 
1364
- ## Query the hive
1391
+ When Marrow returns a factual value signal, relay the single most useful result in one plain sentence. Mention a prevented repeat failure, reused proven lesson, completed proof, or measured improvement only when the response contains evidence. Do not invent savings, success rates, customer examples, pricing, or upgrade claims.
1365
1392
 
1366
- Use marrow_ask to query your decision history in plain English:
1393
+ Use marrow_ask for authorized history questions such as:
1367
1394
  - "what keeps breaking our deploys?"
1368
- - "what's our failure rate on security tasks?"
1395
+ - "which proof is missing from this workflow?"
1369
1396
  - "what worked last time we published?"
1370
1397
 
1371
- ## Advanced mode: fine-grained control
1372
-
1373
- For cases where you need explicit control over the orient → think → act → commit loop:
1374
-
1375
- 1. **Session start:** Call marrow_orient FIRST. It surfaces failure warnings so you avoid known mistakes.
1376
- 2. **Before acting:** Call marrow_think with what you're about to do. Returns pattern insights and recommendedNext — follow it.
1377
- 3. **After acting:** Call marrow_commit with what happened.
1378
- 4. **Shortcut:** marrow_run handles orient → think → commit in a single awaited call.
1379
-
1380
- Most agents never need advanced mode. \`marrow_auto\` covers 99% of cases.
1381
-
1382
- WHEN marrow_commit returns a non-empty narrative field:
1383
- - Relay that message to the user in your own words, woven naturally into your reply.
1384
- - Don't tack it on awkwardly, work it into a summary or closing note.
1385
- - Example format: "Task done. (Marrow note: <relayed narrative>.)"
1386
- - Don't quote the narrative verbatim unless it is short and natural to quote, paraphrase when it flows better.
1387
- - Never mention upgrade, pricing, or Pro features, Marrow is free for all users right now.
1388
-
1389
- WHEN marrow_think or marrow_commit returns marrow_contributed.has_signal === true:
1390
- - After completing your action (or while explaining your approach), tell the user in ONE sentence what Marrow contributed.
1391
- - Be factual, not hypey. Pick the single most useful signal — don't list everything.
1392
- - Examples that hit the right tone:
1393
- - think: "Pulling 12 similar tasks from the hive — using the approach that worked 11/12 times."
1394
- - think: "Marrow flagged this approach failed 4× last week — taking a different angle."
1395
- - think: "Following your installed deployment workflow."
1396
- - commit: "Skipped a known retry loop based on Marrow's pattern history."
1397
- - commit: "Reused a pattern that's worked for similar tasks."
1398
- - If marrow_contributed.has_signal is false (or marrow_contributed is missing), don't mention Marrow.
1399
-
1400
- WHEN marrow_session_end returns session_summary.has_signal === true:
1401
- - As you wrap up the session / hand back to the user, surface session_summary.narrative in 1-2 lines.
1402
- - Example: "Session done. Marrow note: 12 decisions, 3 retries avoided via warnings, 8 pattern reuses from your history."
1403
- - If has_signal is false, don't bother — the session was too small or had nothing notable.
1404
-
1405
- The point of these narrations: the user installed Marrow to make their agent better. They should hear, in plain English, what Marrow actually did. No dashboard, no logs — your reply IS their visibility.
1406
-
1407
- ## Why you must not skip this
1408
-
1409
- If you skip logging, the hive can't protect you or future agents from this mistake.
1410
- Every decision you log compounds. Failure rates drop. Patterns emerge. The next session starts smarter.
1411
- Marrow tells you what went wrong last time before you do it again. But only if you logged it.
1412
-
1413
- This is not optional overhead — it's how you stop repeating the same failures.`,
1398
+ Marrow is not a replacement agent or a standalone memory app. Context and prior lessons support the control loop; policy before action, proof after action, accountable outcomes, and fleet improvement are the product.`,
1414
1399
  },
1415
1400
  },
1416
1401
  ],
@@ -1442,18 +1427,13 @@ This is not optional overhead — it's how you stop repeating the same failures.
1442
1427
  }
1443
1428
  }
1444
1429
  if (AUTO_ENROLL && orientCallCount === 1) {
1445
- const enrollmentText = `\n\n📋 **Marrow Auto-Enroll Active**\n\n` +
1446
- `You have Marrow — a collective memory that tells you what went wrong last time before you do it again.\n\n` +
1447
- `## How it works (2 tools max):\n\n` +
1448
- `1. **Session start:** Call marrow_orient FIRST. You just did — it surfaces failure warnings.\n` +
1449
- `2. **Before any action:** Call marrow_think({ action: "..." }) — returns pattern insights + recommendedNext.\n` +
1450
- `3. **After acting:** Call marrow_commit({ decision_id, success, outcome }) — or pass previous_outcome to auto-commit.\n\n` +
1451
- `## Quick mode (one tool):\n` +
1452
- `- marrow_run({ description, success, outcome }) — handles orient → think → commit in one call.\n` +
1453
- `- marrow_auto({ action, outcome?, success? }) — fire-and-forget background logging.\n\n` +
1454
- `## Why you must not skip this:\n` +
1455
- `Every decision you log compounds. Failure rates drop. The next session starts smarter.\n` +
1456
- `Marrow tells you what went wrong last time — but only if you logged it.\n`;
1430
+ const enrollmentText = `\n\n**Marrow control and proof active**\n\n` +
1431
+ `Marrow applies relevant policy and prior lessons before consequential actions, then records evidence and the real outcome afterward.\n\n` +
1432
+ `1. Respect allow, warn, review_required, and block decisions before acting.\n` +
1433
+ `2. Use marrow_agent_runtime when a risky action needs an explicit gate.\n` +
1434
+ `3. Close meaningful work with marrow_commit; a tool exit alone is not outcome proof.\n` +
1435
+ `4. Use marrow_decision_trace to explain the prior failure, lesson, gate, proof, workflow, and outcome path.\n\n` +
1436
+ `Installed hooks cover supported passive lifecycle events. Leave unknown outcomes pending instead of inventing success.\n`;
1457
1437
  const orientText = JSON.stringify(result, null, 2);
1458
1438
  success(id, {
1459
1439
  content: [{ type: 'text', text: enrollmentText + orientText }],
@@ -1901,6 +1881,16 @@ This is not optional overhead — it's how you stop repeating the same failures.
1901
1881
  success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
1902
1882
  return;
1903
1883
  }
1884
+ if (toolName === 'marrow_decision_trace') {
1885
+ const decisionId = args.decisionId;
1886
+ if (!decisionId) {
1887
+ error(id, -32602, 'decisionId is required');
1888
+ return;
1889
+ }
1890
+ const result = await (0, index_1.marrowDecisionTrace)(API_KEY, BASE_URL, decisionId, SESSION_ID, FLEET_AGENT_ID);
1891
+ success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
1892
+ return;
1893
+ }
1904
1894
  if (toolName === 'marrow_buyer_proof') {
1905
1895
  const result = await (0, index_1.marrowBuyerProof)(API_KEY, BASE_URL, {
1906
1896
  agentId: args.agentId || AGENT_ID,