@paybond/kit 0.10.0 → 0.11.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/README.md +59 -15
- package/completion-presets/catalog.json +1187 -0
- package/completion-presets/catalog.sha256 +1 -0
- package/dev/trace-ui/dashboard.html +617 -0
- package/dist/agent/adapter.d.ts +51 -0
- package/dist/agent/adapter.js +66 -0
- package/dist/agent/attach-bundle.d.ts +37 -0
- package/dist/agent/attach-bundle.js +118 -0
- package/dist/agent/authorization-cache.d.ts +22 -0
- package/dist/agent/authorization-cache.js +36 -0
- package/dist/agent/deferred-tools.d.ts +11 -0
- package/dist/agent/deferred-tools.js +62 -0
- package/dist/agent/discover.d.ts +41 -0
- package/dist/agent/discover.js +147 -0
- package/dist/agent/evidence.d.ts +9 -0
- package/dist/agent/evidence.js +28 -0
- package/dist/agent/facade.d.ts +48 -0
- package/dist/agent/facade.js +112 -0
- package/dist/agent/gateway-trace-reporter.d.ts +28 -0
- package/dist/agent/gateway-trace-reporter.js +49 -0
- package/dist/agent/generic-runner.d.ts +14 -0
- package/dist/agent/generic-runner.js +49 -0
- package/dist/agent/generic-sandbox-demo.d.ts +36 -0
- package/dist/agent/generic-sandbox-demo.js +82 -0
- package/dist/agent/guarded-agent.d.ts +49 -0
- package/dist/agent/guarded-agent.js +100 -0
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.js +13 -0
- package/dist/agent/instrument.d.ts +156 -0
- package/dist/agent/instrument.js +442 -0
- package/dist/agent/interceptor.d.ts +24 -0
- package/dist/agent/interceptor.js +440 -0
- package/dist/agent/lazy-context-tools.d.ts +15 -0
- package/dist/agent/lazy-context-tools.js +81 -0
- package/dist/agent/registry-file.d.ts +39 -0
- package/dist/agent/registry-file.js +219 -0
- package/dist/agent/registry.d.ts +37 -0
- package/dist/agent/registry.js +128 -0
- package/dist/agent/run.d.ts +124 -0
- package/dist/agent/run.js +301 -0
- package/dist/agent/types.d.ts +318 -0
- package/dist/agent/types.js +42 -0
- package/dist/agent-recognition.d.ts +72 -0
- package/dist/agent-recognition.js +165 -0
- package/dist/bincode-wire.d.ts +18 -0
- package/dist/bincode-wire.js +93 -0
- package/dist/claude-agents/config.d.ts +21 -0
- package/dist/claude-agents/config.js +145 -0
- package/dist/claude-agents/index.d.ts +2 -0
- package/dist/claude-agents/index.js +2 -0
- package/dist/claude-agents/sandbox-demo.d.ts +30 -0
- package/dist/claude-agents/sandbox-demo.js +91 -0
- package/dist/cli/agent/demo-loaders.d.ts +4 -0
- package/dist/cli/agent/demo-loaders.js +66 -0
- package/dist/cli/agent/env-quote.d.ts +1 -0
- package/dist/cli/agent/env-quote.js +6 -0
- package/dist/cli/agent/env-write.d.ts +8 -0
- package/dist/cli/agent/env-write.js +47 -0
- package/dist/cli/agent/paybond.d.ts +16 -0
- package/dist/cli/agent/paybond.js +55 -0
- package/dist/cli/agent/policy-file.d.ts +29 -0
- package/dist/cli/agent/policy-file.js +61 -0
- package/dist/cli/agent/production-evidence.d.ts +24 -0
- package/dist/cli/agent/production-evidence.js +98 -0
- package/dist/cli/agent/run-store.d.ts +30 -0
- package/dist/cli/agent/run-store.js +42 -0
- package/dist/cli/agent/run-trace-store.d.ts +39 -0
- package/dist/cli/agent/run-trace-store.js +143 -0
- package/dist/cli/agent-run-trace-table.d.ts +9 -0
- package/dist/cli/agent-run-trace-table.js +24 -0
- package/dist/cli/agent-sandbox-smoke-checklist.d.ts +9 -0
- package/dist/cli/agent-sandbox-smoke-checklist.js +50 -0
- package/dist/cli/command-spec.d.ts +1 -0
- package/dist/cli/command-spec.js +286 -5
- package/dist/cli/commands/agent.d.ts +16 -0
- package/dist/cli/commands/agent.js +1136 -0
- package/dist/cli/commands/dev.d.ts +7 -0
- package/dist/cli/commands/dev.js +348 -0
- package/dist/cli/commands/discovery.js +3 -3
- package/dist/cli/commands/policy.d.ts +13 -0
- package/dist/cli/commands/policy.js +769 -0
- package/dist/cli/commands/setup.d.ts +3 -0
- package/dist/cli/commands/setup.js +124 -8
- package/dist/cli/commands/workflows.js +9 -4
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.js +4 -2
- package/dist/cli/context.js +2 -1
- package/dist/cli/credentials.js +2 -2
- package/dist/cli/doctor-agent-middleware.d.ts +5 -0
- package/dist/cli/doctor-agent-middleware.js +49 -0
- package/dist/cli/globals.d.ts +1 -0
- package/dist/cli/globals.js +11 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +35 -3
- package/dist/cli/mcp-install.js +2 -2
- package/dist/cli/mcp-policy.d.ts +3 -0
- package/dist/cli/mcp-policy.js +19 -13
- package/dist/cli/mcp-verify-config.js +9 -11
- package/dist/cli/redact.js +29 -8
- package/dist/cli/router.js +105 -2
- package/dist/cli/smoke-deep-links.d.ts +15 -0
- package/dist/cli/smoke-deep-links.js +63 -0
- package/dist/cli/telemetry.d.ts +17 -0
- package/dist/cli/telemetry.js +94 -0
- package/dist/completion-catalog-digest.d.ts +2 -0
- package/dist/completion-catalog-digest.js +2 -0
- package/dist/completion-catalog-integrity.d.ts +2 -0
- package/dist/completion-catalog-integrity.js +17 -0
- package/dist/completion-catalog.d.ts +49 -0
- package/dist/completion-catalog.js +62 -0
- package/dist/completion-contract-digest.d.ts +37 -0
- package/dist/completion-contract-digest.js +73 -0
- package/dist/completion-forbidden-fields.d.ts +5 -0
- package/dist/completion-forbidden-fields.js +26 -0
- package/dist/completion-init.d.ts +8 -0
- package/dist/completion-init.js +334 -0
- package/dist/completion-resolve.d.ts +21 -0
- package/dist/completion-resolve.js +86 -0
- package/dist/completion-validate-evidence.d.ts +24 -0
- package/dist/completion-validate-evidence.js +145 -0
- package/dist/dev/offline-gateway.d.ts +24 -0
- package/dist/dev/offline-gateway.js +102 -0
- package/dist/dev/trace-buffer.d.ts +61 -0
- package/dist/dev/trace-buffer.js +330 -0
- package/dist/dev/trace-security-headers.d.ts +11 -0
- package/dist/dev/trace-security-headers.js +16 -0
- package/dist/dev/trace-server.d.ts +8 -0
- package/dist/dev/trace-server.js +38 -0
- package/dist/dev/trace-ui.d.ts +4 -0
- package/dist/dev/trace-ui.js +25 -0
- package/dist/dev/wiremock-up.d.ts +15 -0
- package/dist/dev/wiremock-up.js +118 -0
- package/dist/doctor-completion.d.ts +17 -0
- package/dist/doctor-completion.js +428 -0
- package/dist/gateway-url.d.ts +7 -0
- package/dist/gateway-url.js +69 -0
- package/dist/index.d.ts +119 -2
- package/dist/index.js +267 -6
- package/dist/init.js +374 -57
- package/dist/langgraph/awrap-tool-call.d.ts +25 -0
- package/dist/langgraph/awrap-tool-call.js +81 -0
- package/dist/langgraph/config.d.ts +13 -0
- package/dist/langgraph/config.js +11 -0
- package/dist/langgraph/index.d.ts +4 -0
- package/dist/langgraph/index.js +4 -0
- package/dist/langgraph/sandbox-demo.d.ts +40 -0
- package/dist/langgraph/sandbox-demo.js +96 -0
- package/dist/langgraph/tool-node.d.ts +10 -0
- package/dist/langgraph/tool-node.js +38 -0
- package/dist/login.js +7 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/tool-surface.d.ts +25 -0
- package/dist/mcp/tool-surface.js +17 -0
- package/dist/mcp-capability-token-cache.d.ts +24 -0
- package/dist/mcp-capability-token-cache.js +101 -0
- package/dist/mcp-evidence-policy.d.ts +48 -0
- package/dist/mcp-evidence-policy.js +117 -0
- package/dist/mcp-policy-reload.d.ts +79 -0
- package/dist/mcp-policy-reload.js +200 -0
- package/dist/mcp-sep2828-evidence.d.ts +36 -0
- package/dist/mcp-sep2828-evidence.js +65 -0
- package/dist/mcp-server.d.ts +6 -0
- package/dist/mcp-server.js +224 -44
- package/dist/openai-agents/index.d.ts +40 -0
- package/dist/openai-agents/index.js +151 -0
- package/dist/openai-agents/sandbox-demo.d.ts +34 -0
- package/dist/openai-agents/sandbox-demo.js +118 -0
- package/dist/payee-evidence.js +2 -29
- package/dist/policy/catalog.d.ts +31 -0
- package/dist/policy/catalog.js +48 -0
- package/dist/policy/compose-utils.d.ts +3 -0
- package/dist/policy/compose-utils.js +4 -0
- package/dist/policy/compose.d.ts +20 -0
- package/dist/policy/compose.js +240 -0
- package/dist/policy/digest.d.ts +7 -0
- package/dist/policy/digest.js +75 -0
- package/dist/policy/domain.d.ts +15 -0
- package/dist/policy/domain.js +28 -0
- package/dist/policy/guardrail-spec.d.ts +17 -0
- package/dist/policy/guardrail-spec.js +140 -0
- package/dist/policy/guardrails.d.ts +48 -0
- package/dist/policy/guardrails.js +72 -0
- package/dist/policy/index.d.ts +21 -0
- package/dist/policy/index.js +21 -0
- package/dist/policy/init.d.ts +102 -0
- package/dist/policy/init.js +351 -0
- package/dist/policy/intent-spec.d.ts +52 -0
- package/dist/policy/intent-spec.js +176 -0
- package/dist/policy/json-path.d.ts +4 -0
- package/dist/policy/json-path.js +23 -0
- package/dist/policy/layers-io.d.ts +7 -0
- package/dist/policy/layers-io.js +28 -0
- package/dist/policy/load-effective.d.ts +22 -0
- package/dist/policy/load-effective.js +77 -0
- package/dist/policy/load.d.ts +85 -0
- package/dist/policy/load.js +164 -0
- package/dist/policy/merge.d.ts +29 -0
- package/dist/policy/merge.js +297 -0
- package/dist/policy/parse-text.d.ts +2 -0
- package/dist/policy/parse-text.js +126 -0
- package/dist/policy/policy-api.d.ts +45 -0
- package/dist/policy/policy-api.js +61 -0
- package/dist/policy/presets.d.ts +19 -0
- package/dist/policy/presets.js +66 -0
- package/dist/policy/registry.d.ts +7 -0
- package/dist/policy/registry.js +33 -0
- package/dist/policy/reload.d.ts +86 -0
- package/dist/policy/reload.js +233 -0
- package/dist/policy/render-yaml.d.ts +3 -0
- package/dist/policy/render-yaml.js +69 -0
- package/dist/policy/sandbox-bootstrap.d.ts +19 -0
- package/dist/policy/sandbox-bootstrap.js +66 -0
- package/dist/policy/schema.d.ts +204 -0
- package/dist/policy/schema.js +255 -0
- package/dist/policy/snapshot.d.ts +33 -0
- package/dist/policy/snapshot.js +23 -0
- package/dist/policy/validate-remote.d.ts +43 -0
- package/dist/policy/validate-remote.js +104 -0
- package/dist/policy/validate.d.ts +36 -0
- package/dist/policy/validate.js +150 -0
- package/dist/policy/watcher.d.ts +29 -0
- package/dist/policy/watcher.js +112 -0
- package/dist/principal-intent.d.ts +52 -0
- package/dist/principal-intent.js +193 -37
- package/dist/project-init.d.ts +34 -0
- package/dist/project-init.js +898 -0
- package/dist/sep2828-signature.d.ts +10 -0
- package/dist/sep2828-signature.js +134 -0
- package/dist/solutions/api.d.ts +22 -0
- package/dist/solutions/api.js +40 -0
- package/dist/solutions/catalog.d.ts +34 -0
- package/dist/solutions/catalog.js +129 -0
- package/dist/solutions/index.d.ts +2 -0
- package/dist/solutions/index.js +2 -0
- package/dist/template-init.d.ts +54 -0
- package/dist/template-init.js +203 -0
- package/dist/vercel-ai/config.d.ts +15 -0
- package/dist/vercel-ai/config.js +13 -0
- package/dist/vercel-ai/index.d.ts +4 -0
- package/dist/vercel-ai/index.js +4 -0
- package/dist/vercel-ai/sandbox-demo.d.ts +44 -0
- package/dist/vercel-ai/sandbox-demo.js +153 -0
- package/dist/vercel-ai/tool-approval.d.ts +16 -0
- package/dist/vercel-ai/tool-approval.js +41 -0
- package/dist/vercel-ai/wrap-tools.d.ts +9 -0
- package/dist/vercel-ai/wrap-tools.js +40 -0
- package/dist/x402-receipt-evidence.d.ts +29 -0
- package/dist/x402-receipt-evidence.js +97 -0
- package/dist/x402-receipt-signature.d.ts +12 -0
- package/dist/x402-receipt-signature.js +211 -0
- package/package.json +75 -3
- package/solutions/aws.json +17 -0
- package/solutions/saas.json +17 -0
- package/solutions/shopping.json +17 -0
- package/solutions/travel.json +18 -0
- package/templates/manifest.json +169 -0
- package/templates/openai-shopping-agent/.env.example +3 -0
- package/templates/openai-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/openai-shopping-agent/LICENSE +201 -0
- package/templates/openai-shopping-agent/README.md +29 -0
- package/templates/openai-shopping-agent/package-lock.json +1525 -0
- package/templates/openai-shopping-agent/package.json +22 -0
- package/templates/openai-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/openai-shopping-agent/src/index.ts +22 -0
- package/templates/openai-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/openai-shopping-agent/tsconfig.json +13 -0
- package/templates/paybond-aws-operator/.env.example +3 -0
- package/templates/paybond-aws-operator/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-aws-operator/LICENSE +201 -0
- package/templates/paybond-aws-operator/README.md +29 -0
- package/templates/paybond-aws-operator/package-lock.json +151 -0
- package/templates/paybond-aws-operator/package.json +20 -0
- package/templates/paybond-aws-operator/paybond.policy.yaml +22 -0
- package/templates/paybond-aws-operator/src/index.ts +54 -0
- package/templates/paybond-aws-operator/src/paybond.config.ts +51 -0
- package/templates/paybond-aws-operator/tsconfig.json +13 -0
- package/templates/paybond-claude-agents-demo/.env.example +3 -0
- package/templates/paybond-claude-agents-demo/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-claude-agents-demo/LICENSE +201 -0
- package/templates/paybond-claude-agents-demo/README.md +29 -0
- package/templates/paybond-claude-agents-demo/package-lock.json +1489 -0
- package/templates/paybond-claude-agents-demo/package.json +22 -0
- package/templates/paybond-claude-agents-demo/paybond.policy.yaml +22 -0
- package/templates/paybond-claude-agents-demo/src/index.ts +22 -0
- package/templates/paybond-claude-agents-demo/src/paybond.config.ts +51 -0
- package/templates/paybond-claude-agents-demo/tsconfig.json +13 -0
- package/templates/paybond-invoice-agent/.env.example +3 -0
- package/templates/paybond-invoice-agent/.github/workflows/smoke.yml +19 -0
- package/templates/paybond-invoice-agent/LICENSE +201 -0
- package/templates/paybond-invoice-agent/README.md +29 -0
- package/templates/paybond-invoice-agent/app.py +27 -0
- package/templates/paybond-invoice-agent/package.json +6 -0
- package/templates/paybond-invoice-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-invoice-agent/paybond_config.py +45 -0
- package/templates/paybond-invoice-agent/requirements.txt +2 -0
- package/templates/paybond-mcp-coding-agent/.env.example +3 -0
- package/templates/paybond-mcp-coding-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-mcp-coding-agent/LICENSE +201 -0
- package/templates/paybond-mcp-coding-agent/README.md +39 -0
- package/templates/paybond-mcp-coding-agent/package-lock.json +151 -0
- package/templates/paybond-mcp-coding-agent/package.json +20 -0
- package/templates/paybond-mcp-coding-agent/paybond.policy.yaml +25 -0
- package/templates/paybond-mcp-coding-agent/src/index.ts +40 -0
- package/templates/paybond-mcp-coding-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-mcp-coding-agent/tsconfig.json +13 -0
- package/templates/paybond-openai-agents-demo/.env.example +3 -0
- package/templates/paybond-openai-agents-demo/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-openai-agents-demo/LICENSE +201 -0
- package/templates/paybond-openai-agents-demo/README.md +29 -0
- package/templates/paybond-openai-agents-demo/package-lock.json +1525 -0
- package/templates/paybond-openai-agents-demo/package.json +22 -0
- package/templates/paybond-openai-agents-demo/paybond.policy.yaml +22 -0
- package/templates/paybond-openai-agents-demo/src/index.ts +22 -0
- package/templates/paybond-openai-agents-demo/src/paybond.config.ts +51 -0
- package/templates/paybond-openai-agents-demo/tsconfig.json +13 -0
- package/templates/paybond-procurement-agent/.env.example +3 -0
- package/templates/paybond-procurement-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-procurement-agent/LICENSE +201 -0
- package/templates/paybond-procurement-agent/README.md +29 -0
- package/templates/paybond-procurement-agent/package-lock.json +151 -0
- package/templates/paybond-procurement-agent/package.json +20 -0
- package/templates/paybond-procurement-agent/paybond.policy.yaml +25 -0
- package/templates/paybond-procurement-agent/src/index.ts +54 -0
- package/templates/paybond-procurement-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-procurement-agent/tsconfig.json +13 -0
- package/templates/paybond-travel-agent/.env.example +3 -0
- package/templates/paybond-travel-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-travel-agent/LICENSE +201 -0
- package/templates/paybond-travel-agent/README.md +29 -0
- package/templates/paybond-travel-agent/package-lock.json +444 -0
- package/templates/paybond-travel-agent/package.json +23 -0
- package/templates/paybond-travel-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-travel-agent/src/index.ts +22 -0
- package/templates/paybond-travel-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-travel-agent/tsconfig.json +13 -0
- package/templates/paybond-vercel-shopping-agent/.env.example +3 -0
- package/templates/paybond-vercel-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-vercel-shopping-agent/LICENSE +201 -0
- package/templates/paybond-vercel-shopping-agent/README.md +29 -0
- package/templates/paybond-vercel-shopping-agent/package-lock.json +265 -0
- package/templates/paybond-vercel-shopping-agent/package.json +22 -0
- package/templates/paybond-vercel-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-vercel-shopping-agent/src/index.ts +22 -0
- package/templates/paybond-vercel-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-vercel-shopping-agent/tsconfig.json +13 -0
package/dist/mcp-server.js
CHANGED
|
@@ -4,11 +4,16 @@ import { readFileSync } from "node:fs";
|
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { requireSecureGatewayUrl } from "./gateway-url.js";
|
|
7
8
|
import { runCli } from "./cli/router.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { redactSensitiveFields } from "./cli/redact.js";
|
|
10
|
+
import { MCP_TOOL_ALLOWLIST_ENV, MCP_TOOL_POLICY_ENV, mergeMcpToolPolicy, parseMcpToolAllowlist, parseMcpToolPolicy, resolveMcpToolPolicy, toolAllowedByPolicy, } from "./cli/mcp-policy.js";
|
|
11
|
+
import { MCP_EVIDENCE_POLICY_ENV, McpEvidenceValidationGate, completionEvidenceValidationOk, extractHarborEvidenceValidationInput, extractSandboxGuardrailValidationInput, parseMcpEvidencePolicy, } from "./mcp-evidence-policy.js";
|
|
12
|
+
import { McpCapabilityTokenCache, mcpToolStoresCapabilityToken, parseMcpCapabilityTokenCacheConfig, } from "./mcp-capability-token-cache.js";
|
|
13
|
+
import { createMcpPolicyGatewayAdapter, McpPolicyReloadGate, parseMcpPolicyReloadConfig, } from "./mcp-policy-reload.js";
|
|
14
|
+
import { DEFAULT_PAYBOND_GATEWAY_BASE_URL, GatewayFraudClient, GatewaySignalClient, } from "./index.js";
|
|
10
15
|
const SERVER_NAME = "Paybond MCP";
|
|
11
|
-
const SERVER_VERSION = "0.
|
|
16
|
+
const SERVER_VERSION = "0.11.1";
|
|
12
17
|
const MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
13
18
|
const DEFAULT_PRINCIPAL_PATH = "/v1/auth/principal";
|
|
14
19
|
const DEFAULT_RECOGNITION_VERIFIER_ID = "paybond-gateway";
|
|
@@ -98,6 +103,22 @@ const TOOL_SELECTION_METADATA = {
|
|
|
98
103
|
"sandbox_lifecycle_status",
|
|
99
104
|
]),
|
|
100
105
|
},
|
|
106
|
+
paybond_validate_completion_evidence: {
|
|
107
|
+
title: "Validate Completion Evidence",
|
|
108
|
+
description: "Pre-validates vendor and canonical completion evidence against catalog JSON Schemas and preset forbidden_evidence_fields. " +
|
|
109
|
+
"Required before evidence submit tools when PAYBOND_MCP_EVIDENCE_POLICY=strict. Harbor remains authoritative at submit time.",
|
|
110
|
+
annotations: readOnlyToolAnnotations("Validate Completion Evidence"),
|
|
111
|
+
outputSchema: outputObjectSchema({
|
|
112
|
+
preset_id: { type: "string" },
|
|
113
|
+
ok: { type: "boolean" },
|
|
114
|
+
vendor_schema_ok: { type: "boolean" },
|
|
115
|
+
canonical_schema_ok: { type: "boolean" },
|
|
116
|
+
quality_fields_missing: { type: "array", items: { type: "string" } },
|
|
117
|
+
forbidden_fields_present: { type: "array", items: { type: "string" } },
|
|
118
|
+
pack_stale: { type: "boolean" },
|
|
119
|
+
drift_kinds: { type: "array", items: { type: "string" } },
|
|
120
|
+
}, ["preset_id", "ok"]),
|
|
121
|
+
},
|
|
101
122
|
paybond_submit_sandbox_guardrail_evidence: {
|
|
102
123
|
title: "Submit Sandbox Guardrail Evidence",
|
|
103
124
|
description: "Use this when a sandbox guardrail intent needs evidence to complete simulator settlement or predicate checks. " +
|
|
@@ -330,6 +351,13 @@ const TOOL_SELECTION_METADATA = {
|
|
|
330
351
|
}),
|
|
331
352
|
},
|
|
332
353
|
};
|
|
354
|
+
function readIntentAllowedTools(intent) {
|
|
355
|
+
const raw = intent.allowed_tools;
|
|
356
|
+
if (!Array.isArray(raw)) {
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
return raw.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
360
|
+
}
|
|
333
361
|
function readEnvFileValue(envFile, key) {
|
|
334
362
|
let body;
|
|
335
363
|
try {
|
|
@@ -473,7 +501,14 @@ class PaybondMCPRuntime {
|
|
|
473
501
|
principalValue = null;
|
|
474
502
|
signalValue = null;
|
|
475
503
|
fraudValue = null;
|
|
504
|
+
capabilityTokenCache;
|
|
505
|
+
evidenceGate;
|
|
506
|
+
policyReloadConfig;
|
|
507
|
+
policyGatePromise = null;
|
|
476
508
|
constructor(settings) {
|
|
509
|
+
this.evidenceGate = new McpEvidenceValidationGate(settings.evidencePolicy ?? parseMcpEvidencePolicy(undefined));
|
|
510
|
+
this.capabilityTokenCache = new McpCapabilityTokenCache(settings.capabilityTokenCache);
|
|
511
|
+
this.policyReloadConfig = settings.policyReload ?? null;
|
|
477
512
|
this.settings = {
|
|
478
513
|
gatewayBaseUrl: settings.gatewayBaseUrl ?? DEFAULT_PAYBOND_GATEWAY_BASE_URL,
|
|
479
514
|
apiKey: settings.apiKey,
|
|
@@ -486,6 +521,102 @@ class PaybondMCPRuntime {
|
|
|
486
521
|
maxRetries: this.settings.maxRetries,
|
|
487
522
|
});
|
|
488
523
|
}
|
|
524
|
+
async policyGate() {
|
|
525
|
+
if (!this.policyReloadConfig) {
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
this.policyGatePromise ??= McpPolicyReloadGate.open(this.policyReloadConfig, {
|
|
529
|
+
gateway: createMcpPolicyGatewayAdapter(this.gateway),
|
|
530
|
+
});
|
|
531
|
+
return this.policyGatePromise;
|
|
532
|
+
}
|
|
533
|
+
async getPolicyReloadStatus() {
|
|
534
|
+
const gate = await this.policyGate();
|
|
535
|
+
return gate?.status() ?? null;
|
|
536
|
+
}
|
|
537
|
+
async beginPolicyToolCall() {
|
|
538
|
+
const gate = await this.policyGate();
|
|
539
|
+
gate?.beginToolCall();
|
|
540
|
+
}
|
|
541
|
+
async endPolicyToolCall() {
|
|
542
|
+
const gate = await this.policyGate();
|
|
543
|
+
gate?.endToolCall();
|
|
544
|
+
}
|
|
545
|
+
stopPolicyReload() {
|
|
546
|
+
void this.policyGatePromise?.then((gate) => gate?.stop());
|
|
547
|
+
this.policyGatePromise = null;
|
|
548
|
+
}
|
|
549
|
+
async authorizeAgentSpend(init) {
|
|
550
|
+
const gate = await this.policyGate();
|
|
551
|
+
let operation = init.operation;
|
|
552
|
+
let requestedSpendCents = init.requestedSpendCents ?? 0;
|
|
553
|
+
let policyDigest;
|
|
554
|
+
if (gate) {
|
|
555
|
+
const intent = await this.getIntent(init.intentId);
|
|
556
|
+
const allowedTools = readIntentAllowedTools(intent);
|
|
557
|
+
const gated = gate.assertSpendGate({
|
|
558
|
+
toolName: init.toolName,
|
|
559
|
+
operation,
|
|
560
|
+
allowedTools,
|
|
561
|
+
requestedSpendCents: init.requestedSpendCents,
|
|
562
|
+
});
|
|
563
|
+
operation = gated.operation;
|
|
564
|
+
requestedSpendCents = gated.requestedSpendCents;
|
|
565
|
+
policyDigest = gated.policyDigest;
|
|
566
|
+
}
|
|
567
|
+
const body = await this.verifyCapability({
|
|
568
|
+
intentId: init.intentId,
|
|
569
|
+
token: init.token,
|
|
570
|
+
operation,
|
|
571
|
+
requestedSpendCents,
|
|
572
|
+
});
|
|
573
|
+
if (policyDigest) {
|
|
574
|
+
body.policy_digest = policyDigest;
|
|
575
|
+
}
|
|
576
|
+
return body;
|
|
577
|
+
}
|
|
578
|
+
storeCapabilityToken(intentId, token) {
|
|
579
|
+
this.capabilityTokenCache.store(intentId, token);
|
|
580
|
+
}
|
|
581
|
+
async resolveCapabilityToken(intentId, token) {
|
|
582
|
+
const explicit = token?.trim();
|
|
583
|
+
if (explicit) {
|
|
584
|
+
return explicit;
|
|
585
|
+
}
|
|
586
|
+
const stored = this.capabilityTokenCache.resolve(intentId.trim());
|
|
587
|
+
if (stored) {
|
|
588
|
+
return stored;
|
|
589
|
+
}
|
|
590
|
+
throw new Error(`capability token unavailable or expired for intent ${intentId}; create or bootstrap a funded intent first`);
|
|
591
|
+
}
|
|
592
|
+
prepareToolResponse(value, toolName) {
|
|
593
|
+
if (value === null) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
const intentId = String(value.intent_id ?? "").trim();
|
|
597
|
+
const token = value.capability_token;
|
|
598
|
+
if (mcpToolStoresCapabilityToken(toolName) &&
|
|
599
|
+
intentId &&
|
|
600
|
+
typeof token === "string" &&
|
|
601
|
+
token.trim()) {
|
|
602
|
+
this.storeCapabilityToken(intentId, token);
|
|
603
|
+
}
|
|
604
|
+
return redactSensitiveFields(value);
|
|
605
|
+
}
|
|
606
|
+
validateCompletionEvidence(input) {
|
|
607
|
+
const report = this.evidenceGate.validateAndRecord(input);
|
|
608
|
+
return {
|
|
609
|
+
...report,
|
|
610
|
+
ok: completionEvidenceValidationOk(report),
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
requireEvidenceValidation(input) {
|
|
614
|
+
this.evidenceGate.requirePass(input);
|
|
615
|
+
}
|
|
616
|
+
/** Resolve and cache the gateway principal during MCP server startup. */
|
|
617
|
+
async preloadPrincipal() {
|
|
618
|
+
await this.principal();
|
|
619
|
+
}
|
|
489
620
|
async principal() {
|
|
490
621
|
this.principalValue ??= this.gateway.getJSON(this.settings.principalPath);
|
|
491
622
|
const body = await this.principalValue;
|
|
@@ -588,6 +719,11 @@ class PaybondMCPRuntime {
|
|
|
588
719
|
return body;
|
|
589
720
|
}
|
|
590
721
|
async submitSandboxGuardrailEvidence(init) {
|
|
722
|
+
const extracted = extractSandboxGuardrailValidationInput({
|
|
723
|
+
payload: init.payload,
|
|
724
|
+
completionPresetId: init.completionPresetId,
|
|
725
|
+
});
|
|
726
|
+
this.requireEvidenceValidation(extracted);
|
|
591
727
|
const expectedTenant = await this.tenantId();
|
|
592
728
|
const payload = {};
|
|
593
729
|
if (init.payload !== undefined) {
|
|
@@ -625,7 +761,6 @@ class PaybondMCPRuntime {
|
|
|
625
761
|
const verifier = {
|
|
626
762
|
tenant_id: await this.tenantId(),
|
|
627
763
|
verifier_id: DEFAULT_RECOGNITION_VERIFIER_ID,
|
|
628
|
-
...(init.expectedVerifier ?? {}),
|
|
629
764
|
};
|
|
630
765
|
return this.gateway.postJSON("/protocol/v2/recognition/verify", {
|
|
631
766
|
proof: init.proof,
|
|
@@ -690,6 +825,8 @@ class PaybondMCPRuntime {
|
|
|
690
825
|
}));
|
|
691
826
|
}
|
|
692
827
|
async submitHarborEvidence(init) {
|
|
828
|
+
const extracted = extractHarborEvidenceValidationInput(init.body, init.completionPresetId);
|
|
829
|
+
this.requireEvidenceValidation(extracted);
|
|
693
830
|
return this.gateway.postJSON(`/harbor/intents/${encodeURIComponent(init.intentId)}/evidence`, init.body, gatewayMutationHeaders(await this.tenantId(), init.recognitionProof, optionalMutationHeaders(init.idempotencyKey)));
|
|
694
831
|
}
|
|
695
832
|
async confirmHarborSettlement(init) {
|
|
@@ -722,7 +859,7 @@ export class PaybondMCPServer {
|
|
|
722
859
|
if (!settings.apiKey.trim()) {
|
|
723
860
|
throw new Error("PAYBOND_API_KEY is required");
|
|
724
861
|
}
|
|
725
|
-
this.toolPolicy = settings.toolPolicy ?? { policy: null, allowlist: [] };
|
|
862
|
+
this.toolPolicy = resolveMcpToolPolicy(settings.toolPolicy ?? { policy: null, allowlist: [] });
|
|
726
863
|
this.runtime = new PaybondMCPRuntime(settings);
|
|
727
864
|
this.tools = this.buildTools(settings).filter((tool) => toolAllowedByPolicy(tool.name, tool.annotations, this.toolPolicy));
|
|
728
865
|
}
|
|
@@ -753,15 +890,21 @@ export class PaybondMCPServer {
|
|
|
753
890
|
content: [
|
|
754
891
|
{
|
|
755
892
|
type: "text",
|
|
756
|
-
text: `Tool blocked by ${MCP_TOOL_POLICY_ENV}=${this.toolPolicy.policy ?? "
|
|
893
|
+
text: `Tool blocked by ${MCP_TOOL_POLICY_ENV}=${this.toolPolicy.policy ?? "spend-write"}: ${name}`,
|
|
757
894
|
},
|
|
758
895
|
],
|
|
759
896
|
isError: true,
|
|
760
897
|
};
|
|
761
898
|
}
|
|
762
899
|
try {
|
|
763
|
-
|
|
764
|
-
|
|
900
|
+
await this.runtime.beginPolicyToolCall();
|
|
901
|
+
try {
|
|
902
|
+
const value = await tool.call(args);
|
|
903
|
+
return toToolResult(this.runtime.prepareToolResponse(value === null ? null : value, name));
|
|
904
|
+
}
|
|
905
|
+
finally {
|
|
906
|
+
await this.runtime.endPolicyToolCall();
|
|
907
|
+
}
|
|
765
908
|
}
|
|
766
909
|
catch (err) {
|
|
767
910
|
return {
|
|
@@ -787,6 +930,7 @@ export class PaybondMCPServer {
|
|
|
787
930
|
}
|
|
788
931
|
switch (method) {
|
|
789
932
|
case "initialize":
|
|
933
|
+
await this.runtime.preloadPrincipal();
|
|
790
934
|
return {
|
|
791
935
|
jsonrpc: "2.0",
|
|
792
936
|
id: message.id,
|
|
@@ -805,9 +949,10 @@ export class PaybondMCPServer {
|
|
|
805
949
|
websiteUrl: "https://paybond.ai",
|
|
806
950
|
},
|
|
807
951
|
instructions: "This MCP server is tenant-bound to the configured Paybond service-account API key. " +
|
|
808
|
-
"Use paybond_create_spend_intent or
|
|
809
|
-
"
|
|
810
|
-
"It works with any MCP-compatible host
|
|
952
|
+
"Use paybond_create_spend_intent or paybond_bootstrap_sandbox_guardrail to obtain a funded intent_id, " +
|
|
953
|
+
"then call paybond_authorize_agent_spend before side-effecting tools. Capability tokens are stored " +
|
|
954
|
+
"inside this MCP server and are not returned to agent logs. It works with any MCP-compatible host " +
|
|
955
|
+
"and does not assume a specific model provider.",
|
|
811
956
|
},
|
|
812
957
|
};
|
|
813
958
|
case "ping":
|
|
@@ -910,7 +1055,7 @@ export class PaybondMCPServer {
|
|
|
910
1055
|
},
|
|
911
1056
|
token: {
|
|
912
1057
|
type: "string",
|
|
913
|
-
description: "
|
|
1058
|
+
description: "Optional capability token override. When omitted, the MCP server uses the token stored for intent_id.",
|
|
914
1059
|
},
|
|
915
1060
|
operation: {
|
|
916
1061
|
type: "string",
|
|
@@ -920,15 +1065,19 @@ export class PaybondMCPServer {
|
|
|
920
1065
|
type: "integer",
|
|
921
1066
|
description: "Optional requested spend in cents for this tool call.",
|
|
922
1067
|
},
|
|
923
|
-
}, ["intent_id", "
|
|
924
|
-
call: async (args) =>
|
|
925
|
-
intentId
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
:
|
|
931
|
-
|
|
1068
|
+
}, ["intent_id", "operation"]),
|
|
1069
|
+
call: async (args) => {
|
|
1070
|
+
const intentId = uuidArg(args.intent_id, "intent_id");
|
|
1071
|
+
return this.runtime.authorizeAgentSpend({
|
|
1072
|
+
intentId,
|
|
1073
|
+
token: await this.runtime.resolveCapabilityToken(intentId, optionalString(args.token)),
|
|
1074
|
+
operation: stringArg(args.operation, "operation"),
|
|
1075
|
+
requestedSpendCents: args.requested_spend_cents === undefined
|
|
1076
|
+
? undefined
|
|
1077
|
+
: intArg(args.requested_spend_cents, "requested_spend_cents"),
|
|
1078
|
+
toolName: stringArg(args.operation, "operation"),
|
|
1079
|
+
});
|
|
1080
|
+
},
|
|
932
1081
|
},
|
|
933
1082
|
{
|
|
934
1083
|
name: "paybond_authorize_agent_spend",
|
|
@@ -940,7 +1089,7 @@ export class PaybondMCPServer {
|
|
|
940
1089
|
},
|
|
941
1090
|
token: {
|
|
942
1091
|
type: "string",
|
|
943
|
-
description: "
|
|
1092
|
+
description: "Optional capability token override. When omitted, the MCP server uses the token stored for intent_id.",
|
|
944
1093
|
},
|
|
945
1094
|
operation: {
|
|
946
1095
|
type: "string",
|
|
@@ -950,15 +1099,19 @@ export class PaybondMCPServer {
|
|
|
950
1099
|
type: "integer",
|
|
951
1100
|
description: "Optional requested spend in cents for this tool call.",
|
|
952
1101
|
},
|
|
953
|
-
}, ["intent_id", "
|
|
954
|
-
call: async (args) =>
|
|
955
|
-
intentId
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
:
|
|
961
|
-
|
|
1102
|
+
}, ["intent_id", "operation"]),
|
|
1103
|
+
call: async (args) => {
|
|
1104
|
+
const intentId = uuidArg(args.intent_id, "intent_id");
|
|
1105
|
+
return this.runtime.authorizeAgentSpend({
|
|
1106
|
+
intentId,
|
|
1107
|
+
token: await this.runtime.resolveCapabilityToken(intentId, optionalString(args.token)),
|
|
1108
|
+
operation: stringArg(args.operation, "operation"),
|
|
1109
|
+
requestedSpendCents: args.requested_spend_cents === undefined
|
|
1110
|
+
? undefined
|
|
1111
|
+
: intArg(args.requested_spend_cents, "requested_spend_cents"),
|
|
1112
|
+
toolName: stringArg(args.operation, "operation"),
|
|
1113
|
+
});
|
|
1114
|
+
},
|
|
962
1115
|
},
|
|
963
1116
|
{
|
|
964
1117
|
name: "paybond_bootstrap_sandbox_guardrail",
|
|
@@ -993,6 +1146,30 @@ export class PaybondMCPServer {
|
|
|
993
1146
|
idempotencyKey: optionalString(args.idempotency_key),
|
|
994
1147
|
}),
|
|
995
1148
|
},
|
|
1149
|
+
{
|
|
1150
|
+
name: "paybond_validate_completion_evidence",
|
|
1151
|
+
description: "Pre-validates completion evidence against the shared preset catalog. Call this before paybond_submit_*_evidence when PAYBOND_MCP_EVIDENCE_POLICY=strict.",
|
|
1152
|
+
inputSchema: objectSchema({
|
|
1153
|
+
preset_id: { type: "string" },
|
|
1154
|
+
vendor_payload: { type: "object", additionalProperties: true },
|
|
1155
|
+
canonical_payload: { type: "object", additionalProperties: true },
|
|
1156
|
+
frozen_vendor_api_version: { type: "string" },
|
|
1157
|
+
frozen_vendor_schema_digest_hex: { type: "string" },
|
|
1158
|
+
frozen_canonical_schema_digest_hex: { type: "string" },
|
|
1159
|
+
}, ["preset_id"]),
|
|
1160
|
+
call: async (args) => this.runtime.validateCompletionEvidence({
|
|
1161
|
+
presetId: stringArg(args.preset_id, "preset_id"),
|
|
1162
|
+
vendorPayload: args.vendor_payload === undefined
|
|
1163
|
+
? undefined
|
|
1164
|
+
: ensureObject(args.vendor_payload, "vendor_payload"),
|
|
1165
|
+
canonicalPayload: args.canonical_payload === undefined
|
|
1166
|
+
? undefined
|
|
1167
|
+
: ensureObject(args.canonical_payload, "canonical_payload"),
|
|
1168
|
+
frozenVendorApiVersion: optionalString(args.frozen_vendor_api_version),
|
|
1169
|
+
frozenVendorSchemaDigestHex: optionalString(args.frozen_vendor_schema_digest_hex),
|
|
1170
|
+
frozenCanonicalSchemaDigestHex: optionalString(args.frozen_canonical_schema_digest_hex),
|
|
1171
|
+
}),
|
|
1172
|
+
},
|
|
996
1173
|
{
|
|
997
1174
|
name: "paybond_submit_sandbox_guardrail_evidence",
|
|
998
1175
|
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.",
|
|
@@ -1012,6 +1189,7 @@ export class PaybondMCPServer {
|
|
|
1012
1189
|
description: "Optional sandbox spend amount override for the evidence record.",
|
|
1013
1190
|
},
|
|
1014
1191
|
metadata: { type: "object", additionalProperties: true },
|
|
1192
|
+
completion_preset_id: { type: "string" },
|
|
1015
1193
|
idempotency_key: { type: "string" },
|
|
1016
1194
|
}, ["intent_id"]),
|
|
1017
1195
|
call: async (args) => this.runtime.submitSandboxGuardrailEvidence({
|
|
@@ -1029,6 +1207,7 @@ export class PaybondMCPServer {
|
|
|
1029
1207
|
metadata: args.metadata === undefined
|
|
1030
1208
|
? undefined
|
|
1031
1209
|
: ensureObject(args.metadata, "metadata"),
|
|
1210
|
+
completionPresetId: optionalString(args.completion_preset_id),
|
|
1032
1211
|
idempotencyKey: optionalString(args.idempotency_key),
|
|
1033
1212
|
}),
|
|
1034
1213
|
},
|
|
@@ -1135,20 +1314,17 @@ export class PaybondMCPServer {
|
|
|
1135
1314
|
},
|
|
1136
1315
|
{
|
|
1137
1316
|
name: "paybond_verify_agent_recognition_proof_v1",
|
|
1138
|
-
description: "Verify a replay-safe AgentRecognitionProofV1 against an expected purpose
|
|
1317
|
+
description: "Verify a replay-safe AgentRecognitionProofV1 against an expected purpose and request envelope. " +
|
|
1318
|
+
"Verifier context (tenant_id, verifier_id) is derived from the authenticated MCP session only.",
|
|
1139
1319
|
inputSchema: objectSchema({
|
|
1140
1320
|
proof: { type: "object", additionalProperties: true },
|
|
1141
1321
|
expected_purpose: { type: "string" },
|
|
1142
1322
|
expected_request: { type: "object", additionalProperties: true },
|
|
1143
|
-
expected_verifier: { type: "object", additionalProperties: true },
|
|
1144
1323
|
}, ["proof", "expected_purpose", "expected_request"]),
|
|
1145
1324
|
call: async (args) => this.runtime.verifyAgentRecognitionProofV1({
|
|
1146
1325
|
proof: ensureObject(args.proof, "proof"),
|
|
1147
1326
|
expectedPurpose: stringArg(args.expected_purpose, "expected_purpose"),
|
|
1148
1327
|
expectedRequest: ensureObject(args.expected_request, "expected_request"),
|
|
1149
|
-
expectedVerifier: args.expected_verifier === undefined
|
|
1150
|
-
? undefined
|
|
1151
|
-
: ensureObject(args.expected_verifier, "expected_verifier"),
|
|
1152
1328
|
}),
|
|
1153
1329
|
},
|
|
1154
1330
|
{
|
|
@@ -1236,12 +1412,14 @@ export class PaybondMCPServer {
|
|
|
1236
1412
|
intent_id: { type: "string" },
|
|
1237
1413
|
body: { type: "object", additionalProperties: true },
|
|
1238
1414
|
recognition_proof: { type: "object", additionalProperties: true },
|
|
1415
|
+
completion_preset_id: { type: "string" },
|
|
1239
1416
|
idempotency_key: { type: "string" },
|
|
1240
1417
|
}, ["intent_id", "body", "recognition_proof"]),
|
|
1241
1418
|
call: async (args) => this.runtime.submitHarborEvidence({
|
|
1242
1419
|
intentId: uuidArg(args.intent_id, "intent_id"),
|
|
1243
1420
|
body: ensureObject(args.body, "body"),
|
|
1244
1421
|
recognitionProof: ensureObject(args.recognition_proof, "recognition_proof"),
|
|
1422
|
+
completionPresetId: optionalString(args.completion_preset_id),
|
|
1245
1423
|
idempotencyKey: optionalString(args.idempotency_key),
|
|
1246
1424
|
}),
|
|
1247
1425
|
},
|
|
@@ -1252,12 +1430,14 @@ export class PaybondMCPServer {
|
|
|
1252
1430
|
intent_id: { type: "string" },
|
|
1253
1431
|
body: { type: "object", additionalProperties: true },
|
|
1254
1432
|
recognition_proof: { type: "object", additionalProperties: true },
|
|
1433
|
+
completion_preset_id: { type: "string" },
|
|
1255
1434
|
idempotency_key: { type: "string" },
|
|
1256
1435
|
}, ["intent_id", "body", "recognition_proof"]),
|
|
1257
1436
|
call: async (args) => this.runtime.submitHarborEvidence({
|
|
1258
1437
|
intentId: uuidArg(args.intent_id, "intent_id"),
|
|
1259
1438
|
body: ensureObject(args.body, "body"),
|
|
1260
1439
|
recognitionProof: ensureObject(args.recognition_proof, "recognition_proof"),
|
|
1440
|
+
completionPresetId: optionalString(args.completion_preset_id),
|
|
1261
1441
|
idempotencyKey: optionalString(args.idempotency_key),
|
|
1262
1442
|
}),
|
|
1263
1443
|
},
|
|
@@ -1288,15 +1468,18 @@ export function settingsFromEnv(env = process.env) {
|
|
|
1288
1468
|
throw new Error("PAYBOND_API_KEY is required; run paybond login or configure your MCP host environment");
|
|
1289
1469
|
}
|
|
1290
1470
|
return {
|
|
1291
|
-
gatewayBaseUrl: optionalEnv(env.PAYBOND_GATEWAY_URL) ??
|
|
1471
|
+
gatewayBaseUrl: requireSecureGatewayUrl(optionalEnv(env.PAYBOND_GATEWAY_URL) ??
|
|
1292
1472
|
optionalEnv(env.PAYBOND_GATEWAY_BASE_URL) ??
|
|
1293
|
-
DEFAULT_PAYBOND_GATEWAY_BASE_URL,
|
|
1473
|
+
DEFAULT_PAYBOND_GATEWAY_BASE_URL),
|
|
1294
1474
|
apiKey,
|
|
1295
1475
|
principalPath: optionalEnv(env.PAYBOND_PRINCIPAL_PATH) ?? DEFAULT_PRINCIPAL_PATH,
|
|
1296
1476
|
maxRetries: optionalEnv(env.PAYBOND_MCP_MAX_RETRIES)
|
|
1297
1477
|
? intArg(optionalEnv(env.PAYBOND_MCP_MAX_RETRIES), "PAYBOND_MCP_MAX_RETRIES")
|
|
1298
1478
|
: 3,
|
|
1299
|
-
toolPolicy: mergeMcpToolPolicy(parseMcpToolPolicy(optionalEnv(env[MCP_TOOL_POLICY_ENV])), parseMcpToolAllowlist(optionalEnv(env[MCP_TOOL_ALLOWLIST_ENV]))),
|
|
1479
|
+
toolPolicy: resolveMcpToolPolicy(mergeMcpToolPolicy(parseMcpToolPolicy(optionalEnv(env[MCP_TOOL_POLICY_ENV])), parseMcpToolAllowlist(optionalEnv(env[MCP_TOOL_ALLOWLIST_ENV])))),
|
|
1480
|
+
evidencePolicy: parseMcpEvidencePolicy(optionalEnv(env[MCP_EVIDENCE_POLICY_ENV])),
|
|
1481
|
+
policyReload: parseMcpPolicyReloadConfig(env),
|
|
1482
|
+
capabilityTokenCache: parseMcpCapabilityTokenCacheConfig(env),
|
|
1300
1483
|
};
|
|
1301
1484
|
}
|
|
1302
1485
|
export function main(argv = process.argv.slice(2)) {
|
|
@@ -1319,7 +1502,7 @@ export function main(argv = process.argv.slice(2)) {
|
|
|
1319
1502
|
}
|
|
1320
1503
|
}
|
|
1321
1504
|
function normalizeBase(url) {
|
|
1322
|
-
return url
|
|
1505
|
+
return requireSecureGatewayUrl(url);
|
|
1323
1506
|
}
|
|
1324
1507
|
function parseJSONObject(text, context) {
|
|
1325
1508
|
let parsed;
|
|
@@ -1481,10 +1664,7 @@ function optionalEnv(value) {
|
|
|
1481
1664
|
return value?.trim() ? value.trim() : undefined;
|
|
1482
1665
|
}
|
|
1483
1666
|
function formatError(err) {
|
|
1484
|
-
if (err instanceof Error
|
|
1485
|
-
err instanceof GatewayAuthError ||
|
|
1486
|
-
err instanceof GatewayHTTPError ||
|
|
1487
|
-
err instanceof SignalHttpError) {
|
|
1667
|
+
if (err instanceof Error) {
|
|
1488
1668
|
return err.message;
|
|
1489
1669
|
}
|
|
1490
1670
|
return String(err);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ToolGuardrailFunctionOutputFactory, type FunctionTool, type RunConfig, type ToolInputGuardrailDefinition } from "@openai/agents";
|
|
2
|
+
import { type PaybondAgentRun, type PaybondToolInputGuardDecision } from "../agent/index.js";
|
|
3
|
+
export type PaybondOpenAIAgentsAdapterOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* When true, side-effecting registered tools also set `needsApproval: true`
|
|
6
|
+
* so the OpenAI Agents SDK pauses for human review after Paybond pre-check passes.
|
|
7
|
+
*/
|
|
8
|
+
bridgeNeedsApproval?: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare function isFunctionTool(value: unknown): value is FunctionTool;
|
|
11
|
+
/** Detect OpenAI Agents SDK function tools (`type: "function"`). */
|
|
12
|
+
export { isFunctionTool as isOpenAIFunctionTool };
|
|
13
|
+
/** Map a framework-neutral Paybond decision to OpenAI tool guardrail output. */
|
|
14
|
+
export declare function mapPaybondDecisionToOpenAIToolGuardrail(decision: PaybondToolInputGuardDecision): ReturnType<typeof ToolGuardrailFunctionOutputFactory.allow>;
|
|
15
|
+
/** RunConfig fragment enabling Paybond verify before OpenAI approval interruptions. */
|
|
16
|
+
export declare const paybondOpenAIAgentsRunConfig: Pick<RunConfig, "toolExecution">;
|
|
17
|
+
/** Translate Paybond middleware into OpenAI Agents SDK tool input guardrails. */
|
|
18
|
+
export declare function createOpenAIAgentsAdapter(run: PaybondAgentRun, options?: PaybondOpenAIAgentsAdapterOptions): {
|
|
19
|
+
name: "openai-agents";
|
|
20
|
+
evaluate: (input: import("../agent/types.js").PaybondAuthorizeToolCallInput) => Promise<PaybondToolInputGuardDecision>;
|
|
21
|
+
wrapExecutors: <T extends import("../agent/adapter.js").PaybondGenericToolDefinition>(tools: T[]) => import("../agent/adapter.js").PaybondGenericWrappedToolDefinition[];
|
|
22
|
+
runConfig: Pick<RunConfig, "toolExecution">;
|
|
23
|
+
inputGuardrailFor(toolName: string): ToolInputGuardrailDefinition;
|
|
24
|
+
guardFunctionTools<TContext>(tools: Array<FunctionTool<TContext>>): Array<FunctionTool<TContext>>;
|
|
25
|
+
};
|
|
26
|
+
/** Convenience alias for {@link createOpenAIAgentsAdapter}. */
|
|
27
|
+
export declare function paybondOpenAIAgentsAdapter(run: PaybondAgentRun, options?: PaybondOpenAIAgentsAdapterOptions): ReturnType<typeof createOpenAIAgentsAdapter>;
|
|
28
|
+
export { runOpenAIAgentsSandboxDemo, type RunOpenAIAgentsSandboxDemoInput, type RunOpenAIAgentsSandboxDemoResult, } from "./sandbox-demo.js";
|
|
29
|
+
/** OpenAI Agents SDK runner config: guarded tools plus `runConfig` for pre-approval guardrails. */
|
|
30
|
+
export type PaybondOpenAIAgentsConfig<TContext = unknown> = {
|
|
31
|
+
tools: Array<FunctionTool<TContext>>;
|
|
32
|
+
runConfig: Pick<RunConfig, "toolExecution">;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Framework runner helper for OpenAI Agents SDK `Runner.run`.
|
|
36
|
+
*
|
|
37
|
+
* Returns guarded function tools and the `runConfig` fragment that enables
|
|
38
|
+
* Paybond verify before approval interruptions.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createPaybondOpenAIAgentsConfig<TContext>(run: PaybondAgentRun, tools: Array<FunctionTool<TContext>>, options?: PaybondOpenAIAgentsAdapterOptions): PaybondOpenAIAgentsConfig<TContext>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { defineToolInputGuardrail, ToolGuardrailFunctionOutputFactory, } from "@openai/agents";
|
|
2
|
+
import { createToolInputGuardAdapter, } from "../agent/index.js";
|
|
3
|
+
function parseToolArguments(raw) {
|
|
4
|
+
if (!raw.trim()) {
|
|
5
|
+
return {};
|
|
6
|
+
}
|
|
7
|
+
return JSON.parse(raw);
|
|
8
|
+
}
|
|
9
|
+
function isFunctionTool(value) {
|
|
10
|
+
if (typeof value !== "object" || value === null) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const record = value;
|
|
14
|
+
return record.type === "function" && typeof record.name === "string" && typeof record.invoke === "function";
|
|
15
|
+
}
|
|
16
|
+
/** Detect OpenAI Agents SDK function tools (`type: "function"`). */
|
|
17
|
+
export { isFunctionTool as isOpenAIFunctionTool };
|
|
18
|
+
/** Map a framework-neutral Paybond decision to OpenAI tool guardrail output. */
|
|
19
|
+
export function mapPaybondDecisionToOpenAIToolGuardrail(decision) {
|
|
20
|
+
if (decision.kind === "allow") {
|
|
21
|
+
return ToolGuardrailFunctionOutputFactory.allow({
|
|
22
|
+
paybond: {
|
|
23
|
+
operation: decision.operation,
|
|
24
|
+
auditId: decision.auditId,
|
|
25
|
+
decisionId: decision.decisionId,
|
|
26
|
+
passthrough: decision.passthrough ?? false,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return ToolGuardrailFunctionOutputFactory.rejectContent(decision.message, {
|
|
31
|
+
paybond: {
|
|
32
|
+
kind: decision.kind,
|
|
33
|
+
operation: decision.operation,
|
|
34
|
+
auditId: decision.auditId,
|
|
35
|
+
code: decision.code,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function buildPaybondInputGuardrail(run, toolName) {
|
|
40
|
+
const guard = createToolInputGuardAdapter(run);
|
|
41
|
+
return defineToolInputGuardrail({
|
|
42
|
+
name: `paybond_spend_${toolName}`,
|
|
43
|
+
run: async ({ toolCall }) => {
|
|
44
|
+
const args = parseToolArguments(toolCall.arguments);
|
|
45
|
+
const decision = await guard.evaluate({
|
|
46
|
+
toolName: toolCall.name,
|
|
47
|
+
toolCallId: toolCall.callId,
|
|
48
|
+
arguments: args,
|
|
49
|
+
});
|
|
50
|
+
return mapPaybondDecisionToOpenAIToolGuardrail(decision);
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function resolveToolCallId(details) {
|
|
55
|
+
const callId = details?.toolCall?.callId?.trim();
|
|
56
|
+
if (callId) {
|
|
57
|
+
return callId;
|
|
58
|
+
}
|
|
59
|
+
return globalThis.crypto.randomUUID();
|
|
60
|
+
}
|
|
61
|
+
function guardFunctionTool(run, fnTool, options) {
|
|
62
|
+
if (!run.registry.isSideEffecting(fnTool.name)) {
|
|
63
|
+
return fnTool;
|
|
64
|
+
}
|
|
65
|
+
const paybondGuardrail = buildPaybondInputGuardrail(run, fnTool.name);
|
|
66
|
+
const originalInvoke = fnTool.invoke.bind(fnTool);
|
|
67
|
+
const bridgeApproval = options?.bridgeNeedsApproval === true;
|
|
68
|
+
return {
|
|
69
|
+
...fnTool,
|
|
70
|
+
inputGuardrails: [...(fnTool.inputGuardrails ?? []), paybondGuardrail],
|
|
71
|
+
needsApproval: bridgeApproval
|
|
72
|
+
? async (runContext, input, callId) => {
|
|
73
|
+
const baseNeedsApproval = typeof fnTool.needsApproval === "function"
|
|
74
|
+
? await fnTool.needsApproval(runContext, input, callId)
|
|
75
|
+
: Boolean(fnTool.needsApproval);
|
|
76
|
+
return baseNeedsApproval || bridgeApproval;
|
|
77
|
+
}
|
|
78
|
+
: fnTool.needsApproval,
|
|
79
|
+
invoke: async (runContext, input, details) => {
|
|
80
|
+
const args = parseToolArguments(input);
|
|
81
|
+
const wrapped = await run.interceptor.wrapExecute({
|
|
82
|
+
toolName: fnTool.name,
|
|
83
|
+
toolCallId: resolveToolCallId(details),
|
|
84
|
+
arguments: args,
|
|
85
|
+
execute: async () => {
|
|
86
|
+
const raw = await originalInvoke(runContext, input, details);
|
|
87
|
+
if (typeof raw === "string") {
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(raw);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return raw;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return raw;
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
const { toolResult } = wrapped;
|
|
99
|
+
if (typeof toolResult === "string") {
|
|
100
|
+
return toolResult;
|
|
101
|
+
}
|
|
102
|
+
if (toolResult === undefined || toolResult === null) {
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
if (typeof toolResult === "object") {
|
|
106
|
+
return JSON.stringify(toolResult);
|
|
107
|
+
}
|
|
108
|
+
return toolResult;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** RunConfig fragment enabling Paybond verify before OpenAI approval interruptions. */
|
|
113
|
+
export const paybondOpenAIAgentsRunConfig = {
|
|
114
|
+
toolExecution: {
|
|
115
|
+
preApprovalInputGuardrails: true,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
/** Translate Paybond middleware into OpenAI Agents SDK tool input guardrails. */
|
|
119
|
+
export function createOpenAIAgentsAdapter(run, options) {
|
|
120
|
+
const guard = createToolInputGuardAdapter(run);
|
|
121
|
+
return {
|
|
122
|
+
name: "openai-agents",
|
|
123
|
+
evaluate: guard.evaluate.bind(guard),
|
|
124
|
+
wrapExecutors: guard.wrapExecutors.bind(guard),
|
|
125
|
+
runConfig: paybondOpenAIAgentsRunConfig,
|
|
126
|
+
inputGuardrailFor(toolName) {
|
|
127
|
+
return buildPaybondInputGuardrail(run, toolName);
|
|
128
|
+
},
|
|
129
|
+
guardFunctionTools(tools) {
|
|
130
|
+
return tools.map((tool) => guardFunctionTool(run, tool, options));
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** Convenience alias for {@link createOpenAIAgentsAdapter}. */
|
|
135
|
+
export function paybondOpenAIAgentsAdapter(run, options) {
|
|
136
|
+
return createOpenAIAgentsAdapter(run, options);
|
|
137
|
+
}
|
|
138
|
+
export { runOpenAIAgentsSandboxDemo, } from "./sandbox-demo.js";
|
|
139
|
+
/**
|
|
140
|
+
* Framework runner helper for OpenAI Agents SDK `Runner.run`.
|
|
141
|
+
*
|
|
142
|
+
* Returns guarded function tools and the `runConfig` fragment that enables
|
|
143
|
+
* Paybond verify before approval interruptions.
|
|
144
|
+
*/
|
|
145
|
+
export function createPaybondOpenAIAgentsConfig(run, tools, options) {
|
|
146
|
+
const adapter = createOpenAIAgentsAdapter(run, options);
|
|
147
|
+
return {
|
|
148
|
+
tools: adapter.guardFunctionTools(tools),
|
|
149
|
+
runConfig: adapter.runConfig,
|
|
150
|
+
};
|
|
151
|
+
}
|