@haven_ai/mcp 0.3.0-alpha.0 → 0.5.0-alpha.1
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.cjs +55 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +56 -12
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +55 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -4
- package/dist/index.d.ts +102 -4
- package/dist/index.js +56 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -304,11 +304,14 @@ var toolSchemas = {
|
|
|
304
304
|
website: v3.z.string().optional()
|
|
305
305
|
},
|
|
306
306
|
haven_list_receipts: {
|
|
307
|
-
limit: v3.z.number().int().min(1).max(100).optional()
|
|
307
|
+
limit: v3.z.number().int().min(1).max(100).optional(),
|
|
308
|
+
/** #3128: the previous page's next_cursor (a receipt id). */
|
|
309
|
+
cursor: v3.z.string().min(1).optional()
|
|
308
310
|
},
|
|
309
311
|
haven_verify_receipt: {
|
|
310
312
|
receipt: v3.z.unknown()
|
|
311
313
|
}
|
|
314
|
+
// #3101: keys survive on the type (see the hosted server's contracts.ts).
|
|
312
315
|
};
|
|
313
316
|
var toolDescriptions = {
|
|
314
317
|
haven_send: sdk.composeDescription(sdk.toolDescriptions.send),
|
|
@@ -499,12 +502,32 @@ function createToolHandlers(haven) {
|
|
|
499
502
|
source: entry.source,
|
|
500
503
|
domain_verified: entry.domainVerified,
|
|
501
504
|
verified_payable: entry.verifiedPayable,
|
|
502
|
-
// Which Haven pay tool reaches this entry from the local MCP surface
|
|
505
|
+
// Which Haven pay tool reaches this entry from the local MCP surface,
|
|
506
|
+
// and — #3100 (epic #3105, decision 4) — the arguments that tool
|
|
507
|
+
// accepts VERBATIM, spelled in ITS vocabulary (`merchant_url`, not
|
|
508
|
+
// the entry's `resource_url`). The local surface keeps pointing at
|
|
509
|
+
// its pay tools: they need no cap, so a verbatim hint exists.
|
|
503
510
|
// #1328: the 'mpp' rail's only-ever catalog row (the Haven MPP demo
|
|
504
511
|
// resource) is delisted with the mpp_demo retirement, so this
|
|
505
512
|
// fallback is unreachable today; it stays x402 rather than naming a
|
|
506
513
|
// deleted tool in case a future non-demo 'mpp' rail entry appears.
|
|
507
|
-
|
|
514
|
+
// A row without a tool_name cannot get a verbatim hint —
|
|
515
|
+
// haven_pay_mcp_tool requires tool_name — so it gets the REASON
|
|
516
|
+
// instead of a hint its own tool refuses (haven-reviewer on #3113;
|
|
517
|
+
// the epic's "omitted + reason, never null" shape, decision 3).
|
|
518
|
+
...entry.protocol === "mcp" ? entry.toolName ? {
|
|
519
|
+
suggested_tool: "haven_pay_mcp_tool",
|
|
520
|
+
suggested_arguments: {
|
|
521
|
+
merchant_url: entry.resourceUrl,
|
|
522
|
+
tool_name: entry.toolName,
|
|
523
|
+
...entry.toolArguments ? { arguments: entry.toolArguments } : {}
|
|
524
|
+
}
|
|
525
|
+
} : {
|
|
526
|
+
suggested_tool_omitted_reason: "this catalog row carries no tool_name, which haven_pay_mcp_tool requires; read the merchant's tool list yourself, then call haven_pay_mcp_tool with merchant_url, tool_name and arguments"
|
|
527
|
+
} : {
|
|
528
|
+
suggested_tool: "haven_pay_x402",
|
|
529
|
+
suggested_arguments: { url: entry.resourceUrl }
|
|
530
|
+
}
|
|
508
531
|
}));
|
|
509
532
|
});
|
|
510
533
|
},
|
|
@@ -524,7 +547,7 @@ function createToolHandlers(haven) {
|
|
|
524
547
|
},
|
|
525
548
|
haven_list_receipts: async (input) => {
|
|
526
549
|
const args = objectInput("haven_list_receipts", input);
|
|
527
|
-
return runTool(async () => haven.
|
|
550
|
+
return runTool(async () => haven.listReceiptsPage({ limit: args.limit, cursor: args.cursor }));
|
|
528
551
|
},
|
|
529
552
|
haven_verify_receipt: async (input) => {
|
|
530
553
|
const args = objectInput("haven_verify_receipt", input);
|
|
@@ -669,7 +692,11 @@ function normalizeError(err) {
|
|
|
669
692
|
message: err.message,
|
|
670
693
|
statusCode: err.statusCode,
|
|
671
694
|
nextAction: err.nextAction,
|
|
672
|
-
|
|
695
|
+
next_action: err.nextAction,
|
|
696
|
+
retry_with_new_quote: err.retryWithNewQuote,
|
|
697
|
+
// #3103: the local runtime's one decision site — no tool can act until
|
|
698
|
+
// the merchant recovers; the message carries retry_after_s.
|
|
699
|
+
next_tool_omitted_reason: "the merchant needs to recover first; re-quote after the retry_after_s in the message"
|
|
673
700
|
};
|
|
674
701
|
}
|
|
675
702
|
if (err instanceof sdk.HavenPaymentStateError) {
|
|
@@ -682,6 +709,7 @@ function normalizeError(err) {
|
|
|
682
709
|
status: err.status,
|
|
683
710
|
phase: err.phase,
|
|
684
711
|
nextAction: err.nextAction,
|
|
712
|
+
next_action: err.nextAction,
|
|
685
713
|
resume_state: err.resumeState,
|
|
686
714
|
body: err.body
|
|
687
715
|
};
|
|
@@ -703,6 +731,10 @@ function normalizeError(err) {
|
|
|
703
731
|
paymentId: err.paymentId,
|
|
704
732
|
phase: stringOrUndefined(body?.phase),
|
|
705
733
|
nextAction: stringOrUndefined(body?.nextAction) ?? stringOrUndefined(body?.next_action) ?? sdk.AgentPaymentNextAction.StopAndTellUser,
|
|
734
|
+
next_action: stringOrUndefined(body?.nextAction) ?? stringOrUndefined(body?.next_action) ?? sdk.AgentPaymentNextAction.StopAndTellUser,
|
|
735
|
+
// #3303: a backend refusal that already names why no tool follows (the
|
|
736
|
+
// 426 `client_outdated` does) keeps that reason at the top level.
|
|
737
|
+
...typeof body?.next_tool_omitted_reason === "string" ? { next_tool_omitted_reason: body.next_tool_omitted_reason } : {},
|
|
706
738
|
body: err.body
|
|
707
739
|
};
|
|
708
740
|
}
|
|
@@ -719,7 +751,11 @@ function normalizeError(err) {
|
|
|
719
751
|
success: false,
|
|
720
752
|
code: "UNKNOWN_ERROR",
|
|
721
753
|
message: err instanceof Error ? err.message : String(err),
|
|
722
|
-
nextAction: sdk.AgentPaymentNextAction.StopAndTellUser
|
|
754
|
+
nextAction: sdk.AgentPaymentNextAction.StopAndTellUser,
|
|
755
|
+
next_action: sdk.AgentPaymentNextAction.StopAndTellUser,
|
|
756
|
+
// #3103: the second local decision site — nothing structured can follow an
|
|
757
|
+
// error this runtime did not recognise.
|
|
758
|
+
next_tool_omitted_reason: "an error this runtime does not recognise; tell the user what the message says"
|
|
723
759
|
};
|
|
724
760
|
}
|
|
725
761
|
function stringOrUndefined(value) {
|
|
@@ -751,7 +787,7 @@ function renderConsentBlock(input, hash) {
|
|
|
751
787
|
];
|
|
752
788
|
if (input.apiUrl) lines.push(`Haven API: ${input.apiUrl}`);
|
|
753
789
|
if (input.agentId) lines.push(`Agent ID: ${input.agentId}`);
|
|
754
|
-
if (input.accountAddress) lines.push(`Haven wallet
|
|
790
|
+
if (input.accountAddress) lines.push(`Haven wallet: ${input.accountAddress}`);
|
|
755
791
|
if (input.delegateAddress) lines.push(`Delegate (local signer): ${input.delegateAddress}`);
|
|
756
792
|
if (typeof input.chainId === "number") lines.push(`Chain ID: ${input.chainId}`);
|
|
757
793
|
lines.push("");
|
|
@@ -914,7 +950,10 @@ async function resolveHavenClient(options = {}) {
|
|
|
914
950
|
const client = new sdk.HavenClient({
|
|
915
951
|
apiKey: credentials.apiKey,
|
|
916
952
|
delegateKey: credentials.delegateKey,
|
|
917
|
-
baseUrl: credentials.apiUrl
|
|
953
|
+
baseUrl: credentials.apiUrl,
|
|
954
|
+
// #3303: name this package, not the SDK inside it, so the backend's
|
|
955
|
+
// update hint and refusal speak about what the user actually installed.
|
|
956
|
+
clientIdentity: sdk.havenClientIdentity(MCP_NAME, MCP_VERSION)
|
|
918
957
|
});
|
|
919
958
|
return { client, credentials };
|
|
920
959
|
}
|
|
@@ -923,7 +962,7 @@ async function createHavenMcpServer(options = {}) {
|
|
|
923
962
|
return buildMcpServer(haven);
|
|
924
963
|
}
|
|
925
964
|
var MCP_NAME = "@haven_ai/mcp";
|
|
926
|
-
var MCP_VERSION = "0.
|
|
965
|
+
var MCP_VERSION = "0.5.0-alpha.1";
|
|
927
966
|
var MCP_INSTRUCTIONS = [
|
|
928
967
|
"Haven local MCP server: signs in-process with the delegate key it holds on",
|
|
929
968
|
"this machine \u2014 the key never leaves this process. Call haven_get_agent",
|
|
@@ -932,7 +971,8 @@ var MCP_INSTRUCTIONS = [
|
|
|
932
971
|
"",
|
|
933
972
|
"To pay: haven_discover_tools to find a payable service, then",
|
|
934
973
|
"haven_pay_mcp_tool for MCP merchants or haven_pay_x402 for any x402",
|
|
935
|
-
"paywall. Tool responses carry nextAction
|
|
974
|
+
"paywall. Tool responses carry next_action (nextAction is the same value, kept one more",
|
|
975
|
+
"release) and, when no tool follows, next_tool_omitted_reason \u2014 follow them; description prose",
|
|
936
976
|
"is fallback, not the source of truth.",
|
|
937
977
|
"",
|
|
938
978
|
"A payment outside the agent budget is declined before any money moves. Haven",
|
|
@@ -959,7 +999,7 @@ function buildMcpServer(haven) {
|
|
|
959
999
|
toolSchemas[name],
|
|
960
1000
|
async (args) => haven.withRequestContext(
|
|
961
1001
|
{ "X-Haven-MCP-Tool": name },
|
|
962
|
-
async () => toMcpResult(await handlers[name](args))
|
|
1002
|
+
async () => toMcpResult(withClientUpdate(await handlers[name](args), haven.clientUpdate()))
|
|
963
1003
|
)
|
|
964
1004
|
);
|
|
965
1005
|
}
|
|
@@ -1009,6 +1049,10 @@ async function runConsentGate(haven, credentials, options) {
|
|
|
1009
1049
|
writeAck: options.writeAck
|
|
1010
1050
|
});
|
|
1011
1051
|
}
|
|
1052
|
+
function withClientUpdate(payload, hint) {
|
|
1053
|
+
if (!hint || payload.client_update) return payload;
|
|
1054
|
+
return { ...payload, client_update: hint };
|
|
1055
|
+
}
|
|
1012
1056
|
function toMcpResult(payload) {
|
|
1013
1057
|
return {
|
|
1014
1058
|
isError: !payload.success,
|