@paybond/kit 0.11.10 → 0.12.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 +2 -2
- package/completion-presets/catalog.json +374 -3
- package/completion-presets/catalog.sha256 +1 -1
- package/dist/agent/facade.js +13 -0
- package/dist/agent/guarded-agent.d.ts +1 -1
- package/dist/agent/guarded-agent.js +19 -0
- package/dist/agent/index.d.ts +2 -1
- package/dist/agent/index.js +1 -0
- package/dist/agent/instrument.d.ts +6 -0
- package/dist/agent/instrument.js +6 -0
- package/dist/agent/interceptor.d.ts +9 -0
- package/dist/agent/interceptor.js +177 -1
- package/dist/agent/receipt-client.d.ts +49 -0
- package/dist/agent/receipt-client.js +45 -0
- package/dist/agent/registry.js +1 -0
- package/dist/agent/run.d.ts +2 -0
- package/dist/agent/run.js +52 -0
- package/dist/agent/types.d.ts +70 -0
- package/dist/agent-receipt-external-attestations.d.ts +29 -0
- package/dist/agent-receipt-external-attestations.js +124 -0
- package/dist/agent-receipt.d.ts +134 -0
- package/dist/agent-receipt.js +580 -0
- package/dist/agent-recognition.d.ts +25 -0
- package/dist/agent-recognition.js +36 -0
- package/dist/audit/exports.d.ts +72 -0
- package/dist/audit/exports.js +185 -0
- package/dist/audit/index.d.ts +3 -0
- package/dist/audit/index.js +3 -0
- package/dist/audit/verify.d.ts +8 -0
- package/dist/audit/verify.js +113 -0
- package/dist/audit/wire.d.ts +54 -0
- package/dist/audit/wire.js +80 -0
- package/dist/cli/agent/demo-loaders.d.ts +2 -0
- package/dist/cli/agent/demo-loaders.js +24 -0
- package/dist/cli/agent/production-evidence.d.ts +11 -0
- package/dist/cli/agent/production-evidence.js +17 -0
- package/dist/cli/audit-export.d.ts +2 -7
- package/dist/cli/audit-export.js +2 -120
- package/dist/cli/command-spec.js +43 -10
- package/dist/cli/commands/agent.d.ts +3 -0
- package/dist/cli/commands/agent.js +143 -1
- package/dist/cli/commands/discovery.js +39 -36
- package/dist/cli/commands/workflows.js +116 -18
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +12 -8
- package/dist/cli/intents-harbor-mutation.d.ts +18 -0
- package/dist/cli/intents-harbor-mutation.js +33 -0
- package/dist/cli/paybond.d.ts +9 -0
- package/dist/cli/paybond.js +23 -0
- package/dist/cli/redact.js +3 -0
- package/dist/cloudflare-agents/config.d.ts +24 -0
- package/dist/cloudflare-agents/config.js +23 -0
- package/dist/cloudflare-agents/index.d.ts +3 -0
- package/dist/cloudflare-agents/index.js +3 -0
- package/dist/cloudflare-agents/peer.d.ts +9 -0
- package/dist/cloudflare-agents/peer.js +20 -0
- package/dist/cloudflare-agents/sandbox-demo.d.ts +36 -0
- package/dist/cloudflare-agents/sandbox-demo.js +89 -0
- package/dist/completion-catalog-digest.d.ts +1 -1
- package/dist/completion-catalog-digest.js +1 -1
- package/dist/completion-init.js +8 -3
- package/dist/dev/offline-gateway.d.ts +2 -1
- package/dist/dev/offline-gateway.js +34 -3
- package/dist/dev/x402-fund-mock.d.ts +28 -0
- package/dist/dev/x402-fund-mock.js +124 -0
- package/dist/index.d.ts +125 -9
- package/dist/index.js +264 -17
- package/dist/init.js +113 -2
- package/dist/mastra/config.d.ts +30 -0
- package/dist/mastra/config.js +58 -0
- package/dist/mastra/index.d.ts +2 -0
- package/dist/mastra/index.js +2 -0
- package/dist/mastra/peer.d.ts +11 -0
- package/dist/mastra/peer.js +24 -0
- package/dist/mastra/sandbox-demo.d.ts +36 -0
- package/dist/mastra/sandbox-demo.js +87 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/sandbox-demo.d.ts +38 -0
- package/dist/mcp/sandbox-demo.js +112 -0
- package/dist/mcp-receipt-resource.d.ts +10 -0
- package/dist/mcp-receipt-resource.js +32 -0
- package/dist/mcp-server.d.ts +6 -0
- package/dist/mcp-server.js +124 -1
- package/dist/mpp-commercial.d.ts +19 -0
- package/dist/mpp-commercial.js +34 -0
- package/dist/mpp-funding.d.ts +71 -0
- package/dist/mpp-funding.js +192 -0
- package/dist/payment-transport.d.ts +30 -0
- package/dist/payment-transport.js +56 -0
- package/dist/policy/init.js +2 -0
- package/dist/policy/intent-spec.js +2 -0
- package/dist/principal-intent.d.ts +1 -1
- package/dist/principal-intent.js +4 -1
- package/dist/project-init.js +8 -0
- package/dist/template-init.d.ts +2 -2
- package/dist/template-init.js +6 -2
- package/dist/x402-funding.d.ts +52 -0
- package/dist/x402-funding.js +124 -0
- package/package.json +20 -2
- package/templates/manifest.json +28 -9
- package/templates/openai-shopping-agent/package-lock.json +16 -8
- package/templates/openai-shopping-agent/package.json +1 -1
- package/templates/paybond-aws-operator/package-lock.json +13 -5
- package/templates/paybond-aws-operator/package.json +1 -1
- package/templates/paybond-claude-agents-demo/package-lock.json +16 -8
- package/templates/paybond-claude-agents-demo/package.json +1 -1
- package/templates/paybond-invoice-agent/requirements.txt +1 -1
- package/templates/paybond-mastra-travel-agent/.env.example +3 -0
- package/templates/paybond-mastra-travel-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-mastra-travel-agent/LICENSE +201 -0
- package/templates/paybond-mastra-travel-agent/README.md +29 -0
- package/templates/paybond-mastra-travel-agent/package-lock.json +3377 -0
- package/templates/paybond-mastra-travel-agent/package.json +22 -0
- package/templates/paybond-mastra-travel-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-mastra-travel-agent/src/index.ts +22 -0
- package/templates/paybond-mastra-travel-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-mastra-travel-agent/tsconfig.json +13 -0
- package/templates/paybond-mcp-coding-agent/package-lock.json +13 -5
- package/templates/paybond-mcp-coding-agent/package.json +1 -1
- package/templates/paybond-openai-agents-demo/package-lock.json +16 -8
- package/templates/paybond-openai-agents-demo/package.json +1 -1
- package/templates/paybond-procurement-agent/package-lock.json +13 -5
- package/templates/paybond-procurement-agent/package.json +1 -1
- package/templates/paybond-travel-agent/package-lock.json +16 -8
- package/templates/paybond-travel-agent/package.json +1 -1
- package/templates/paybond-vercel-shopping-agent/package-lock.json +13 -5
- package/templates/paybond-vercel-shopping-agent/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
function resolveMastraToolCallId(context, fallback) {
|
|
2
|
+
if (typeof context === "object" && context !== null) {
|
|
3
|
+
const record = context;
|
|
4
|
+
const agent = record.agent;
|
|
5
|
+
if (typeof agent === "object" && agent !== null) {
|
|
6
|
+
const toolCallId = agent.toolCallId;
|
|
7
|
+
if (typeof toolCallId === "string" && toolCallId.trim()) {
|
|
8
|
+
return toolCallId.trim();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const direct = record.toolCallId;
|
|
12
|
+
if (typeof direct === "string" && direct.trim()) {
|
|
13
|
+
return direct.trim();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return fallback;
|
|
17
|
+
}
|
|
18
|
+
function wrapMastraTool(run, tool) {
|
|
19
|
+
const toolName = tool.id.trim();
|
|
20
|
+
if (typeof tool.execute !== "function" || !run.registry.isSideEffecting(toolName)) {
|
|
21
|
+
return tool;
|
|
22
|
+
}
|
|
23
|
+
const originalExecute = tool.execute.bind(tool);
|
|
24
|
+
return {
|
|
25
|
+
...tool,
|
|
26
|
+
execute: async (inputData, context) => {
|
|
27
|
+
const toolCallId = resolveMastraToolCallId(context, globalThis.crypto.randomUUID());
|
|
28
|
+
const wrapped = await run.interceptor.wrapExecute({
|
|
29
|
+
toolName,
|
|
30
|
+
toolCallId,
|
|
31
|
+
arguments: inputData,
|
|
32
|
+
approvalToken: run.getApprovalToken(toolCallId),
|
|
33
|
+
execute: () => originalExecute(inputData, context),
|
|
34
|
+
});
|
|
35
|
+
return wrapped.toolResult;
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Wrap side-effecting Mastra tools with Paybond `wrapExecute` so Harbor verify,
|
|
41
|
+
* spend finalize, and auto-evidence run after successful execution.
|
|
42
|
+
*
|
|
43
|
+
* Read-only tools pass through unchanged.
|
|
44
|
+
*/
|
|
45
|
+
export function paybondMastraWrapTools(run, tools) {
|
|
46
|
+
return tools.map((tool) => wrapMastraTool(run, tool));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Framework runner helper for Mastra `createTool({ execute })` definitions.
|
|
50
|
+
*
|
|
51
|
+
* Preserves schema, id, and description; replaces `execute` only on
|
|
52
|
+
* side-effecting registry tools.
|
|
53
|
+
*/
|
|
54
|
+
export function createPaybondMastraConfig(run, tools) {
|
|
55
|
+
return {
|
|
56
|
+
tools: paybondMastraWrapTools(run, tools),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type MastraToolsModule = typeof import("@mastra/core/tools");
|
|
2
|
+
/**
|
|
3
|
+
* Lazily resolve the optional `@mastra/core` peer dependency.
|
|
4
|
+
*
|
|
5
|
+
* Importing `@paybond/kit/mastra` must not require Mastra installed — the peer
|
|
6
|
+
* is only needed when adapter functions or the sandbox demo actually run.
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadMastraTools(): MastraToolsModule;
|
|
9
|
+
/** Re-export {@link loadMastraTools} as `createTool` for sandbox demos. */
|
|
10
|
+
export declare function loadMastraCreateTool(): MastraToolsModule["createTool"];
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
let cachedMastraTools;
|
|
3
|
+
/**
|
|
4
|
+
* Lazily resolve the optional `@mastra/core` peer dependency.
|
|
5
|
+
*
|
|
6
|
+
* Importing `@paybond/kit/mastra` must not require Mastra installed — the peer
|
|
7
|
+
* is only needed when adapter functions or the sandbox demo actually run.
|
|
8
|
+
*/
|
|
9
|
+
export function loadMastraTools() {
|
|
10
|
+
if (cachedMastraTools === undefined) {
|
|
11
|
+
try {
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
cachedMastraTools = require("@mastra/core/tools");
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
throw new Error('The Mastra integration requires the optional peer dependency "@mastra/core"; install it with: npm install @mastra/core', { cause: err });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return cachedMastraTools;
|
|
20
|
+
}
|
|
21
|
+
/** Re-export {@link loadMastraTools} as `createTool` for sandbox demos. */
|
|
22
|
+
export function loadMastraCreateTool() {
|
|
23
|
+
return loadMastraTools().createTool;
|
|
24
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Paybond } from "../index.js";
|
|
2
|
+
export type RunMastraSandboxDemoInput = {
|
|
3
|
+
paybond: Paybond;
|
|
4
|
+
operation?: string;
|
|
5
|
+
requestedSpendCents?: number;
|
|
6
|
+
evidencePreset?: string;
|
|
7
|
+
toolCallId?: string;
|
|
8
|
+
};
|
|
9
|
+
export type RunMastraSandboxDemoResult = {
|
|
10
|
+
bind: {
|
|
11
|
+
run_id: string;
|
|
12
|
+
tenant_id: string;
|
|
13
|
+
intent_id: string;
|
|
14
|
+
capability_token: string;
|
|
15
|
+
operation: string;
|
|
16
|
+
sandbox_lifecycle_status?: string;
|
|
17
|
+
};
|
|
18
|
+
authorization: {
|
|
19
|
+
allow: boolean;
|
|
20
|
+
audit_id?: string;
|
|
21
|
+
decision_id?: string;
|
|
22
|
+
};
|
|
23
|
+
execute: {
|
|
24
|
+
tool_result?: unknown;
|
|
25
|
+
evidence?: {
|
|
26
|
+
submitted: boolean;
|
|
27
|
+
sandbox_lifecycle_status?: string;
|
|
28
|
+
predicate_passed?: boolean | null;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* No-LLM Mastra sandbox demo: wrapped `createTool` execute + auto-evidence.
|
|
34
|
+
* Requires optional peer `@mastra/core`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runMastraSandboxDemo(input: RunMastraSandboxDemoInput): Promise<RunMastraSandboxDemoResult>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createPaybondToolRegistry } from "../agent/registry.js";
|
|
3
|
+
import { createPaybondMastraConfig } from "./config.js";
|
|
4
|
+
import { loadMastraCreateTool } from "./peer.js";
|
|
5
|
+
async function executePaidTool(args) {
|
|
6
|
+
return { status: "completed", cost_cents: args.estimatedPriceCents };
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* No-LLM Mastra sandbox demo: wrapped `createTool` execute + auto-evidence.
|
|
10
|
+
* Requires optional peer `@mastra/core`.
|
|
11
|
+
*/
|
|
12
|
+
export async function runMastraSandboxDemo(input) {
|
|
13
|
+
const operation = (input.operation ?? "paid-tool").trim();
|
|
14
|
+
const requestedSpendCents = input.requestedSpendCents ?? 100;
|
|
15
|
+
const evidencePreset = (input.evidencePreset ?? "cost_and_completion").trim();
|
|
16
|
+
const toolCallId = (input.toolCallId ?? "mastra-demo-1").trim();
|
|
17
|
+
const registry = createPaybondToolRegistry({
|
|
18
|
+
defaultDeny: true,
|
|
19
|
+
sideEffecting: {
|
|
20
|
+
[operation]: {
|
|
21
|
+
operation,
|
|
22
|
+
evidencePreset,
|
|
23
|
+
spendCents: (args) => typeof args === "object" &&
|
|
24
|
+
args !== null &&
|
|
25
|
+
"estimatedPriceCents" in args &&
|
|
26
|
+
typeof args.estimatedPriceCents === "number"
|
|
27
|
+
? args.estimatedPriceCents
|
|
28
|
+
: requestedSpendCents,
|
|
29
|
+
evidenceMapper: (result) => {
|
|
30
|
+
const payload = result;
|
|
31
|
+
return {
|
|
32
|
+
status: payload.status,
|
|
33
|
+
cost_cents: payload.cost_cents,
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const run = await input.paybond.agentRun.bind({
|
|
40
|
+
bootstrap: {
|
|
41
|
+
kind: "sandbox",
|
|
42
|
+
operation,
|
|
43
|
+
requestedSpendCents,
|
|
44
|
+
completionPreset: evidencePreset,
|
|
45
|
+
},
|
|
46
|
+
registry,
|
|
47
|
+
});
|
|
48
|
+
const createTool = loadMastraCreateTool();
|
|
49
|
+
const rawTools = [
|
|
50
|
+
createTool({
|
|
51
|
+
id: operation,
|
|
52
|
+
description: `Paid operation ${operation}`,
|
|
53
|
+
inputSchema: z.object({
|
|
54
|
+
estimatedPriceCents: z.number().int().nonnegative(),
|
|
55
|
+
}),
|
|
56
|
+
execute: async (inputData) => executePaidTool(inputData),
|
|
57
|
+
}),
|
|
58
|
+
];
|
|
59
|
+
const { tools } = createPaybondMastraConfig(run, rawTools);
|
|
60
|
+
const guardedTool = tools[0];
|
|
61
|
+
if (!guardedTool?.execute) {
|
|
62
|
+
throw new Error("Mastra sandbox demo missing guarded tool execute handler");
|
|
63
|
+
}
|
|
64
|
+
const toolResult = await guardedTool.execute({ estimatedPriceCents: requestedSpendCents }, { toolCallId });
|
|
65
|
+
const sandboxStatus = run.binding.sandbox?.sandboxLifecycleStatus;
|
|
66
|
+
return {
|
|
67
|
+
bind: {
|
|
68
|
+
run_id: run.runId,
|
|
69
|
+
tenant_id: run.tenantId,
|
|
70
|
+
intent_id: run.intentId,
|
|
71
|
+
capability_token: run.capabilityToken,
|
|
72
|
+
operation,
|
|
73
|
+
sandbox_lifecycle_status: sandboxStatus,
|
|
74
|
+
},
|
|
75
|
+
authorization: {
|
|
76
|
+
allow: true,
|
|
77
|
+
},
|
|
78
|
+
execute: {
|
|
79
|
+
tool_result: toolResult,
|
|
80
|
+
evidence: {
|
|
81
|
+
submitted: true,
|
|
82
|
+
sandbox_lifecycle_status: sandboxStatus,
|
|
83
|
+
predicate_passed: true,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
package/dist/mcp/index.d.ts
CHANGED
package/dist/mcp/index.js
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Paybond } from "../index.js";
|
|
2
|
+
export type RunMcpSandboxDemoInput = {
|
|
3
|
+
paybond: Paybond;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
gatewayBaseUrl: string;
|
|
6
|
+
operation?: string;
|
|
7
|
+
requestedSpendCents?: number;
|
|
8
|
+
evidencePreset?: string;
|
|
9
|
+
};
|
|
10
|
+
export type RunMcpSandboxDemoResult = {
|
|
11
|
+
bind: {
|
|
12
|
+
run_id: string;
|
|
13
|
+
tenant_id: string;
|
|
14
|
+
intent_id: string;
|
|
15
|
+
capability_token: string;
|
|
16
|
+
operation: string;
|
|
17
|
+
sandbox_lifecycle_status?: string;
|
|
18
|
+
};
|
|
19
|
+
authorization: {
|
|
20
|
+
allow: boolean;
|
|
21
|
+
audit_id?: string;
|
|
22
|
+
decision_id?: string;
|
|
23
|
+
};
|
|
24
|
+
tool_result: {
|
|
25
|
+
status: string;
|
|
26
|
+
cost_cents: number;
|
|
27
|
+
};
|
|
28
|
+
evidence: {
|
|
29
|
+
submitted: boolean;
|
|
30
|
+
sandbox_lifecycle_status?: string;
|
|
31
|
+
predicate_passed?: boolean | null;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* No-LLM MCP sandbox demo: agent-run bind + in-process `PaybondMCPServer.callTool`
|
|
36
|
+
* for authorize and evidence (no stdio subprocess).
|
|
37
|
+
*/
|
|
38
|
+
export declare function runMcpSandboxDemo(input: RunMcpSandboxDemoInput): Promise<RunMcpSandboxDemoResult>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createPaybondToolRegistry } from "../agent/registry.js";
|
|
2
|
+
import { PaybondMCPServer } from "../mcp-server.js";
|
|
3
|
+
function readStructuredContent(result) {
|
|
4
|
+
const structured = result.structuredContent;
|
|
5
|
+
return typeof structured === "object" && structured !== null
|
|
6
|
+
? structured
|
|
7
|
+
: undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* No-LLM MCP sandbox demo: agent-run bind + in-process `PaybondMCPServer.callTool`
|
|
11
|
+
* for authorize and evidence (no stdio subprocess).
|
|
12
|
+
*/
|
|
13
|
+
export async function runMcpSandboxDemo(input) {
|
|
14
|
+
const operation = (input.operation ?? "paid-tool").trim();
|
|
15
|
+
const requestedSpendCents = input.requestedSpendCents ?? 100;
|
|
16
|
+
const evidencePreset = (input.evidencePreset ?? "cost_and_completion").trim();
|
|
17
|
+
const registry = createPaybondToolRegistry({
|
|
18
|
+
defaultDeny: true,
|
|
19
|
+
sideEffecting: {
|
|
20
|
+
[operation]: {
|
|
21
|
+
operation,
|
|
22
|
+
evidencePreset,
|
|
23
|
+
spendCents: requestedSpendCents,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
const run = await input.paybond.agentRun.bind({
|
|
28
|
+
bootstrap: {
|
|
29
|
+
kind: "sandbox",
|
|
30
|
+
operation,
|
|
31
|
+
requestedSpendCents,
|
|
32
|
+
completionPreset: evidencePreset,
|
|
33
|
+
},
|
|
34
|
+
registry,
|
|
35
|
+
});
|
|
36
|
+
const server = new PaybondMCPServer({
|
|
37
|
+
gatewayBaseUrl: input.gatewayBaseUrl,
|
|
38
|
+
apiKey: input.apiKey,
|
|
39
|
+
});
|
|
40
|
+
const authorizeResult = await server.callTool("paybond_authorize_agent_spend", {
|
|
41
|
+
intent_id: run.intentId,
|
|
42
|
+
token: run.capabilityToken,
|
|
43
|
+
operation,
|
|
44
|
+
requested_spend_cents: requestedSpendCents,
|
|
45
|
+
});
|
|
46
|
+
if (authorizeResult.isError) {
|
|
47
|
+
const message = authorizeResult.content[0]?.type === "text"
|
|
48
|
+
? authorizeResult.content[0].text
|
|
49
|
+
: "paybond_authorize_agent_spend failed";
|
|
50
|
+
throw new Error(message);
|
|
51
|
+
}
|
|
52
|
+
const authorizationBody = readStructuredContent(authorizeResult) ?? {};
|
|
53
|
+
const toolResult = {
|
|
54
|
+
status: "completed",
|
|
55
|
+
cost_cents: requestedSpendCents,
|
|
56
|
+
};
|
|
57
|
+
const validationResult = await server.callTool("paybond_validate_completion_evidence", {
|
|
58
|
+
preset_id: evidencePreset,
|
|
59
|
+
vendor_payload: toolResult,
|
|
60
|
+
canonical_payload: toolResult,
|
|
61
|
+
});
|
|
62
|
+
if (validationResult.isError) {
|
|
63
|
+
const message = validationResult.content[0]?.type === "text"
|
|
64
|
+
? validationResult.content[0].text
|
|
65
|
+
: "paybond_validate_completion_evidence failed";
|
|
66
|
+
throw new Error(message);
|
|
67
|
+
}
|
|
68
|
+
const validationBody = readStructuredContent(validationResult) ?? {};
|
|
69
|
+
if (validationBody.ok !== true) {
|
|
70
|
+
throw new Error("paybond_validate_completion_evidence did not pass");
|
|
71
|
+
}
|
|
72
|
+
const evidenceResult = await server.callTool("paybond_submit_sandbox_guardrail_evidence", {
|
|
73
|
+
intent_id: run.intentId,
|
|
74
|
+
payload: toolResult,
|
|
75
|
+
operation,
|
|
76
|
+
requested_spend_cents: requestedSpendCents,
|
|
77
|
+
completion_preset_id: evidencePreset,
|
|
78
|
+
});
|
|
79
|
+
if (evidenceResult.isError) {
|
|
80
|
+
const message = evidenceResult.content[0]?.type === "text"
|
|
81
|
+
? evidenceResult.content[0].text
|
|
82
|
+
: "paybond_submit_sandbox_guardrail_evidence failed";
|
|
83
|
+
throw new Error(message);
|
|
84
|
+
}
|
|
85
|
+
const evidenceBody = readStructuredContent(evidenceResult) ?? {};
|
|
86
|
+
const sandboxStatus = typeof evidenceBody.sandbox_lifecycle_status === "string"
|
|
87
|
+
? evidenceBody.sandbox_lifecycle_status
|
|
88
|
+
: run.binding.sandbox?.sandboxLifecycleStatus;
|
|
89
|
+
return {
|
|
90
|
+
bind: {
|
|
91
|
+
run_id: run.runId,
|
|
92
|
+
tenant_id: run.tenantId,
|
|
93
|
+
intent_id: run.intentId,
|
|
94
|
+
capability_token: run.capabilityToken,
|
|
95
|
+
operation,
|
|
96
|
+
sandbox_lifecycle_status: sandboxStatus,
|
|
97
|
+
},
|
|
98
|
+
authorization: {
|
|
99
|
+
allow: authorizationBody.allow === true,
|
|
100
|
+
audit_id: typeof authorizationBody.audit_id === "string" ? authorizationBody.audit_id : undefined,
|
|
101
|
+
decision_id: typeof authorizationBody.decision_id === "string"
|
|
102
|
+
? authorizationBody.decision_id
|
|
103
|
+
: undefined,
|
|
104
|
+
},
|
|
105
|
+
tool_result: toolResult,
|
|
106
|
+
evidence: {
|
|
107
|
+
submitted: true,
|
|
108
|
+
sandbox_lifecycle_status: sandboxStatus,
|
|
109
|
+
predicate_passed: typeof evidenceBody.predicate_passed === "boolean" ? evidenceBody.predicate_passed : true,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** MCP resource URI helpers for tenant-bound agent receipt handoff. */
|
|
2
|
+
export declare const MCP_AGENT_RECEIPT_RESOURCE_SCHEME = "paybond";
|
|
3
|
+
export declare const MCP_AGENT_RECEIPT_RESOURCE_HOST = "receipt";
|
|
4
|
+
export declare const MCP_AGENT_RECEIPT_RESOURCE_URI_TEMPLATE = "paybond://receipt/{receipt_id}";
|
|
5
|
+
export declare const MCP_AGENT_RECEIPT_RESOURCE_MIME_TYPE = "application/json";
|
|
6
|
+
/** Parse `paybond://receipt/{receipt_id}` into a canonical receipt id. */
|
|
7
|
+
export declare function parseAgentReceiptResourceUri(uri: string): string;
|
|
8
|
+
/** Build the MCP resource URI for one signed agent receipt id. */
|
|
9
|
+
export declare function agentReceiptResourceUri(receiptId: string): string;
|
|
10
|
+
export declare function agentReceiptResourceTemplateDefinition(): Record<string, unknown>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** MCP resource URI helpers for tenant-bound agent receipt handoff. */
|
|
2
|
+
export const MCP_AGENT_RECEIPT_RESOURCE_SCHEME = "paybond";
|
|
3
|
+
export const MCP_AGENT_RECEIPT_RESOURCE_HOST = "receipt";
|
|
4
|
+
export const MCP_AGENT_RECEIPT_RESOURCE_URI_TEMPLATE = "paybond://receipt/{receipt_id}";
|
|
5
|
+
export const MCP_AGENT_RECEIPT_RESOURCE_MIME_TYPE = "application/json";
|
|
6
|
+
const RECEIPT_URI_RE = /^paybond:\/\/receipt\/([0-9a-f]{64}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
|
|
7
|
+
/** Parse `paybond://receipt/{receipt_id}` into a canonical receipt id. */
|
|
8
|
+
export function parseAgentReceiptResourceUri(uri) {
|
|
9
|
+
const trimmed = uri.trim();
|
|
10
|
+
const match = RECEIPT_URI_RE.exec(trimmed);
|
|
11
|
+
if (!match) {
|
|
12
|
+
throw new Error(`unsupported resource URI ${trimmed}; expected ${MCP_AGENT_RECEIPT_RESOURCE_URI_TEMPLATE}`);
|
|
13
|
+
}
|
|
14
|
+
return match[1].toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
/** Build the MCP resource URI for one signed agent receipt id. */
|
|
17
|
+
export function agentReceiptResourceUri(receiptId) {
|
|
18
|
+
const normalized = receiptId.trim().toLowerCase();
|
|
19
|
+
if (!RECEIPT_URI_RE.test(`paybond://receipt/${normalized}`)) {
|
|
20
|
+
throw new Error("receipt_id must be a lowercase SHA-256 hex digest or canonical UUID");
|
|
21
|
+
}
|
|
22
|
+
return `paybond://receipt/${normalized}`;
|
|
23
|
+
}
|
|
24
|
+
export function agentReceiptResourceTemplateDefinition() {
|
|
25
|
+
return {
|
|
26
|
+
uriTemplate: MCP_AGENT_RECEIPT_RESOURCE_URI_TEMPLATE,
|
|
27
|
+
name: "paybond_agent_receipt",
|
|
28
|
+
title: "Paybond Agent Receipt",
|
|
29
|
+
description: "Signed paybond.agent_receipt_v1 JSON fetched tenant-bound from Gateway GET /protocol/v2/agent-receipts/{receipt_id}.",
|
|
30
|
+
mimeType: MCP_AGENT_RECEIPT_RESOURCE_MIME_TYPE,
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -44,6 +44,12 @@ export declare class PaybondMCPServer {
|
|
|
44
44
|
private readonly toolPolicy;
|
|
45
45
|
private initialized;
|
|
46
46
|
constructor(settings: PaybondMCPSettings);
|
|
47
|
+
listResourceTemplates(): Array<Record<string, unknown>>;
|
|
48
|
+
readResource(uri: string): Promise<{
|
|
49
|
+
uri: string;
|
|
50
|
+
mimeType: string;
|
|
51
|
+
text: string;
|
|
52
|
+
}>;
|
|
47
53
|
listTools(): Array<Record<string, unknown>>;
|
|
48
54
|
callTool(name: string, args?: Record<string, unknown>): Promise<MCPCallToolResult>;
|
|
49
55
|
handleMessage(message: JSONRPCRequest): Promise<JSONRPCResponse | null>;
|
package/dist/mcp-server.js
CHANGED
|
@@ -11,9 +11,10 @@ import { MCP_TOOL_ALLOWLIST_ENV, MCP_TOOL_POLICY_ENV, mergeMcpToolPolicy, parseM
|
|
|
11
11
|
import { MCP_EVIDENCE_POLICY_ENV, McpEvidenceValidationGate, completionEvidenceValidationOk, extractHarborEvidenceValidationInput, extractSandboxGuardrailValidationInput, parseMcpEvidencePolicy, } from "./mcp-evidence-policy.js";
|
|
12
12
|
import { McpCapabilityTokenCache, mcpToolStoresCapabilityToken, parseMcpCapabilityTokenCacheConfig, } from "./mcp-capability-token-cache.js";
|
|
13
13
|
import { createMcpPolicyGatewayAdapter, McpPolicyReloadGate, parseMcpPolicyReloadConfig, } from "./mcp-policy-reload.js";
|
|
14
|
+
import { agentReceiptResourceTemplateDefinition, agentReceiptResourceUri, MCP_AGENT_RECEIPT_RESOURCE_MIME_TYPE, parseAgentReceiptResourceUri, } from "./mcp-receipt-resource.js";
|
|
14
15
|
import { DEFAULT_PAYBOND_GATEWAY_BASE_URL, GatewayFraudClient, GatewaySignalClient, } from "./index.js";
|
|
15
16
|
const SERVER_NAME = "Paybond MCP";
|
|
16
|
-
const SERVER_VERSION = "0.
|
|
17
|
+
const SERVER_VERSION = "0.12.0";
|
|
17
18
|
const MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
18
19
|
const DEFAULT_PRINCIPAL_PATH = "/v1/auth/principal";
|
|
19
20
|
const DEFAULT_RECOGNITION_VERIFIER_ID = "paybond-gateway";
|
|
@@ -160,6 +161,25 @@ const TOOL_SELECTION_METADATA = {
|
|
|
160
161
|
tenant_id: { type: "string" },
|
|
161
162
|
}),
|
|
162
163
|
},
|
|
164
|
+
paybond_list_audit_exports: {
|
|
165
|
+
title: "List Audit Exports",
|
|
166
|
+
annotations: readOnlyToolAnnotations("List Audit Exports"),
|
|
167
|
+
outputSchema: outputObjectSchema({
|
|
168
|
+
tenant_realm_id: { type: "string" },
|
|
169
|
+
jobs: {
|
|
170
|
+
type: "array",
|
|
171
|
+
items: { type: "object", additionalProperties: true },
|
|
172
|
+
},
|
|
173
|
+
next_cursor: { type: "string" },
|
|
174
|
+
}),
|
|
175
|
+
},
|
|
176
|
+
paybond_get_audit_export: {
|
|
177
|
+
title: "Get Audit Export",
|
|
178
|
+
annotations: readOnlyToolAnnotations("Get Audit Export"),
|
|
179
|
+
outputSchema: outputObjectSchema({
|
|
180
|
+
job: { type: "object", additionalProperties: true },
|
|
181
|
+
}),
|
|
182
|
+
},
|
|
163
183
|
paybond_get_reputation_receipt: {
|
|
164
184
|
title: "Get Reputation Receipt",
|
|
165
185
|
annotations: readOnlyToolAnnotations("Get Reputation Receipt"),
|
|
@@ -665,6 +685,20 @@ class PaybondMCPRuntime {
|
|
|
665
685
|
"x-tenant-id": await this.tenantId(),
|
|
666
686
|
});
|
|
667
687
|
}
|
|
688
|
+
async listAuditExports(init) {
|
|
689
|
+
const params = new URLSearchParams({
|
|
690
|
+
limit: String(Math.max(1, Math.min(intArg(init.limit ?? 50, "limit"), 200))),
|
|
691
|
+
});
|
|
692
|
+
if (init.cursor?.trim()) {
|
|
693
|
+
params.set("cursor", init.cursor.trim());
|
|
694
|
+
}
|
|
695
|
+
const body = await this.gateway.getJSON(`/v1/compliance/audit-exports?${params.toString()}`);
|
|
696
|
+
return body;
|
|
697
|
+
}
|
|
698
|
+
async getAuditExport(jobId, init) {
|
|
699
|
+
const query = init?.issueDownload ? "?issue_download=1" : "";
|
|
700
|
+
return this.gateway.getJSON(`/v1/compliance/audit-exports/${encodeURIComponent(jobId)}${query}`);
|
|
701
|
+
}
|
|
668
702
|
async getA2AAgentCard() {
|
|
669
703
|
return this.gateway.getJSON("/.well-known/agent-card.json");
|
|
670
704
|
}
|
|
@@ -813,6 +847,22 @@ class PaybondMCPRuntime {
|
|
|
813
847
|
"x-tenant-id": await this.tenantId(),
|
|
814
848
|
});
|
|
815
849
|
}
|
|
850
|
+
async getAgentReceiptV1(receiptId) {
|
|
851
|
+
const normalized = receiptId.trim().toLowerCase();
|
|
852
|
+
const body = await this.gateway.getJSON(`/protocol/v2/agent-receipts/${encodeURIComponent(normalized)}`, {
|
|
853
|
+
"x-tenant-id": await this.tenantId(),
|
|
854
|
+
});
|
|
855
|
+
const expectedTenant = await this.tenantId();
|
|
856
|
+
const echoedTenant = String(body.tenant_id ?? "").trim();
|
|
857
|
+
if (echoedTenant !== expectedTenant) {
|
|
858
|
+
throw new Error(`tenant mismatch: expected=${expectedTenant} gateway=${echoedTenant}`);
|
|
859
|
+
}
|
|
860
|
+
const echoedReceipt = String(body.receipt_id ?? "").trim().toLowerCase();
|
|
861
|
+
if (echoedReceipt !== normalized) {
|
|
862
|
+
throw new Error(`receipt mismatch: requested=${normalized} gateway=${echoedReceipt}`);
|
|
863
|
+
}
|
|
864
|
+
return body;
|
|
865
|
+
}
|
|
816
866
|
async createHarborIntent(init) {
|
|
817
867
|
return this.gateway.postJSON("/harbor/intents", init.body, gatewayMutationHeaders(await this.tenantId(), init.recognitionProof, optionalMutationHeaders(init.idempotencyKey)));
|
|
818
868
|
}
|
|
@@ -863,6 +913,18 @@ export class PaybondMCPServer {
|
|
|
863
913
|
this.runtime = new PaybondMCPRuntime(settings);
|
|
864
914
|
this.tools = this.buildTools(settings).filter((tool) => toolAllowedByPolicy(tool.name, tool.annotations, this.toolPolicy));
|
|
865
915
|
}
|
|
916
|
+
listResourceTemplates() {
|
|
917
|
+
return [agentReceiptResourceTemplateDefinition()];
|
|
918
|
+
}
|
|
919
|
+
async readResource(uri) {
|
|
920
|
+
const receiptId = parseAgentReceiptResourceUri(uri);
|
|
921
|
+
const receipt = await this.runtime.getAgentReceiptV1(receiptId);
|
|
922
|
+
return {
|
|
923
|
+
uri: agentReceiptResourceUri(receiptId),
|
|
924
|
+
mimeType: MCP_AGENT_RECEIPT_RESOURCE_MIME_TYPE,
|
|
925
|
+
text: JSON.stringify(receipt, null, 2),
|
|
926
|
+
};
|
|
927
|
+
}
|
|
866
928
|
listTools() {
|
|
867
929
|
return this.tools.map((tool) => ({
|
|
868
930
|
name: tool.name,
|
|
@@ -940,6 +1002,10 @@ export class PaybondMCPServer {
|
|
|
940
1002
|
tools: {
|
|
941
1003
|
listChanged: false,
|
|
942
1004
|
},
|
|
1005
|
+
resources: {
|
|
1006
|
+
subscribe: false,
|
|
1007
|
+
listChanged: false,
|
|
1008
|
+
},
|
|
943
1009
|
},
|
|
944
1010
|
serverInfo: {
|
|
945
1011
|
name: SERVER_NAME,
|
|
@@ -969,6 +1035,34 @@ export class PaybondMCPServer {
|
|
|
969
1035
|
tools: this.listTools(),
|
|
970
1036
|
},
|
|
971
1037
|
};
|
|
1038
|
+
case "resources/list":
|
|
1039
|
+
return {
|
|
1040
|
+
jsonrpc: "2.0",
|
|
1041
|
+
id: message.id,
|
|
1042
|
+
result: {
|
|
1043
|
+
resources: [],
|
|
1044
|
+
},
|
|
1045
|
+
};
|
|
1046
|
+
case "resources/templates/list":
|
|
1047
|
+
return {
|
|
1048
|
+
jsonrpc: "2.0",
|
|
1049
|
+
id: message.id,
|
|
1050
|
+
result: {
|
|
1051
|
+
resourceTemplates: this.listResourceTemplates(),
|
|
1052
|
+
},
|
|
1053
|
+
};
|
|
1054
|
+
case "resources/read": {
|
|
1055
|
+
const params = ensureObject(message.params, "resources/read params");
|
|
1056
|
+
const uri = stringArg(params.uri, "uri");
|
|
1057
|
+
const contents = await this.readResource(uri);
|
|
1058
|
+
return {
|
|
1059
|
+
jsonrpc: "2.0",
|
|
1060
|
+
id: message.id,
|
|
1061
|
+
result: {
|
|
1062
|
+
contents: [contents],
|
|
1063
|
+
},
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
972
1066
|
case "tools/call": {
|
|
973
1067
|
const params = ensureObject(message.params, "tools/call params");
|
|
974
1068
|
const name = stringArg(params.name, "name");
|
|
@@ -1238,6 +1332,35 @@ export class PaybondMCPServer {
|
|
|
1238
1332
|
}, ["intent_id"]),
|
|
1239
1333
|
call: async (args) => this.runtime.getIntent(uuidArg(args.intent_id, "intent_id")),
|
|
1240
1334
|
},
|
|
1335
|
+
{
|
|
1336
|
+
name: "paybond_list_audit_exports",
|
|
1337
|
+
description: "List tenant-scoped compliance audit export jobs through the gateway operator view.",
|
|
1338
|
+
inputSchema: objectSchema({
|
|
1339
|
+
limit: { type: "integer", minimum: 1, maximum: 200 },
|
|
1340
|
+
cursor: { type: "string" },
|
|
1341
|
+
}),
|
|
1342
|
+
call: async (args) => this.runtime.listAuditExports({
|
|
1343
|
+
limit: args.limit === undefined ? undefined : intArg(args.limit, "limit"),
|
|
1344
|
+
cursor: optionalString(args.cursor),
|
|
1345
|
+
}),
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
name: "paybond_get_audit_export",
|
|
1349
|
+
description: "Fetch one tenant-scoped compliance audit export job detail through the gateway operator view.",
|
|
1350
|
+
inputSchema: objectSchema({
|
|
1351
|
+
job_id: {
|
|
1352
|
+
type: "string",
|
|
1353
|
+
description: "Compliance audit export job identifier.",
|
|
1354
|
+
},
|
|
1355
|
+
issue_download: {
|
|
1356
|
+
type: "boolean",
|
|
1357
|
+
description: "When true, request a bundle download token for ready exports.",
|
|
1358
|
+
},
|
|
1359
|
+
}, ["job_id"]),
|
|
1360
|
+
call: async (args) => this.runtime.getAuditExport(stringArg(args.job_id, "job_id"), {
|
|
1361
|
+
issueDownload: args.issue_download === true,
|
|
1362
|
+
}),
|
|
1363
|
+
},
|
|
1241
1364
|
{
|
|
1242
1365
|
name: "paybond_get_reputation_receipt",
|
|
1243
1366
|
description: "Fetch the signed Signal receipt for one operator DID.",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MPP commercial denomination helpers for Paybond MVP.
|
|
3
|
+
*
|
|
4
|
+
* Paybond intent commercial fields remain USD-denominated (`amount_cents`, `currency`).
|
|
5
|
+
* Tempo session deposits use USDC base units (6 decimals): `amount_cents * 10_000`.
|
|
6
|
+
*/
|
|
7
|
+
import type { SettlementRail } from "./principal-intent.js";
|
|
8
|
+
/** USDC uses 6 decimal places; one USD cent maps to 10_000 base units. */
|
|
9
|
+
export declare const USDC_BASE_UNITS_PER_USD_CENT = 10000;
|
|
10
|
+
/** Rails that require USD-denominated commercial intent fields for MVP. */
|
|
11
|
+
export declare const USD_DENOMINATED_SETTLEMENT_RAILS: Set<SettlementRail>;
|
|
12
|
+
/**
|
|
13
|
+
* Rejects non-USD intents on rails that remain USD-denominated for MVP.
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateUsdDenominatedSettlement(settlementRail: SettlementRail, currency: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Converts Paybond USD cents to Tempo USDC base units.
|
|
18
|
+
*/
|
|
19
|
+
export declare function usdCentsToUsdcBaseUnits(amountCents: number): bigint;
|