@haven_ai/mcp 0.1.34-alpha.0 → 0.1.35-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 +30 -3
- package/dist/cli.cjs +69 -14
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +69 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +69 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +69 -14
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -222,12 +222,16 @@ var toolSchemas = {
|
|
|
222
222
|
asset: v3.z.enum(["ETH", "USDC"]),
|
|
223
223
|
recipient: v3.z.string().min(1),
|
|
224
224
|
amount: v3.z.string().min(1),
|
|
225
|
+
idempotency_key: v3.z.string().optional(),
|
|
226
|
+
/** Legacy spelling, accepted during the #2366 window. Warns; do not use. */
|
|
225
227
|
idempotencyKey: v3.z.string().optional()
|
|
226
228
|
},
|
|
227
229
|
haven_pay_mcp_tool: {
|
|
228
230
|
merchant_url: v3.z.string().url(),
|
|
229
231
|
tool_name: v3.z.string().min(1),
|
|
230
232
|
arguments: v3.z.record(v3.z.string(), v3.z.unknown()).optional(),
|
|
233
|
+
idempotency_key: v3.z.string().optional(),
|
|
234
|
+
/** Legacy spelling, accepted during the #2366 window. Warns; do not use. */
|
|
231
235
|
idempotencyKey: v3.z.string().optional()
|
|
232
236
|
},
|
|
233
237
|
haven_quote_x402: {
|
|
@@ -235,10 +239,14 @@ var toolSchemas = {
|
|
|
235
239
|
method: v3.z.string().optional(),
|
|
236
240
|
headers: headersSchema,
|
|
237
241
|
body: v3.z.string().optional(),
|
|
242
|
+
idempotency_key: v3.z.string().optional(),
|
|
243
|
+
/** Legacy spelling, accepted during the #2366 window. Warns; do not use. */
|
|
238
244
|
idempotencyKey: v3.z.string().optional()
|
|
239
245
|
},
|
|
240
246
|
haven_pay_x402_quote: {
|
|
241
247
|
quote: v3.z.unknown(),
|
|
248
|
+
idempotency_key: v3.z.string().optional(),
|
|
249
|
+
/** Legacy spelling, accepted during the #2366 window. Warns; do not use. */
|
|
242
250
|
idempotencyKey: v3.z.string().optional()
|
|
243
251
|
},
|
|
244
252
|
haven_pay_x402: {
|
|
@@ -246,6 +254,8 @@ var toolSchemas = {
|
|
|
246
254
|
method: v3.z.string().optional(),
|
|
247
255
|
headers: headersSchema,
|
|
248
256
|
body: v3.z.string().optional(),
|
|
257
|
+
idempotency_key: v3.z.string().optional(),
|
|
258
|
+
/** Legacy spelling, accepted during the #2366 window. Warns; do not use. */
|
|
249
259
|
idempotencyKey: v3.z.string().optional()
|
|
250
260
|
},
|
|
251
261
|
haven_resume_x402_payment: {
|
|
@@ -298,8 +308,10 @@ var toolDescriptions = {
|
|
|
298
308
|
function createToolHandlers(haven) {
|
|
299
309
|
return {
|
|
300
310
|
haven_send: async (input) => {
|
|
311
|
+
const pf = preflight("haven_send", input);
|
|
312
|
+
if ("success" in pf) return pf;
|
|
313
|
+
const { args, warnings } = pf;
|
|
301
314
|
return runTool(async () => {
|
|
302
|
-
const args = objectInput("haven_send", input);
|
|
303
315
|
try {
|
|
304
316
|
const result = await haven.pay({
|
|
305
317
|
token: args.asset,
|
|
@@ -307,7 +319,7 @@ function createToolHandlers(haven) {
|
|
|
307
319
|
to: args.recipient,
|
|
308
320
|
// #1207: was accepted by the schema but silently dropped — now
|
|
309
321
|
// carried to the backend's replay contract.
|
|
310
|
-
idempotencyKey:
|
|
322
|
+
idempotencyKey: args.idempotencyKey
|
|
311
323
|
});
|
|
312
324
|
return {
|
|
313
325
|
payment_id: result.paymentId,
|
|
@@ -331,11 +343,13 @@ function createToolHandlers(haven) {
|
|
|
331
343
|
}
|
|
332
344
|
throw err;
|
|
333
345
|
}
|
|
334
|
-
});
|
|
346
|
+
}, warnings);
|
|
335
347
|
},
|
|
336
348
|
haven_pay_mcp_tool: async (input) => {
|
|
349
|
+
const pf = preflight("haven_pay_mcp_tool", input);
|
|
350
|
+
if ("success" in pf) return pf;
|
|
351
|
+
const { args, warnings } = pf;
|
|
337
352
|
return runTool(async () => {
|
|
338
|
-
const args = objectInput("haven_pay_mcp_tool", input);
|
|
339
353
|
const envelope = buildMcpToolsCallEnvelope(args.tool_name, args.arguments);
|
|
340
354
|
const init = {
|
|
341
355
|
method: "POST",
|
|
@@ -366,18 +380,23 @@ function createToolHandlers(haven) {
|
|
|
366
380
|
merchant_url: merchantUrl,
|
|
367
381
|
...merchantUrl !== args.merchant_url ? { merchant_url_discovered_from: args.merchant_url } : {}
|
|
368
382
|
};
|
|
369
|
-
});
|
|
383
|
+
}, warnings);
|
|
370
384
|
},
|
|
371
385
|
haven_quote_x402: async (input) => {
|
|
372
|
-
const
|
|
386
|
+
const pf = preflight("haven_quote_x402", input);
|
|
387
|
+
if ("success" in pf) return pf;
|
|
388
|
+
const { args, warnings } = pf;
|
|
373
389
|
try {
|
|
374
|
-
|
|
390
|
+
const data = await haven.quoteX402(args.url, requestInit(args), { idempotencyKey: args.idempotencyKey });
|
|
391
|
+
return warnings.length > 0 ? { success: true, data, warnings } : { success: true, data };
|
|
375
392
|
} catch (err) {
|
|
376
393
|
return normalizeError(err);
|
|
377
394
|
}
|
|
378
395
|
},
|
|
379
396
|
haven_pay_x402_quote: async (input) => {
|
|
380
|
-
const
|
|
397
|
+
const pf = preflight("haven_pay_x402_quote", input);
|
|
398
|
+
if ("success" in pf) return pf;
|
|
399
|
+
const { args, warnings } = pf;
|
|
381
400
|
const quote = args.quote;
|
|
382
401
|
if (!quote || typeof quote !== "object") {
|
|
383
402
|
return wrongTool(
|
|
@@ -396,14 +415,16 @@ function createToolHandlers(haven) {
|
|
|
396
415
|
return runTool(async () => {
|
|
397
416
|
const response = await haven.payX402Quote(args.quote, { idempotencyKey: args.idempotencyKey });
|
|
398
417
|
return responsePayload(response);
|
|
399
|
-
});
|
|
418
|
+
}, warnings);
|
|
400
419
|
},
|
|
401
420
|
haven_pay_x402: async (input) => {
|
|
402
|
-
const
|
|
421
|
+
const pf = preflight("haven_pay_x402", input);
|
|
422
|
+
if ("success" in pf) return pf;
|
|
423
|
+
const { args, warnings } = pf;
|
|
403
424
|
return runTool(async () => {
|
|
404
425
|
const response = await haven.fetch(args.url, requestInit(args), { idempotencyKey: args.idempotencyKey });
|
|
405
426
|
return responsePayload(response);
|
|
406
|
-
});
|
|
427
|
+
}, warnings);
|
|
407
428
|
},
|
|
408
429
|
haven_resume_x402_payment: async (input) => {
|
|
409
430
|
const args = objectInput("haven_resume_x402_payment", input);
|
|
@@ -501,6 +522,39 @@ function isPendingApproval(status) {
|
|
|
501
522
|
function wrongTool(code, message, suggested_tool) {
|
|
502
523
|
return { success: false, code, message, suggested_tool };
|
|
503
524
|
}
|
|
525
|
+
function preflight(name, input) {
|
|
526
|
+
let args;
|
|
527
|
+
try {
|
|
528
|
+
args = objectInput(name, input);
|
|
529
|
+
} catch (err) {
|
|
530
|
+
return normalizeError(err);
|
|
531
|
+
}
|
|
532
|
+
const idem = resolveIdempotencyKey(args);
|
|
533
|
+
if ("success" in idem) return idem;
|
|
534
|
+
if (idem.key !== void 0) args = { ...args, idempotencyKey: idem.key };
|
|
535
|
+
return { args, warnings: idem.warnings };
|
|
536
|
+
}
|
|
537
|
+
function resolveIdempotencyKey(args) {
|
|
538
|
+
const modern = typeof args.idempotency_key === "string" ? args.idempotency_key : void 0;
|
|
539
|
+
const legacy = typeof args.idempotencyKey === "string" ? args.idempotencyKey : void 0;
|
|
540
|
+
if (modern !== void 0 && legacy !== void 0 && modern !== legacy) {
|
|
541
|
+
return {
|
|
542
|
+
success: false,
|
|
543
|
+
code: "AMBIGUOUS_IDEMPOTENCY_KEY",
|
|
544
|
+
message: "Both idempotency_key and idempotencyKey were sent with different values. Nothing was contacted or spent. Send exactly one \u2014 idempotency_key is the current spelling; idempotencyKey is deprecated and will be removed."
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
if (modern !== void 0) return { key: modern, warnings: [] };
|
|
548
|
+
if (legacy !== void 0) {
|
|
549
|
+
return {
|
|
550
|
+
key: legacy,
|
|
551
|
+
warnings: [
|
|
552
|
+
"idempotencyKey is deprecated and will be removed in a future release of @haven_ai/mcp. Send idempotency_key instead \u2014 it is the spelling the hosted Haven MCP surface and every other Haven wire contract use."
|
|
553
|
+
]
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
return { warnings: [] };
|
|
557
|
+
}
|
|
504
558
|
function buildMcpToolsCallEnvelope(toolName, args) {
|
|
505
559
|
return {
|
|
506
560
|
jsonrpc: "2.0",
|
|
@@ -523,9 +577,10 @@ function requestInit(input) {
|
|
|
523
577
|
body: input.body
|
|
524
578
|
};
|
|
525
579
|
}
|
|
526
|
-
async function runTool(fn) {
|
|
580
|
+
async function runTool(fn, warnings = []) {
|
|
527
581
|
try {
|
|
528
|
-
|
|
582
|
+
const data = await fn();
|
|
583
|
+
return warnings.length > 0 ? { success: true, data, warnings } : { success: true, data };
|
|
529
584
|
} catch (err) {
|
|
530
585
|
return normalizeError(err);
|
|
531
586
|
}
|
|
@@ -804,7 +859,7 @@ async function createHavenMcpServer(options = {}) {
|
|
|
804
859
|
return buildMcpServer(haven);
|
|
805
860
|
}
|
|
806
861
|
var MCP_NAME = "@haven_ai/mcp";
|
|
807
|
-
var MCP_VERSION = "0.1.
|
|
862
|
+
var MCP_VERSION = "0.1.35-alpha.0";
|
|
808
863
|
var MCP_INSTRUCTIONS = [
|
|
809
864
|
"Haven local MCP server: signs in-process with the delegate key it holds on",
|
|
810
865
|
"this machine \u2014 the key never leaves this process. Call haven_get_agent",
|