@paybond/kit 0.9.7 → 0.10.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/dist/cli/audit-export.d.ts +7 -0
- package/dist/cli/audit-export.js +120 -0
- package/dist/cli/automation.d.ts +25 -0
- package/dist/cli/automation.js +297 -0
- package/dist/cli/body.d.ts +7 -0
- package/dist/cli/body.js +22 -0
- package/dist/cli/color.d.ts +15 -0
- package/dist/cli/color.js +39 -0
- package/dist/cli/command-spec.d.ts +12 -0
- package/dist/cli/command-spec.js +330 -0
- package/dist/cli/commands/discovery.d.ts +8 -0
- package/dist/cli/commands/discovery.js +194 -0
- package/dist/cli/commands/setup.d.ts +15 -0
- package/dist/cli/commands/setup.js +397 -0
- package/dist/cli/commands/workflows.d.ts +7 -0
- package/dist/cli/commands/workflows.js +209 -0
- package/dist/cli/config.d.ts +14 -0
- package/dist/cli/config.js +96 -0
- package/dist/cli/context.d.ts +22 -0
- package/dist/cli/context.js +109 -0
- package/dist/cli/credentials.d.ts +21 -0
- package/dist/cli/credentials.js +141 -0
- package/dist/cli/doctor-agent.d.ts +15 -0
- package/dist/cli/doctor-agent.js +311 -0
- package/dist/cli/envelope.d.ts +14 -0
- package/dist/cli/envelope.js +46 -0
- package/dist/cli/globals.d.ts +22 -0
- package/dist/cli/globals.js +238 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.js +51 -0
- package/dist/cli/mcp-install.d.ts +41 -0
- package/dist/cli/mcp-install.js +95 -0
- package/dist/cli/mcp-policy.d.ts +23 -0
- package/dist/cli/mcp-policy.js +104 -0
- package/dist/cli/mcp-verify-config.d.ts +37 -0
- package/dist/cli/mcp-verify-config.js +174 -0
- package/dist/cli/redact.d.ts +4 -0
- package/dist/cli/redact.js +67 -0
- package/dist/cli/request-id.d.ts +2 -0
- package/dist/cli/request-id.js +5 -0
- package/dist/cli/router.d.ts +2 -0
- package/dist/cli/router.js +275 -0
- package/dist/cli/suggest.d.ts +4 -0
- package/dist/cli/suggest.js +58 -0
- package/dist/cli/support-diagnostics.d.ts +19 -0
- package/dist/cli/support-diagnostics.js +47 -0
- package/dist/cli/types.d.ts +72 -0
- package/dist/cli/types.js +60 -0
- package/dist/cli/ux.d.ts +8 -0
- package/dist/cli/ux.js +164 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +38 -0
- package/dist/index.d.ts +46 -12
- package/dist/index.js +136 -47
- package/dist/init.js +9 -14
- package/dist/login.d.ts +14 -1
- package/dist/login.js +123 -63
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.js +204 -76
- package/package.json +5 -2
package/dist/mcp-server.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { runCli } from "./cli/router.js";
|
|
8
|
+
import { MCP_TOOL_ALLOWLIST_ENV, MCP_TOOL_POLICY_ENV, mergeMcpToolPolicy, parseMcpToolAllowlist, parseMcpToolPolicy, toolAllowedByPolicy, } from "./cli/mcp-policy.js";
|
|
4
9
|
import { GatewayAuthError, GatewayFraudClient, GatewaySignalClient, SignalHttpError, DEFAULT_PAYBOND_GATEWAY_BASE_URL, } from "./index.js";
|
|
5
10
|
const SERVER_NAME = "Paybond MCP";
|
|
6
|
-
const SERVER_VERSION = "0.
|
|
11
|
+
const SERVER_VERSION = "0.10.0";
|
|
7
12
|
const MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
8
13
|
const DEFAULT_PRINCIPAL_PATH = "/v1/auth/principal";
|
|
9
14
|
const DEFAULT_RECOGNITION_VERIFIER_ID = "paybond-gateway";
|
|
@@ -14,7 +19,10 @@ const TOOL_SELECTION_METADATA = {
|
|
|
14
19
|
title: "Get Paybond Principal",
|
|
15
20
|
annotations: readOnlyToolAnnotations("Get Paybond Principal"),
|
|
16
21
|
outputSchema: outputObjectSchema({
|
|
17
|
-
tenant_id: {
|
|
22
|
+
tenant_id: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Tenant bound to the configured Paybond API key.",
|
|
25
|
+
},
|
|
18
26
|
subject: { type: "string" },
|
|
19
27
|
roles: { type: "array", items: { type: "string" } },
|
|
20
28
|
}),
|
|
@@ -25,10 +33,22 @@ const TOOL_SELECTION_METADATA = {
|
|
|
25
33
|
"Do not use this to create, fund, or modify intents; use paybond_authorize_agent_spend as the clearer gate before side-effecting agent tools.",
|
|
26
34
|
annotations: additiveMutationToolAnnotations("Verify Paybond Capability"),
|
|
27
35
|
outputSchema: outputObjectSchema({
|
|
28
|
-
allow: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
allow: {
|
|
37
|
+
type: "boolean",
|
|
38
|
+
description: "Whether the requested operation is allowed.",
|
|
39
|
+
},
|
|
40
|
+
tenant: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Tenant echoed by the gateway.",
|
|
43
|
+
},
|
|
44
|
+
intent_id: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "Verified Harbor intent UUID.",
|
|
47
|
+
},
|
|
48
|
+
audit_id: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Gateway audit identifier when available.",
|
|
51
|
+
},
|
|
32
52
|
}, ["tenant", "intent_id"]),
|
|
33
53
|
},
|
|
34
54
|
paybond_authorize_agent_spend: {
|
|
@@ -37,10 +57,22 @@ const TOOL_SELECTION_METADATA = {
|
|
|
37
57
|
"Do not use this for creating, funding, or changing intents; call paybond_create_spend_intent or paybond_fund_intent first when no funded capability token exists.",
|
|
38
58
|
annotations: additiveMutationToolAnnotations("Authorize Agent Spend"),
|
|
39
59
|
outputSchema: outputObjectSchema({
|
|
40
|
-
allow: {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
allow: {
|
|
61
|
+
type: "boolean",
|
|
62
|
+
description: "Whether the requested operation is allowed.",
|
|
63
|
+
},
|
|
64
|
+
tenant: {
|
|
65
|
+
type: "string",
|
|
66
|
+
description: "Tenant echoed by the gateway.",
|
|
67
|
+
},
|
|
68
|
+
intent_id: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "Verified Harbor intent UUID.",
|
|
71
|
+
},
|
|
72
|
+
audit_id: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Gateway audit identifier when available.",
|
|
75
|
+
},
|
|
44
76
|
}, ["tenant", "intent_id"]),
|
|
45
77
|
},
|
|
46
78
|
paybond_bootstrap_sandbox_guardrail: {
|
|
@@ -57,7 +89,14 @@ const TOOL_SELECTION_METADATA = {
|
|
|
57
89
|
sandbox_lifecycle_status: { type: "string" },
|
|
58
90
|
settlement_rail: { type: "string" },
|
|
59
91
|
settlement_mode: { type: "string" },
|
|
60
|
-
}, [
|
|
92
|
+
}, [
|
|
93
|
+
"tenant_id",
|
|
94
|
+
"intent_id",
|
|
95
|
+
"capability_token",
|
|
96
|
+
"operation",
|
|
97
|
+
"requested_spend_cents",
|
|
98
|
+
"sandbox_lifecycle_status",
|
|
99
|
+
]),
|
|
61
100
|
},
|
|
62
101
|
paybond_submit_sandbox_guardrail_evidence: {
|
|
63
102
|
title: "Submit Sandbox Guardrail Evidence",
|
|
@@ -72,13 +111,22 @@ const TOOL_SELECTION_METADATA = {
|
|
|
72
111
|
sandbox_lifecycle_status: { type: "string" },
|
|
73
112
|
predicate_passed: { type: "boolean" },
|
|
74
113
|
payload_digest: { type: "string" },
|
|
75
|
-
}, [
|
|
114
|
+
}, [
|
|
115
|
+
"tenant_id",
|
|
116
|
+
"intent_id",
|
|
117
|
+
"operation",
|
|
118
|
+
"requested_spend_cents",
|
|
119
|
+
"sandbox_lifecycle_status",
|
|
120
|
+
]),
|
|
76
121
|
},
|
|
77
122
|
paybond_list_intents: {
|
|
78
123
|
title: "List Harbor Intents",
|
|
79
124
|
annotations: readOnlyToolAnnotations("List Harbor Intents"),
|
|
80
125
|
outputSchema: outputObjectSchema({
|
|
81
|
-
items: {
|
|
126
|
+
items: {
|
|
127
|
+
type: "array",
|
|
128
|
+
items: { type: "object", additionalProperties: true },
|
|
129
|
+
},
|
|
82
130
|
next_cursor: { type: "string" },
|
|
83
131
|
}),
|
|
84
132
|
},
|
|
@@ -106,7 +154,10 @@ const TOOL_SELECTION_METADATA = {
|
|
|
106
154
|
outputSchema: outputObjectSchema({
|
|
107
155
|
tenant_id: { type: "string" },
|
|
108
156
|
score_model_version: { type: "string" },
|
|
109
|
-
operators: {
|
|
157
|
+
operators: {
|
|
158
|
+
type: "array",
|
|
159
|
+
items: { type: "object", additionalProperties: true },
|
|
160
|
+
},
|
|
110
161
|
}),
|
|
111
162
|
},
|
|
112
163
|
paybond_get_signed_portfolio_artifact: {
|
|
@@ -144,14 +195,20 @@ const TOOL_SELECTION_METADATA = {
|
|
|
144
195
|
outputSchema: outputObjectSchema({
|
|
145
196
|
name: { type: "string" },
|
|
146
197
|
version: { type: "string" },
|
|
147
|
-
skills: {
|
|
198
|
+
skills: {
|
|
199
|
+
type: "array",
|
|
200
|
+
items: { type: "object", additionalProperties: true },
|
|
201
|
+
},
|
|
148
202
|
}),
|
|
149
203
|
},
|
|
150
204
|
paybond_list_a2a_task_contracts: {
|
|
151
205
|
title: "List A2A Task Contracts",
|
|
152
206
|
annotations: readOnlyToolAnnotations("List A2A Task Contracts"),
|
|
153
207
|
outputSchema: outputObjectSchema({
|
|
154
|
-
contracts: {
|
|
208
|
+
contracts: {
|
|
209
|
+
type: "array",
|
|
210
|
+
items: { type: "object", additionalProperties: true },
|
|
211
|
+
},
|
|
155
212
|
}),
|
|
156
213
|
},
|
|
157
214
|
paybond_get_a2a_task_contract: {
|
|
@@ -327,8 +384,12 @@ function parseGatewayErrorEnvelope(text) {
|
|
|
327
384
|
if (body === null || Array.isArray(body) || typeof body !== "object") {
|
|
328
385
|
return {};
|
|
329
386
|
}
|
|
330
|
-
const errorCode = typeof body.error === "string" && body.error.trim()
|
|
331
|
-
|
|
387
|
+
const errorCode = typeof body.error === "string" && body.error.trim()
|
|
388
|
+
? body.error.trim()
|
|
389
|
+
: undefined;
|
|
390
|
+
const errorMessage = typeof body.message === "string" && body.message.trim()
|
|
391
|
+
? body.message.trim()
|
|
392
|
+
: undefined;
|
|
332
393
|
return { errorCode, errorMessage };
|
|
333
394
|
}
|
|
334
395
|
catch {
|
|
@@ -369,7 +430,9 @@ class GatewayAPIClient {
|
|
|
369
430
|
accept: "application/json",
|
|
370
431
|
authorization: `Bearer ${this.apiKey}`,
|
|
371
432
|
...(extraHeaders ?? {}),
|
|
372
|
-
...(payload === undefined
|
|
433
|
+
...(payload === undefined
|
|
434
|
+
? {}
|
|
435
|
+
: { "content-type": "application/json" }),
|
|
373
436
|
},
|
|
374
437
|
...(payload === undefined ? {} : { body: JSON.stringify(payload) }),
|
|
375
438
|
});
|
|
@@ -382,7 +445,8 @@ class GatewayAPIClient {
|
|
|
382
445
|
await delay(backoffMs(attempt));
|
|
383
446
|
continue;
|
|
384
447
|
}
|
|
385
|
-
if ([429, 500, 502, 503, 504].includes(res.status) &&
|
|
448
|
+
if ([429, 500, 502, 503, 504].includes(res.status) &&
|
|
449
|
+
attempt + 1 < this.maxRetries) {
|
|
386
450
|
const retryAfter = parseRetryAfterSeconds(res.headers.get("retry-after"));
|
|
387
451
|
await delay(retryAfter != null ? retryAfter * 1000 : backoffMs(attempt));
|
|
388
452
|
continue;
|
|
@@ -620,7 +684,9 @@ class PaybondMCPRuntime {
|
|
|
620
684
|
async fundHarborIntent(init) {
|
|
621
685
|
return this.gateway.postJSON(`/harbor/intents/${encodeURIComponent(init.intentId)}/fund`, {}, gatewayMutationHeaders(await this.tenantId(), init.recognitionProof, {
|
|
622
686
|
...optionalMutationHeaders(init.idempotencyKey),
|
|
623
|
-
...(init.paymentSignature?.trim()
|
|
687
|
+
...(init.paymentSignature?.trim()
|
|
688
|
+
? { "payment-signature": init.paymentSignature.trim() }
|
|
689
|
+
: {}),
|
|
624
690
|
}));
|
|
625
691
|
}
|
|
626
692
|
async submitHarborEvidence(init) {
|
|
@@ -643,16 +709,22 @@ function gatewayMutationHeaders(tenantId, recognitionProof, extraHeaders) {
|
|
|
643
709
|
[agentRecognitionProofHeader]: encodeRecognitionProofHeader(recognitionProof),
|
|
644
710
|
};
|
|
645
711
|
}
|
|
712
|
+
export function formatMcpStdioFrame(response) {
|
|
713
|
+
const body = JSON.stringify(response);
|
|
714
|
+
return `Content-Length: ${Buffer.byteLength(body, "utf8")}\r\n\r\n${body}`;
|
|
715
|
+
}
|
|
646
716
|
export class PaybondMCPServer {
|
|
647
717
|
runtime;
|
|
648
718
|
tools;
|
|
719
|
+
toolPolicy;
|
|
649
720
|
initialized = false;
|
|
650
721
|
constructor(settings) {
|
|
651
722
|
if (!settings.apiKey.trim()) {
|
|
652
723
|
throw new Error("PAYBOND_API_KEY is required");
|
|
653
724
|
}
|
|
725
|
+
this.toolPolicy = settings.toolPolicy ?? { policy: null, allowlist: [] };
|
|
654
726
|
this.runtime = new PaybondMCPRuntime(settings);
|
|
655
|
-
this.tools = this.buildTools(settings);
|
|
727
|
+
this.tools = this.buildTools(settings).filter((tool) => toolAllowedByPolicy(tool.name, tool.annotations, this.toolPolicy));
|
|
656
728
|
}
|
|
657
729
|
listTools() {
|
|
658
730
|
return this.tools.map((tool) => ({
|
|
@@ -660,8 +732,12 @@ export class PaybondMCPServer {
|
|
|
660
732
|
title: tool.title,
|
|
661
733
|
description: tool.description,
|
|
662
734
|
inputSchema: tool.inputSchema,
|
|
663
|
-
...(tool.outputSchema === undefined
|
|
664
|
-
|
|
735
|
+
...(tool.outputSchema === undefined
|
|
736
|
+
? {}
|
|
737
|
+
: { outputSchema: tool.outputSchema }),
|
|
738
|
+
...(tool.annotations === undefined
|
|
739
|
+
? {}
|
|
740
|
+
: { annotations: tool.annotations }),
|
|
665
741
|
}));
|
|
666
742
|
}
|
|
667
743
|
async callTool(name, args = {}) {
|
|
@@ -672,6 +748,17 @@ export class PaybondMCPServer {
|
|
|
672
748
|
isError: true,
|
|
673
749
|
};
|
|
674
750
|
}
|
|
751
|
+
if (!toolAllowedByPolicy(name, tool.annotations, this.toolPolicy)) {
|
|
752
|
+
return {
|
|
753
|
+
content: [
|
|
754
|
+
{
|
|
755
|
+
type: "text",
|
|
756
|
+
text: `Tool blocked by ${MCP_TOOL_POLICY_ENV}=${this.toolPolicy.policy ?? "unset"}: ${name}`,
|
|
757
|
+
},
|
|
758
|
+
],
|
|
759
|
+
isError: true,
|
|
760
|
+
};
|
|
761
|
+
}
|
|
675
762
|
try {
|
|
676
763
|
const value = await tool.call(args);
|
|
677
764
|
return toToolResult(value);
|
|
@@ -740,7 +827,9 @@ export class PaybondMCPServer {
|
|
|
740
827
|
case "tools/call": {
|
|
741
828
|
const params = ensureObject(message.params, "tools/call params");
|
|
742
829
|
const name = stringArg(params.name, "name");
|
|
743
|
-
const args = params.arguments === undefined
|
|
830
|
+
const args = params.arguments === undefined
|
|
831
|
+
? {}
|
|
832
|
+
: ensureObject(params.arguments, "arguments");
|
|
744
833
|
return {
|
|
745
834
|
jsonrpc: "2.0",
|
|
746
835
|
id: message.id,
|
|
@@ -752,26 +841,36 @@ export class PaybondMCPServer {
|
|
|
752
841
|
}
|
|
753
842
|
}
|
|
754
843
|
runStdio() {
|
|
755
|
-
let buffer =
|
|
756
|
-
process.stdin.setEncoding("utf8");
|
|
844
|
+
let buffer = Buffer.alloc(0);
|
|
757
845
|
process.stdin.on("data", (chunk) => {
|
|
758
|
-
buffer
|
|
846
|
+
buffer = Buffer.concat([buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8")]);
|
|
759
847
|
while (true) {
|
|
760
|
-
const
|
|
761
|
-
if (
|
|
848
|
+
const headerEnd = buffer.indexOf("\r\n\r\n");
|
|
849
|
+
if (headerEnd < 0) {
|
|
762
850
|
break;
|
|
763
851
|
}
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
852
|
+
const headerText = buffer.subarray(0, headerEnd).toString("ascii");
|
|
853
|
+
const contentLength = Number.parseInt(headerText
|
|
854
|
+
.split("\r\n")
|
|
855
|
+
.find((line) => line.toLowerCase().startsWith("content-length:"))
|
|
856
|
+
?.split(":", 2)[1]
|
|
857
|
+
?.trim() ?? "", 10);
|
|
858
|
+
if (!Number.isFinite(contentLength) || contentLength <= 0) {
|
|
859
|
+
break;
|
|
768
860
|
}
|
|
769
|
-
|
|
861
|
+
const bodyStart = headerEnd + 4;
|
|
862
|
+
const frameEnd = bodyStart + contentLength;
|
|
863
|
+
if (buffer.length < frameEnd) {
|
|
864
|
+
break;
|
|
865
|
+
}
|
|
866
|
+
const body = buffer.subarray(bodyStart, frameEnd).toString("utf8");
|
|
867
|
+
buffer = buffer.subarray(frameEnd);
|
|
868
|
+
void this.handleLine(body);
|
|
770
869
|
}
|
|
771
870
|
});
|
|
772
871
|
process.stdin.on("end", () => {
|
|
773
|
-
if (buffer.
|
|
774
|
-
void this.handleLine(buffer.
|
|
872
|
+
if (buffer.length > 0) {
|
|
873
|
+
void this.handleLine(buffer.toString("utf8"));
|
|
775
874
|
}
|
|
776
875
|
});
|
|
777
876
|
process.stdin.resume();
|
|
@@ -791,7 +890,7 @@ export class PaybondMCPServer {
|
|
|
791
890
|
}
|
|
792
891
|
}
|
|
793
892
|
writeResponse(response) {
|
|
794
|
-
process.stdout.write(
|
|
893
|
+
process.stdout.write(formatMcpStdioFrame(response));
|
|
795
894
|
}
|
|
796
895
|
buildTools(settings) {
|
|
797
896
|
const tools = [
|
|
@@ -805,12 +904,18 @@ export class PaybondMCPServer {
|
|
|
805
904
|
name: "paybond_verify_capability",
|
|
806
905
|
description: "Verify a capability token returned by a created or funded Paybond intent for one tenant-bound Harbor intent.",
|
|
807
906
|
inputSchema: objectSchema({
|
|
808
|
-
intent_id: {
|
|
907
|
+
intent_id: {
|
|
908
|
+
type: "string",
|
|
909
|
+
description: "Canonical Harbor intent UUID.",
|
|
910
|
+
},
|
|
809
911
|
token: {
|
|
810
912
|
type: "string",
|
|
811
913
|
description: "Capability token returned by paybond_create_spend_intent or paybond_fund_intent.",
|
|
812
914
|
},
|
|
813
|
-
operation: {
|
|
915
|
+
operation: {
|
|
916
|
+
type: "string",
|
|
917
|
+
description: "Delegated operation or tool name.",
|
|
918
|
+
},
|
|
814
919
|
requested_spend_cents: {
|
|
815
920
|
type: "integer",
|
|
816
921
|
description: "Optional requested spend in cents for this tool call.",
|
|
@@ -829,12 +934,18 @@ export class PaybondMCPServer {
|
|
|
829
934
|
name: "paybond_authorize_agent_spend",
|
|
830
935
|
description: "Provider-agnostic spend gate: verify the funded intent's capability token before a side-effecting tool, paid API, vendor action, or settlement workflow executes.",
|
|
831
936
|
inputSchema: objectSchema({
|
|
832
|
-
intent_id: {
|
|
937
|
+
intent_id: {
|
|
938
|
+
type: "string",
|
|
939
|
+
description: "Canonical Harbor intent UUID.",
|
|
940
|
+
},
|
|
833
941
|
token: {
|
|
834
942
|
type: "string",
|
|
835
943
|
description: "Capability token returned by paybond_create_spend_intent or paybond_fund_intent.",
|
|
836
944
|
},
|
|
837
|
-
operation: {
|
|
945
|
+
operation: {
|
|
946
|
+
type: "string",
|
|
947
|
+
description: "Delegated operation or tool name.",
|
|
948
|
+
},
|
|
838
949
|
requested_spend_cents: {
|
|
839
950
|
type: "integer",
|
|
840
951
|
description: "Optional requested spend in cents for this tool call.",
|
|
@@ -853,12 +964,18 @@ export class PaybondMCPServer {
|
|
|
853
964
|
name: "paybond_bootstrap_sandbox_guardrail",
|
|
854
965
|
description: "Bootstrap a sandbox-only Paybond guardrail intent for a first paid-tool integration. Tenant scope is derived from the configured service-account API key and the route never touches live settlement rails.",
|
|
855
966
|
inputSchema: objectSchema({
|
|
856
|
-
operation: {
|
|
967
|
+
operation: {
|
|
968
|
+
type: "string",
|
|
969
|
+
description: "Delegated operation or paid tool name.",
|
|
970
|
+
},
|
|
857
971
|
requested_spend_cents: {
|
|
858
972
|
type: "integer",
|
|
859
973
|
description: "Sandbox spend amount in cents to authorize for the sample tool call.",
|
|
860
974
|
},
|
|
861
|
-
currency: {
|
|
975
|
+
currency: {
|
|
976
|
+
type: "string",
|
|
977
|
+
description: "Optional ISO currency code; defaults at the gateway.",
|
|
978
|
+
},
|
|
862
979
|
evidence_schema: { type: "object", additionalProperties: true },
|
|
863
980
|
metadata: { type: "object", additionalProperties: true },
|
|
864
981
|
idempotency_key: { type: "string" },
|
|
@@ -867,8 +984,12 @@ export class PaybondMCPServer {
|
|
|
867
984
|
operation: stringArg(args.operation, "operation"),
|
|
868
985
|
requestedSpendCents: intArg(args.requested_spend_cents, "requested_spend_cents"),
|
|
869
986
|
currency: optionalString(args.currency),
|
|
870
|
-
evidenceSchema: args.evidence_schema === undefined
|
|
871
|
-
|
|
987
|
+
evidenceSchema: args.evidence_schema === undefined
|
|
988
|
+
? undefined
|
|
989
|
+
: ensureObject(args.evidence_schema, "evidence_schema"),
|
|
990
|
+
metadata: args.metadata === undefined
|
|
991
|
+
? undefined
|
|
992
|
+
: ensureObject(args.metadata, "metadata"),
|
|
872
993
|
idempotencyKey: optionalString(args.idempotency_key),
|
|
873
994
|
}),
|
|
874
995
|
},
|
|
@@ -876,10 +997,16 @@ export class PaybondMCPServer {
|
|
|
876
997
|
name: "paybond_submit_sandbox_guardrail_evidence",
|
|
877
998
|
description: "Submit evidence for a sandbox-only Paybond guardrail intent. Tenant scope is derived from the configured service-account API key and simulator settlement remains sandbox-only.",
|
|
878
999
|
inputSchema: objectSchema({
|
|
879
|
-
intent_id: {
|
|
1000
|
+
intent_id: {
|
|
1001
|
+
type: "string",
|
|
1002
|
+
description: "Sandbox guardrail intent UUID.",
|
|
1003
|
+
},
|
|
880
1004
|
payload: { type: "object", additionalProperties: true },
|
|
881
1005
|
artifacts: { type: "array", items: { type: "string" } },
|
|
882
|
-
operation: {
|
|
1006
|
+
operation: {
|
|
1007
|
+
type: "string",
|
|
1008
|
+
description: "Optional operation override for the evidence record.",
|
|
1009
|
+
},
|
|
883
1010
|
requested_spend_cents: {
|
|
884
1011
|
type: "integer",
|
|
885
1012
|
description: "Optional sandbox spend amount override for the evidence record.",
|
|
@@ -889,13 +1016,19 @@ export class PaybondMCPServer {
|
|
|
889
1016
|
}, ["intent_id"]),
|
|
890
1017
|
call: async (args) => this.runtime.submitSandboxGuardrailEvidence({
|
|
891
1018
|
intentId: uuidArg(args.intent_id, "intent_id"),
|
|
892
|
-
payload: args.payload === undefined
|
|
893
|
-
|
|
1019
|
+
payload: args.payload === undefined
|
|
1020
|
+
? undefined
|
|
1021
|
+
: ensureObject(args.payload, "payload"),
|
|
1022
|
+
artifacts: args.artifacts === undefined
|
|
1023
|
+
? undefined
|
|
1024
|
+
: stringArrayArg(args.artifacts, "artifacts"),
|
|
894
1025
|
operation: optionalString(args.operation),
|
|
895
1026
|
requestedSpendCents: args.requested_spend_cents === undefined
|
|
896
1027
|
? undefined
|
|
897
1028
|
: intArg(args.requested_spend_cents, "requested_spend_cents"),
|
|
898
|
-
metadata: args.metadata === undefined
|
|
1029
|
+
metadata: args.metadata === undefined
|
|
1030
|
+
? undefined
|
|
1031
|
+
: ensureObject(args.metadata, "metadata"),
|
|
899
1032
|
idempotencyKey: optionalString(args.idempotency_key),
|
|
900
1033
|
}),
|
|
901
1034
|
},
|
|
@@ -919,7 +1052,10 @@ export class PaybondMCPServer {
|
|
|
919
1052
|
name: "paybond_get_intent",
|
|
920
1053
|
description: "Fetch one tenant-scoped Harbor intent detail through the gateway operator view.",
|
|
921
1054
|
inputSchema: objectSchema({
|
|
922
|
-
intent_id: {
|
|
1055
|
+
intent_id: {
|
|
1056
|
+
type: "string",
|
|
1057
|
+
description: "Canonical Harbor intent UUID.",
|
|
1058
|
+
},
|
|
923
1059
|
}, ["intent_id"]),
|
|
924
1060
|
call: async (args) => this.runtime.getIntent(uuidArg(args.intent_id, "intent_id")),
|
|
925
1061
|
},
|
|
@@ -1160,6 +1296,7 @@ export function settingsFromEnv(env = process.env) {
|
|
|
1160
1296
|
maxRetries: optionalEnv(env.PAYBOND_MCP_MAX_RETRIES)
|
|
1161
1297
|
? intArg(optionalEnv(env.PAYBOND_MCP_MAX_RETRIES), "PAYBOND_MCP_MAX_RETRIES")
|
|
1162
1298
|
: 3,
|
|
1299
|
+
toolPolicy: mergeMcpToolPolicy(parseMcpToolPolicy(optionalEnv(env[MCP_TOOL_POLICY_ENV])), parseMcpToolAllowlist(optionalEnv(env[MCP_TOOL_ALLOWLIST_ENV]))),
|
|
1163
1300
|
};
|
|
1164
1301
|
}
|
|
1165
1302
|
export function main(argv = process.argv.slice(2)) {
|
|
@@ -1314,18 +1451,6 @@ function toToolResult(value) {
|
|
|
1314
1451
|
structuredContent: value,
|
|
1315
1452
|
};
|
|
1316
1453
|
}
|
|
1317
|
-
function jsonObjectFromValue(value) {
|
|
1318
|
-
if (value === null) {
|
|
1319
|
-
return {};
|
|
1320
|
-
}
|
|
1321
|
-
if (Array.isArray(value)) {
|
|
1322
|
-
return { items: value };
|
|
1323
|
-
}
|
|
1324
|
-
if (typeof value !== "object") {
|
|
1325
|
-
return { value };
|
|
1326
|
-
}
|
|
1327
|
-
return JSON.parse(JSON.stringify(value));
|
|
1328
|
-
}
|
|
1329
1454
|
function responseError(id, code, message) {
|
|
1330
1455
|
return {
|
|
1331
1456
|
jsonrpc: "2.0",
|
|
@@ -1365,19 +1490,15 @@ function formatError(err) {
|
|
|
1365
1490
|
return String(err);
|
|
1366
1491
|
}
|
|
1367
1492
|
function normalizeFileURL(url) {
|
|
1368
|
-
return url.startsWith("file:///var/")
|
|
1493
|
+
return url.startsWith("file:///var/")
|
|
1494
|
+
? url.replace("file:///var/", "file:///private/var/")
|
|
1495
|
+
: url;
|
|
1369
1496
|
}
|
|
1370
1497
|
async function invokedFromCLI() {
|
|
1371
1498
|
const scriptPath = process.argv[1];
|
|
1372
1499
|
if (!scriptPath) {
|
|
1373
1500
|
return false;
|
|
1374
1501
|
}
|
|
1375
|
-
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
1376
|
-
const fs = (await import("node:fs/promises"));
|
|
1377
|
-
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
1378
|
-
const path = (await import("node:path"));
|
|
1379
|
-
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
1380
|
-
const url = (await import("node:url"));
|
|
1381
1502
|
async function realFileURL(filePath) {
|
|
1382
1503
|
let resolved = path.resolve(filePath);
|
|
1383
1504
|
try {
|
|
@@ -1387,14 +1508,21 @@ async function invokedFromCLI() {
|
|
|
1387
1508
|
// If realpath fails, compare the absolute path. This keeps direct execution
|
|
1388
1509
|
// working even when the script path disappears during process startup.
|
|
1389
1510
|
}
|
|
1390
|
-
return normalizeFileURL(
|
|
1511
|
+
return normalizeFileURL(pathToFileURL(resolved).href);
|
|
1391
1512
|
}
|
|
1392
|
-
return (await realFileURL(scriptPath)) ===
|
|
1513
|
+
return ((await realFileURL(scriptPath)) ===
|
|
1514
|
+
(await realFileURL(fileURLToPath(import.meta.url))));
|
|
1393
1515
|
}
|
|
1394
1516
|
invokedFromCLI().then((invoked) => {
|
|
1395
|
-
if (invoked
|
|
1396
|
-
|
|
1517
|
+
if (!invoked) {
|
|
1518
|
+
return;
|
|
1397
1519
|
}
|
|
1520
|
+
runCli(["mcp", "serve", ...process.argv.slice(2)]).then((code) => {
|
|
1521
|
+
process.exitCode = code;
|
|
1522
|
+
}, (err) => {
|
|
1523
|
+
process.stderr.write(`${formatError(err)}\n`);
|
|
1524
|
+
process.exitCode = 1;
|
|
1525
|
+
});
|
|
1398
1526
|
}, (err) => {
|
|
1399
1527
|
process.stderr.write(`${formatError(err)}\n`);
|
|
1400
1528
|
process.exitCode = 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paybond/kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"mcpName": "io.github.nonameuserd/paybond",
|
|
5
5
|
"description": "Paybond Kit for TypeScript: agent spend governance for paid tool calls with spend authorization, evidence receipts, refunds, disputes, hosted Gateway sessions, and settlement.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
10
10
|
"bin": {
|
|
11
|
-
"paybond": "dist/
|
|
11
|
+
"paybond": "dist/cli.js",
|
|
12
|
+
"paybond-kit-login": "dist/login.js",
|
|
12
13
|
"paybond-init": "dist/init.js",
|
|
13
14
|
"paybond-mcp-server": "dist/mcp-server.js"
|
|
14
15
|
},
|
|
@@ -77,6 +78,7 @@
|
|
|
77
78
|
"scripts": {
|
|
78
79
|
"clean": "node ./scripts/clean-dist.mjs",
|
|
79
80
|
"build": "npm run clean && tsc -p tsconfig.json",
|
|
81
|
+
"generate:cli-contract": "node ../cli-parity/generate.mjs",
|
|
80
82
|
"test": "vitest run",
|
|
81
83
|
"pack:dry-run": "npm pack --dry-run",
|
|
82
84
|
"verify:release": "node ./scripts/verify-release.mjs",
|
|
@@ -88,6 +90,7 @@
|
|
|
88
90
|
"uuid": "^14.0.0"
|
|
89
91
|
},
|
|
90
92
|
"devDependencies": {
|
|
93
|
+
"@types/node": "^22.10.0",
|
|
91
94
|
"typescript": "^5.7.2",
|
|
92
95
|
"vitest": "^4.1.8"
|
|
93
96
|
}
|