@getmarrow/mcp 3.9.54 → 3.9.56
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 +35 -3
- package/dist/cli.js +140 -1
- package/dist/cli.js.map +1 -1
- package/dist/guidance-cache.d.ts +17 -0
- package/dist/guidance-cache.d.ts.map +1 -0
- package/dist/guidance-cache.js +57 -0
- package/dist/guidance-cache.js.map +1 -0
- package/dist/hook-context.d.ts +2 -1
- package/dist/hook-context.d.ts.map +1 -1
- package/dist/hook-context.js +98 -42
- package/dist/hook-context.js.map +1 -1
- package/dist/hook-contract.d.ts +6 -6
- package/dist/hook-contract.js +1 -1
- package/dist/hook-session.d.ts +1 -1
- package/dist/hook.d.ts +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +188 -4
- package/dist/index.js.map +1 -1
- package/dist/lifecycle-spool.d.ts +1 -0
- package/dist/lifecycle-spool.d.ts.map +1 -1
- package/dist/lifecycle-spool.js +1 -1
- package/dist/lifecycle-spool.js.map +1 -1
- package/dist/ping-state.d.ts +14 -0
- package/dist/ping-state.d.ts.map +1 -0
- package/dist/ping-state.js +61 -0
- package/dist/ping-state.js.map +1 -0
- package/package.json +2 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -97,11 +97,33 @@ npx -y @getmarrow/install@latest doctor
|
|
|
97
97
|
|
|
98
98
|
# Manual MCP-only setup
|
|
99
99
|
npx -y @getmarrow/mcp@latest setup
|
|
100
|
+
|
|
101
|
+
# Verify live read latency, last success, and local backlog
|
|
102
|
+
npx -y @getmarrow/mcp@latest ping
|
|
100
103
|
```
|
|
101
104
|
|
|
102
105
|
Detection and notification are automatic. After explicit installer activation, the local controller may restore only Marrow-managed hooks/configuration. Package upgrades, owner policy, credentials, and unrelated configuration remain explicit and subject to the operator's normal change policy.
|
|
103
106
|
|
|
104
|
-
## What's New in v3.9.
|
|
107
|
+
## What's New in v3.9.56
|
|
108
|
+
|
|
109
|
+
v3.9.56 adds tenant-scoped coordination and evidence-only replay to the existing MCP governance surface:
|
|
110
|
+
|
|
111
|
+
- each normal user prompt performs one compact `/v1/agent/context` read; risky or mutating prompts perform one `/v1/agent/runtime` call instead;
|
|
112
|
+
- prompt lifecycle receipts are accepted into the owner-only local spool immediately and delivered asynchronously by later lifecycle activity;
|
|
113
|
+
- the prompt read deadline is 400 ms, injected guidance is limited to 3–8 concise lines, and raw prompts are not stored in the guidance cache;
|
|
114
|
+
- transient failures can use an owner-only, account/key/agent-scoped last-known brief for at most one hour, clearly labeled with its age;
|
|
115
|
+
- 401 and 403 responses never use cached guidance, and cached runtime guidance cannot authorize high-risk work;
|
|
116
|
+
- `marrow_ask` now maps to the canonical decision brief contract instead of a separate route;
|
|
117
|
+
- `npx -y @getmarrow/mcp@latest ping` reports current latency, rolling measured p50/p99, last success, and lifecycle backlog health;
|
|
118
|
+
- `marrow_coordinate` acquires/releases tenant-scoped resource leases and carries compact child proof packets without sharing transcripts;
|
|
119
|
+
- `marrow_replay_compare` compares already-recorded baseline and candidate outcomes with durable proof and never executes either model;
|
|
120
|
+
- both new tools preserve agent-bound key scope, reject unsafe path identifiers, and return unavailable or incomplete evidence rather than manufacturing a winner.
|
|
121
|
+
|
|
122
|
+
The package remains backward compatible with supported server aliases while advertising only implemented tools.
|
|
123
|
+
|
|
124
|
+
This release accepts `@getmarrow/sdk@^3.7.54` and is released after SDK `3.7.55`. The deterministic release order is SDK `3.7.55` first, MCP `3.9.56` second, and installer `0.1.40` last.
|
|
125
|
+
|
|
126
|
+
## Previous: v3.9.54
|
|
105
127
|
|
|
106
128
|
v3.9.54 makes Marrow's intervention visible through the existing decision-trace workflow:
|
|
107
129
|
|
|
@@ -111,8 +133,6 @@ v3.9.54 makes Marrow's intervention visible through the existing decision-trace
|
|
|
111
133
|
|
|
112
134
|
It preserves the bounded MCP lifecycle recovery introduced in v3.9.53.
|
|
113
135
|
|
|
114
|
-
This release is certified against `@getmarrow/sdk@3.7.53`. The deterministic release order is SDK `3.7.53` first, MCP `3.9.54` second, and installer `0.1.38` last.
|
|
115
|
-
|
|
116
136
|
## Previous: v3.9.53
|
|
117
137
|
|
|
118
138
|
v3.9.53 adds exact lifecycle backlog visibility and bounded recovery for MCP-routed agent activity:
|
|
@@ -265,6 +285,16 @@ URLs, paths, credentials, or customer content. The arbitration response owns the
|
|
|
265
285
|
session; pass its short-lived, single-use `owner_approval_receipt_id` to
|
|
266
286
|
`marrow_commit`. An agent cannot authorize itself with a proof field.
|
|
267
287
|
|
|
288
|
+
Use `marrow_coordinate` when parallel agents could edit the same file, service,
|
|
289
|
+
deployment, or workflow. An acquired lease returns a one-time release capability.
|
|
290
|
+
Child agents can then create a compact proof packet containing only a bounded
|
|
291
|
+
summary and opaque durable evidence references. Complete is accepted only when
|
|
292
|
+
the linked outcome and required proof are actually closed.
|
|
293
|
+
|
|
294
|
+
Use `marrow_replay_compare` after two model or workflow variants have each
|
|
295
|
+
recorded an outcome. It compares that existing evidence under one tenant task;
|
|
296
|
+
it does not run models, retain prompts, or infer a winner from labels.
|
|
297
|
+
|
|
268
298
|
## Passive Use
|
|
269
299
|
|
|
270
300
|
`npx @getmarrow/mcp setup` installs supported prompt, tool-result, and session-stop hooks so the agent can receive before-action context, record meaningful tool outcomes, and keep unfinished closure visible without the owner repeatedly prompting it to use Marrow.
|
|
@@ -294,6 +324,8 @@ Status diagnostics distinguish missing keys, invalid keys, wrong bound-agent ide
|
|
|
294
324
|
| --- | --- |
|
|
295
325
|
| `marrow_agent_runtime` | One-call pre-action status, policy gate, relevant lessons, proof requirements, and exact next action |
|
|
296
326
|
| `marrow_arbitrate` | Resolve conflicting agent proposals before execution and return an explainable arbitration receipt |
|
|
327
|
+
| `marrow_coordinate` | Acquire/release resource leases and exchange compact child proof packets across tenant agents |
|
|
328
|
+
| `marrow_replay_compare` | Compare two existing proof-backed outcomes without executing a model |
|
|
297
329
|
| `marrow_decision_brief` | Compact operating brief for meaningful work |
|
|
298
330
|
| `marrow_think` | Record intent and retrieve relevant governance intelligence |
|
|
299
331
|
| `marrow_commit` | Close an action with outcome, receipt, and proof |
|
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ const hook_session_1 = require("./hook-session");
|
|
|
17
17
|
const hook_pre_action_1 = require("./hook-pre-action");
|
|
18
18
|
const env_1 = require("./env");
|
|
19
19
|
const lifecycle_spool_1 = require("./lifecycle-spool");
|
|
20
|
+
const ping_state_1 = require("./ping-state");
|
|
20
21
|
const redact_1 = require("./redact");
|
|
21
22
|
// Parse CLI args
|
|
22
23
|
function parseArgs() {
|
|
@@ -48,9 +49,62 @@ function parseArgs() {
|
|
|
48
49
|
if (args[i] === 'drain-spool' || args[i] === '--drain-spool') {
|
|
49
50
|
result.drainSpool = true;
|
|
50
51
|
}
|
|
52
|
+
if (args[i] === 'ping' || args[i] === '--ping') {
|
|
53
|
+
result.ping = true;
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
return result;
|
|
53
57
|
}
|
|
58
|
+
async function runPingCommand() {
|
|
59
|
+
if (cliArgs.apiKey) {
|
|
60
|
+
process.stderr.write('Error: ping requires MARROW_API_KEY from trusted environment or owner configuration; --key is not accepted.\n');
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const resolved = (0, env_1.resolveMarrowEnv)({ trustedOnly: true });
|
|
65
|
+
if (!resolved.apiKey) {
|
|
66
|
+
process.stdout.write(JSON.stringify({ ok: false, error: 'missing_key', exact_fix: resolved.exactFix }) + '\n');
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const baseUrl = (0, index_1.validateBaseUrl)(resolved.baseUrl || 'https://api.getmarrow.ai');
|
|
71
|
+
const controller = new AbortController();
|
|
72
|
+
const timer = setTimeout(() => controller.abort(), 400);
|
|
73
|
+
timer.unref?.();
|
|
74
|
+
const started = Date.now();
|
|
75
|
+
try {
|
|
76
|
+
const status = await (0, index_1.marrowRuntimeStatus)(resolved.apiKey, baseUrl, true, resolved.sessionId, resolved.agentId, controller.signal);
|
|
77
|
+
const latencyMs = Date.now() - started;
|
|
78
|
+
const history = (0, ping_state_1.updatePingState)({ apiKey: resolved.apiKey, baseUrl, agentId: resolved.agentId, latencyMs, success: true });
|
|
79
|
+
process.stdout.write(JSON.stringify({
|
|
80
|
+
ok: status.ok === true,
|
|
81
|
+
health: status.health || 'available',
|
|
82
|
+
current_ms: latencyMs,
|
|
83
|
+
p50_ms: history.p50_ms,
|
|
84
|
+
p99_ms: history.p99_ms,
|
|
85
|
+
sample_count: history.sample_count,
|
|
86
|
+
last_success_at: history.last_success_at,
|
|
87
|
+
lifecycle_spool: (0, lifecycle_spool_1.lifecycleSpoolStatus)({ apiKey: resolved.apiKey, agentId: resolved.agentId }),
|
|
88
|
+
}, null, 2) + '\n');
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const history = (0, ping_state_1.updatePingState)({ apiKey: resolved.apiKey, baseUrl, agentId: resolved.agentId, success: false });
|
|
92
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
93
|
+
process.stdout.write(JSON.stringify({
|
|
94
|
+
ok: false,
|
|
95
|
+
error: /401|unauthorized/i.test(message) ? 'authentication_failed' : /403|forbidden/i.test(message) ? 'permission_denied' : /abort|timeout/i.test(message) ? 'timeout' : 'unavailable',
|
|
96
|
+
p50_ms: history.p50_ms,
|
|
97
|
+
p99_ms: history.p99_ms,
|
|
98
|
+
sample_count: history.sample_count,
|
|
99
|
+
last_success_at: history.last_success_at,
|
|
100
|
+
lifecycle_spool: (0, lifecycle_spool_1.lifecycleSpoolStatus)({ apiKey: resolved.apiKey, agentId: resolved.agentId }),
|
|
101
|
+
}, null, 2) + '\n');
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
54
108
|
async function runSpoolCommand(drain) {
|
|
55
109
|
if (cliArgs.apiKey) {
|
|
56
110
|
process.stderr.write('Error: lifecycle spool commands require MARROW_API_KEY from trusted environment or owner configuration; --key is not accepted.\n');
|
|
@@ -288,6 +342,9 @@ if (process.argv[2] !== 'keys') {
|
|
|
288
342
|
else if (cliArgs.drainSpool) {
|
|
289
343
|
void runSpoolCommand(true);
|
|
290
344
|
}
|
|
345
|
+
else if (cliArgs.ping) {
|
|
346
|
+
void runPingCommand();
|
|
347
|
+
}
|
|
291
348
|
else if (cliArgs.setup) {
|
|
292
349
|
runSetup();
|
|
293
350
|
}
|
|
@@ -1117,6 +1174,75 @@ if (process.argv[2] !== 'keys') {
|
|
|
1117
1174
|
required: ['objective', 'proposals'],
|
|
1118
1175
|
},
|
|
1119
1176
|
},
|
|
1177
|
+
{
|
|
1178
|
+
name: 'marrow_coordinate',
|
|
1179
|
+
description: 'Coordinate tenant agents without sharing transcripts. Acquire or release a bounded resource lease, ' +
|
|
1180
|
+
'list current leases, or create/list compact evidence-backed child proof packets for a parent agent.',
|
|
1181
|
+
inputSchema: {
|
|
1182
|
+
type: 'object',
|
|
1183
|
+
properties: {
|
|
1184
|
+
action: {
|
|
1185
|
+
type: 'string',
|
|
1186
|
+
enum: ['list_leases', 'acquire_lease', 'release_lease', 'list_proof_packets', 'create_proof_packet'],
|
|
1187
|
+
},
|
|
1188
|
+
resource_type: { type: 'string', enum: ['file', 'directory', 'service', 'workflow', 'deployment', 'custom'] },
|
|
1189
|
+
resource: { type: 'string', maxLength: 160, description: 'Bounded tenant-visible resource label. Do not send secrets.' },
|
|
1190
|
+
workflow_id: { type: 'string' },
|
|
1191
|
+
ttl_seconds: { type: 'number', minimum: 30, maximum: 3600 },
|
|
1192
|
+
lease_id: { type: 'string' },
|
|
1193
|
+
lease_token: { type: 'string', description: 'One-time lease capability returned by acquire_lease.' },
|
|
1194
|
+
status: { type: 'string', enum: ['active', 'released', 'expired', 'incomplete', 'complete', 'failed'] },
|
|
1195
|
+
limit: { type: 'number', minimum: 1, maximum: 100 },
|
|
1196
|
+
decision_id: { type: 'string' },
|
|
1197
|
+
proof_pack_id: { type: 'string' },
|
|
1198
|
+
summary: { type: 'string', maxLength: 280, description: 'Compact result summary; no raw transcript.' },
|
|
1199
|
+
evidence_refs: {
|
|
1200
|
+
type: 'array', maxItems: 20, items: { type: 'string' },
|
|
1201
|
+
description: 'Opaque durable evidence identifiers only.',
|
|
1202
|
+
},
|
|
1203
|
+
},
|
|
1204
|
+
required: ['action'],
|
|
1205
|
+
},
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
name: 'marrow_replay_compare',
|
|
1209
|
+
description: 'Compare two already-recorded outcomes for the same tenant task using durable proof. ' +
|
|
1210
|
+
'This does not run a model or replay customer content; it returns complete or insufficient_evidence.',
|
|
1211
|
+
inputSchema: {
|
|
1212
|
+
type: 'object',
|
|
1213
|
+
properties: {
|
|
1214
|
+
comparison_id: { type: 'string', description: 'Fetch a prior replay comparison by id.' },
|
|
1215
|
+
source_decision_id: { type: 'string', description: 'Original task decision used to bind the comparison.' },
|
|
1216
|
+
workspace_binding_id: { type: 'string', description: 'Optional privacy-safe workspace binding from runtime.' },
|
|
1217
|
+
constraints: {
|
|
1218
|
+
type: 'object',
|
|
1219
|
+
additionalProperties: false,
|
|
1220
|
+
maxProperties: 7,
|
|
1221
|
+
description: 'Allowlisted comparison labels only; prompts, code, transcripts, credentials, and nested content are rejected.',
|
|
1222
|
+
properties: {
|
|
1223
|
+
environment: { type: 'string', maxLength: 80 },
|
|
1224
|
+
tests: { type: 'string', maxLength: 80 },
|
|
1225
|
+
policy_profile_id: { type: 'string', maxLength: 80 },
|
|
1226
|
+
workflow_type: { type: 'string', maxLength: 80 },
|
|
1227
|
+
task_type: { type: 'string', maxLength: 80 },
|
|
1228
|
+
required_proof: { type: 'boolean' },
|
|
1229
|
+
same_workspace: { type: 'boolean' },
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1232
|
+
baseline: {
|
|
1233
|
+
type: 'object',
|
|
1234
|
+
properties: { label: { type: 'string' }, decision_id: { type: 'string' } },
|
|
1235
|
+
required: ['decision_id'],
|
|
1236
|
+
},
|
|
1237
|
+
candidate: {
|
|
1238
|
+
type: 'object',
|
|
1239
|
+
properties: { label: { type: 'string' }, decision_id: { type: 'string' } },
|
|
1240
|
+
required: ['decision_id'],
|
|
1241
|
+
},
|
|
1242
|
+
},
|
|
1243
|
+
required: [],
|
|
1244
|
+
},
|
|
1245
|
+
},
|
|
1120
1246
|
{
|
|
1121
1247
|
name: 'marrow_governance_control_plane',
|
|
1122
1248
|
description: 'Return Marrow control-plane proof: governance, runtime gates, proof packs, fleet intelligence, supported harnesses, and exact next action.',
|
|
@@ -1411,7 +1537,7 @@ if (process.argv[2] !== 'keys') {
|
|
|
1411
1537
|
success(id, {
|
|
1412
1538
|
protocolVersion: '2024-11-05',
|
|
1413
1539
|
capabilities: { tools: {}, prompts: {} },
|
|
1414
|
-
serverInfo: { name: 'marrow', version: '3.9.
|
|
1540
|
+
serverInfo: { name: 'marrow', version: '3.9.56' },
|
|
1415
1541
|
});
|
|
1416
1542
|
// Auto-enroll: emit enrollment notification on connection
|
|
1417
1543
|
if (AUTO_ENROLL) {
|
|
@@ -1962,6 +2088,19 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
1962
2088
|
success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
|
|
1963
2089
|
return;
|
|
1964
2090
|
}
|
|
2091
|
+
if (toolName === 'marrow_coordinate') {
|
|
2092
|
+
const coordinationArgs = { ...args };
|
|
2093
|
+
delete coordinationArgs.agent_id;
|
|
2094
|
+
delete coordinationArgs.source_agent_id;
|
|
2095
|
+
const result = await (0, index_1.marrowCoordinate)(API_KEY, BASE_URL, coordinationArgs, SESSION_ID, FLEET_AGENT_ID);
|
|
2096
|
+
success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
if (toolName === 'marrow_replay_compare') {
|
|
2100
|
+
const result = await (0, index_1.marrowReplayCompare)(API_KEY, BASE_URL, args, SESSION_ID, FLEET_AGENT_ID);
|
|
2101
|
+
success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
1965
2104
|
if (toolName === 'marrow_governance_control_plane') {
|
|
1966
2105
|
const result = await (0, index_1.marrowGovernanceControlPlane)(API_KEY, BASE_URL, SESSION_ID, FLEET_AGENT_ID);
|
|
1967
2106
|
success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
|