@haven_ai/mcp 0.7.0-alpha.0 → 0.8.0-alpha.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 +11 -7
- package/dist/cli.cjs +145 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +146 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +145 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +145 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -66,7 +66,7 @@ declare function loadCredentials(source?: string | HavenCredentialSource | undef
|
|
|
66
66
|
* which is where URL-hardening would matter.)
|
|
67
67
|
*/
|
|
68
68
|
|
|
69
|
-
type HavenMcpToolName = 'haven_send' | 'haven_pay_mcp_tool' | 'haven_quote_x402' | 'haven_pay_x402_quote' | 'haven_pay_x402' | 'haven_resume_x402_payment' | 'haven_get_payment_status' | 'haven_get_resume_state' | 'haven_get_agent' | 'haven_get_allowances' | 'haven_list_receipts' | 'haven_verify_receipt' | 'haven_sweep_delegate' | 'haven_discover_tools' | 'haven_submit_catalog_entry' | 'haven_open_task_budget' | 'haven_close_task_budget' | 'haven_submit';
|
|
69
|
+
type HavenMcpToolName = 'haven_send' | 'haven_pay_mcp_tool' | 'haven_quote_x402' | 'haven_pay_x402_quote' | 'haven_pay_x402' | 'haven_resume_x402_payment' | 'haven_get_payment_status' | 'haven_get_resume_state' | 'haven_get_agent' | 'haven_get_allowances' | 'haven_list_receipts' | 'haven_verify_receipt' | 'haven_sweep_delegate' | 'haven_discover_tools' | 'haven_submit_catalog_entry' | 'haven_open_task_budget' | 'haven_close_task_budget' | 'haven_get_task_budget' | 'haven_submit';
|
|
70
70
|
declare const toolSchemas: {
|
|
71
71
|
readonly haven_send: {
|
|
72
72
|
readonly asset: z.ZodEnum<["ETH", "USDC"]>;
|
|
@@ -167,8 +167,12 @@ declare const toolSchemas: {
|
|
|
167
167
|
readonly haven_close_task_budget: {
|
|
168
168
|
readonly task_budget_id: z.ZodString;
|
|
169
169
|
};
|
|
170
|
+
readonly haven_get_task_budget: {
|
|
171
|
+
readonly task_budget_id: z.ZodString;
|
|
172
|
+
};
|
|
170
173
|
readonly haven_submit: {
|
|
171
174
|
readonly task_budget_id: z.ZodOptional<z.ZodString>;
|
|
175
|
+
readonly sub_budget_id: z.ZodOptional<z.ZodString>;
|
|
172
176
|
readonly payment_id: z.ZodOptional<z.ZodString>;
|
|
173
177
|
readonly signature: z.ZodString;
|
|
174
178
|
};
|
|
@@ -407,7 +411,7 @@ declare function createHavenMcpServer(options?: HavenMcpServerOptions): Promise<
|
|
|
407
411
|
* `agent_tool_invocations` rows are always attributed to the right tool.
|
|
408
412
|
*/
|
|
409
413
|
declare const MCP_NAME = "@haven_ai/mcp";
|
|
410
|
-
declare const MCP_VERSION = "0.
|
|
414
|
+
declare const MCP_VERSION = "0.8.0-alpha.0";
|
|
411
415
|
/**
|
|
412
416
|
* Refuse to start on an unsupported Node (#1161).
|
|
413
417
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ declare function loadCredentials(source?: string | HavenCredentialSource | undef
|
|
|
66
66
|
* which is where URL-hardening would matter.)
|
|
67
67
|
*/
|
|
68
68
|
|
|
69
|
-
type HavenMcpToolName = 'haven_send' | 'haven_pay_mcp_tool' | 'haven_quote_x402' | 'haven_pay_x402_quote' | 'haven_pay_x402' | 'haven_resume_x402_payment' | 'haven_get_payment_status' | 'haven_get_resume_state' | 'haven_get_agent' | 'haven_get_allowances' | 'haven_list_receipts' | 'haven_verify_receipt' | 'haven_sweep_delegate' | 'haven_discover_tools' | 'haven_submit_catalog_entry' | 'haven_open_task_budget' | 'haven_close_task_budget' | 'haven_submit';
|
|
69
|
+
type HavenMcpToolName = 'haven_send' | 'haven_pay_mcp_tool' | 'haven_quote_x402' | 'haven_pay_x402_quote' | 'haven_pay_x402' | 'haven_resume_x402_payment' | 'haven_get_payment_status' | 'haven_get_resume_state' | 'haven_get_agent' | 'haven_get_allowances' | 'haven_list_receipts' | 'haven_verify_receipt' | 'haven_sweep_delegate' | 'haven_discover_tools' | 'haven_submit_catalog_entry' | 'haven_open_task_budget' | 'haven_close_task_budget' | 'haven_get_task_budget' | 'haven_submit';
|
|
70
70
|
declare const toolSchemas: {
|
|
71
71
|
readonly haven_send: {
|
|
72
72
|
readonly asset: z.ZodEnum<["ETH", "USDC"]>;
|
|
@@ -167,8 +167,12 @@ declare const toolSchemas: {
|
|
|
167
167
|
readonly haven_close_task_budget: {
|
|
168
168
|
readonly task_budget_id: z.ZodString;
|
|
169
169
|
};
|
|
170
|
+
readonly haven_get_task_budget: {
|
|
171
|
+
readonly task_budget_id: z.ZodString;
|
|
172
|
+
};
|
|
170
173
|
readonly haven_submit: {
|
|
171
174
|
readonly task_budget_id: z.ZodOptional<z.ZodString>;
|
|
175
|
+
readonly sub_budget_id: z.ZodOptional<z.ZodString>;
|
|
172
176
|
readonly payment_id: z.ZodOptional<z.ZodString>;
|
|
173
177
|
readonly signature: z.ZodString;
|
|
174
178
|
};
|
|
@@ -407,7 +411,7 @@ declare function createHavenMcpServer(options?: HavenMcpServerOptions): Promise<
|
|
|
407
411
|
* `agent_tool_invocations` rows are always attributed to the right tool.
|
|
408
412
|
*/
|
|
409
413
|
declare const MCP_NAME = "@haven_ai/mcp";
|
|
410
|
-
declare const MCP_VERSION = "0.
|
|
414
|
+
declare const MCP_VERSION = "0.8.0-alpha.0";
|
|
411
415
|
/**
|
|
412
416
|
* Refuse to start on an unsupported Node (#1161).
|
|
413
417
|
*
|
package/dist/index.js
CHANGED
|
@@ -351,12 +351,19 @@ var toolSchemas = {
|
|
|
351
351
|
haven_close_task_budget: {
|
|
352
352
|
task_budget_id: z.string().min(1)
|
|
353
353
|
},
|
|
354
|
-
// #
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
|
|
354
|
+
// #3518: read ONE task budget by id, any status — the status check a close
|
|
355
|
+
// refusal's "re-check the budget's status" points at, on the local surface
|
|
356
|
+
// too (schema and wording parity with the hosted read).
|
|
357
|
+
haven_get_task_budget: {
|
|
358
|
+
task_budget_id: z.string().min(1)
|
|
359
|
+
},
|
|
360
|
+
// #3329 / #3506: relays a signature from the local signer — the open/close
|
|
361
|
+
// signature for a task budget or a sub-budget row, or (schema parity with
|
|
362
|
+
// the hosted surface) a direct-payment signature by payment_id. Exactly one
|
|
363
|
+
// of task_budget_id / sub_budget_id / payment_id, never two or none.
|
|
358
364
|
haven_submit: {
|
|
359
365
|
task_budget_id: z.string().min(1).optional(),
|
|
366
|
+
sub_budget_id: z.string().min(1).optional(),
|
|
360
367
|
payment_id: z.string().min(1).optional(),
|
|
361
368
|
signature: z.string().regex(/^0x[0-9a-fA-F]+$/, "signature must be a 0x-prefixed hex string")
|
|
362
369
|
}
|
|
@@ -384,11 +391,19 @@ var CLOSE_TASK_BUDGET_DESCRIPTION = [
|
|
|
384
391
|
"the signature with haven_submit. A task budget past its own deadline closes immediately, the",
|
|
385
392
|
"same as the pending case."
|
|
386
393
|
].join(" ");
|
|
394
|
+
var GET_TASK_BUDGET_DESCRIPTION = [
|
|
395
|
+
"Read one task budget by id, any status.",
|
|
396
|
+
"Returns { task_budget } with status (pending | open | closing | closed), isExpired, maxDisplay, recipientAddress, label and expiresAt \u2014",
|
|
397
|
+
"the check to run after a close or submit refusal says to re-check the budget's status.",
|
|
398
|
+
"haven_get_agent lists live task budgets only; this reads any one, closed or expired included."
|
|
399
|
+
].join(" ");
|
|
387
400
|
var SUBMIT_DESCRIPTION = [
|
|
388
401
|
"Relay a signature from the local signer. Pass exactly one of task_budget_id (from",
|
|
389
|
-
"haven_open_task_budget or haven_close_task_budget)
|
|
390
|
-
"
|
|
391
|
-
|
|
402
|
+
"haven_open_task_budget or haven_close_task_budget), sub_budget_id (from haven_get_agent",
|
|
403
|
+
"pendingSubBudgetSignatures[]) or payment_id \u2014 never two, never none \u2014 plus signature.",
|
|
404
|
+
"For a task budget this opens or closes it on-chain and returns { task_budget,",
|
|
405
|
+
'status }; a close in progress may return { task_budget, status: "closed", close_tx_hash }.',
|
|
406
|
+
"A sub_budget_id returns { sub_budget, status } with the next signer step, if one is owed."
|
|
392
407
|
].join(" ");
|
|
393
408
|
var toolDescriptions = {
|
|
394
409
|
haven_send: composeDescription(toolDescriptions$1.send),
|
|
@@ -408,8 +423,101 @@ var toolDescriptions = {
|
|
|
408
423
|
haven_verify_receipt: composeDescription(toolDescriptions$1.verifyReceipt),
|
|
409
424
|
haven_open_task_budget: OPEN_TASK_BUDGET_DESCRIPTION,
|
|
410
425
|
haven_close_task_budget: CLOSE_TASK_BUDGET_DESCRIPTION,
|
|
426
|
+
haven_get_task_budget: GET_TASK_BUDGET_DESCRIPTION,
|
|
411
427
|
haven_submit: SUBMIT_DESCRIPTION
|
|
412
428
|
};
|
|
429
|
+
function subBudgetSignStep(subBudgetId) {
|
|
430
|
+
return {
|
|
431
|
+
next_action: "sign",
|
|
432
|
+
next_tool: "mcp__haven-signer__haven_sign",
|
|
433
|
+
next_arguments: { sub_budget_id: subBudgetId }
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
async function submitSubBudgetTool(haven, subBudgetId, signature) {
|
|
437
|
+
let result;
|
|
438
|
+
try {
|
|
439
|
+
result = await haven.submitSubBudget(subBudgetId, signature);
|
|
440
|
+
} catch (err) {
|
|
441
|
+
const code = err instanceof HavenApiError ? err.body?.error_code : void 0;
|
|
442
|
+
if (code === "close_needs_reprepare") {
|
|
443
|
+
let fresh;
|
|
444
|
+
try {
|
|
445
|
+
fresh = await haven.closeSubBudget(subBudgetId);
|
|
446
|
+
} catch (closeErr) {
|
|
447
|
+
return normalizeError(closeErr);
|
|
448
|
+
}
|
|
449
|
+
if (fresh.status === "closed") {
|
|
450
|
+
return {
|
|
451
|
+
success: true,
|
|
452
|
+
data: {
|
|
453
|
+
sub_budget: fresh.subBudget,
|
|
454
|
+
status: "closed",
|
|
455
|
+
next_action: "none",
|
|
456
|
+
next_tool_omitted_reason: "the sub-budget is closed on-chain; nothing further to sign or submit for it"
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
return {
|
|
461
|
+
success: false,
|
|
462
|
+
code: "CLOSE_NEEDS_REPREPARE",
|
|
463
|
+
message: "The stored close operation for this sub-budget was stale, so nothing was relayed. Haven prepared a fresh one: sign it with haven_sign, then call haven_submit again with the new signature.",
|
|
464
|
+
statusCode: 409,
|
|
465
|
+
...subBudgetSignStep(subBudgetId)
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
if (code === "close_outcome_unconfirmed") {
|
|
469
|
+
return {
|
|
470
|
+
success: false,
|
|
471
|
+
code: "CLOSE_OUTCOME_UNCONFIRMED",
|
|
472
|
+
message: "The close operation was sent but its outcome is not confirmed yet (on Base that can take tens of minutes). Wait, then call haven_submit again with the same arguments: it reports closed once the chain has finalised the disable, or prepares a fresh operation to sign if the earlier one did not land.",
|
|
473
|
+
statusCode: 502,
|
|
474
|
+
next_action: "check_status_later",
|
|
475
|
+
next_tool: "haven_submit",
|
|
476
|
+
next_arguments: { sub_budget_id: subBudgetId, signature }
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
return normalizeError(err);
|
|
480
|
+
}
|
|
481
|
+
return runTool(async () => {
|
|
482
|
+
const submitted = {
|
|
483
|
+
sub_budget: result.subBudget,
|
|
484
|
+
status: result.status,
|
|
485
|
+
...result.closeTxHash !== void 0 ? { close_tx_hash: result.closeTxHash } : {}
|
|
486
|
+
};
|
|
487
|
+
if (result.status === "closed") {
|
|
488
|
+
return {
|
|
489
|
+
...submitted,
|
|
490
|
+
next_action: "none",
|
|
491
|
+
next_tool_omitted_reason: "the sub-budget is closed on-chain; nothing further to sign or submit for it"
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
let pending;
|
|
495
|
+
try {
|
|
496
|
+
pending = await haven.listPendingSubBudgetSignatures();
|
|
497
|
+
} catch {
|
|
498
|
+
pending = null;
|
|
499
|
+
}
|
|
500
|
+
if (pending === null) {
|
|
501
|
+
return {
|
|
502
|
+
...submitted,
|
|
503
|
+
next_action: "check_status_later",
|
|
504
|
+
next_tool: "haven_get_agent",
|
|
505
|
+
next_arguments: {},
|
|
506
|
+
reason: "This sub-budget row is open, but Haven could not say whether its tree has another row awaiting your signature. Call haven_get_agent and sign any pendingSubBudgetSignatures row."
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const tree = result.subBudget.parentSubBudgetId ?? result.subBudget.id;
|
|
510
|
+
const sibling = pending.find(
|
|
511
|
+
(row) => row.purpose === "open" && row.subBudgetId !== result.subBudget.id && (row.parentSubBudgetId ?? row.subBudgetId) === tree
|
|
512
|
+
);
|
|
513
|
+
if (sibling) return { ...submitted, ...subBudgetSignStep(sibling.subBudgetId) };
|
|
514
|
+
return {
|
|
515
|
+
...submitted,
|
|
516
|
+
next_action: "none",
|
|
517
|
+
next_tool_omitted_reason: "no other row of this sub-budget awaits your signature, so the sub-budget is fully open and the sub-agent can spend through its grant"
|
|
518
|
+
};
|
|
519
|
+
});
|
|
520
|
+
}
|
|
413
521
|
function createToolHandlers(haven) {
|
|
414
522
|
return {
|
|
415
523
|
haven_send: async (input) => {
|
|
@@ -565,7 +673,17 @@ function createToolHandlers(haven) {
|
|
|
565
673
|
const args = objectInput("haven_get_resume_state", input);
|
|
566
674
|
return runTool(async () => haven.getResumeState(args.payment_id));
|
|
567
675
|
},
|
|
568
|
-
haven_get_agent: async () => runTool(async () =>
|
|
676
|
+
haven_get_agent: async () => runTool(async () => {
|
|
677
|
+
const summary = await haven.getAgentSummary();
|
|
678
|
+
if (!Array.isArray(summary.pendingSubBudgetSignatures)) return summary;
|
|
679
|
+
return {
|
|
680
|
+
...summary,
|
|
681
|
+
pendingSubBudgetSignatures: summary.pendingSubBudgetSignatures.map((row) => ({
|
|
682
|
+
...row,
|
|
683
|
+
...subBudgetSignStep(row.subBudgetId)
|
|
684
|
+
}))
|
|
685
|
+
};
|
|
686
|
+
}),
|
|
569
687
|
haven_get_allowances: async () => runTool(async () => haven.getAllowances()),
|
|
570
688
|
haven_sweep_delegate: async () => runTool(async () => haven.sweepDelegate()),
|
|
571
689
|
haven_discover_tools: async (input) => {
|
|
@@ -692,17 +810,32 @@ function createToolHandlers(haven) {
|
|
|
692
810
|
};
|
|
693
811
|
});
|
|
694
812
|
},
|
|
813
|
+
// #3518: read ONE task budget by id, any status — the status check a
|
|
814
|
+
// close/submit refusal's "re-check the budget's status" points at. The
|
|
815
|
+
// SDK relays `GET /task-budgets/:id` (the backend route answers any
|
|
816
|
+
// status) and a 404 carries the backend's own message through runTool.
|
|
817
|
+
haven_get_task_budget: async (input) => {
|
|
818
|
+
const args = objectInput("haven_get_task_budget", input);
|
|
819
|
+
return runTool(async () => {
|
|
820
|
+
const taskBudget = await haven.getTaskBudget(args.task_budget_id);
|
|
821
|
+
return { task_budget: taskBudget };
|
|
822
|
+
});
|
|
823
|
+
},
|
|
695
824
|
haven_submit: async (input) => {
|
|
696
825
|
const args = objectInput("haven_submit", input);
|
|
697
826
|
const hasTaskBudget = typeof args.task_budget_id === "string" && args.task_budget_id.length > 0;
|
|
827
|
+
const hasSubBudget = typeof args.sub_budget_id === "string" && args.sub_budget_id.length > 0;
|
|
698
828
|
const hasPayment = typeof args.payment_id === "string" && args.payment_id.length > 0;
|
|
699
|
-
if (hasTaskBudget
|
|
829
|
+
if ([hasTaskBudget, hasSubBudget, hasPayment].filter(Boolean).length !== 1) {
|
|
700
830
|
return {
|
|
701
831
|
success: false,
|
|
702
832
|
code: "INVALID_INPUT",
|
|
703
|
-
message: "haven_submit takes exactly one of task_budget_id or
|
|
833
|
+
message: "haven_submit takes exactly one of payment_id, task_budget_id or sub_budget_id, never two or none. Nothing was relayed."
|
|
704
834
|
};
|
|
705
835
|
}
|
|
836
|
+
if (hasSubBudget) {
|
|
837
|
+
return submitSubBudgetTool(haven, args.sub_budget_id, args.signature);
|
|
838
|
+
}
|
|
706
839
|
return runTool(async () => {
|
|
707
840
|
if (hasTaskBudget) {
|
|
708
841
|
const result = await haven.submitTaskBudget(args.task_budget_id, args.signature);
|
|
@@ -713,7 +846,7 @@ function createToolHandlers(haven) {
|
|
|
713
846
|
};
|
|
714
847
|
}
|
|
715
848
|
throw new HavenApiError(
|
|
716
|
-
"haven_submit with payment_id is not supported on the local MCP surface: haven_send signs and submits a direct payment in one call, so there is no separate relay step. Use haven_submit with task_budget_id to relay a
|
|
849
|
+
"haven_submit with payment_id is not supported on the local MCP surface: haven_send signs and submits a direct payment in one call, so there is no separate relay step. Use haven_submit with task_budget_id or sub_budget_id to relay a budget open/close signature.",
|
|
717
850
|
400
|
|
718
851
|
);
|
|
719
852
|
});
|
|
@@ -1153,7 +1286,7 @@ async function createHavenMcpServer(options = {}) {
|
|
|
1153
1286
|
return buildMcpServer(haven);
|
|
1154
1287
|
}
|
|
1155
1288
|
var MCP_NAME = "@haven_ai/mcp";
|
|
1156
|
-
var MCP_VERSION = "0.
|
|
1289
|
+
var MCP_VERSION = "0.8.0-alpha.0";
|
|
1157
1290
|
var MCP_INSTRUCTIONS = [
|
|
1158
1291
|
"Haven local MCP server: signs in-process with the delegate key it holds on",
|
|
1159
1292
|
"this machine \u2014 the key never leaves this process. Call haven_get_agent",
|