@haven_ai/mcp 0.7.0-alpha.0 → 0.8.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/dist/cli.cjs +145 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +146 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +145 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +145 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/credentials.ts","../src/signer-compat.ts","../src/tools.ts","../src/consent.ts","../src/server.ts"],"names":["sharedDescriptions","readFile","HavenClient"],"mappings":"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","file":"index.js","sourcesContent":["import { readFile, stat } from 'node:fs/promises'\n\nexport interface HavenCredentialFile {\n apiKey: string\n delegateKey: string\n agentId?: string\n /** The Haven account (smart account) the agent spends from. */\n accountAddress?: string\n delegateAddress?: string\n chainId?: number\n network?: string\n apiUrl?: string\n allowanceSummary?: readonly HavenCredentialAllowance[]\n /**\n * Absolute path the credentials were loaded from, if any. Set when the\n * caller pointed at a JSON file via `--credentials` or `HAVEN_CREDENTIALS`;\n * left undefined when credentials came purely from environment variables.\n * The MCP server uses this to locate the consent sidecar\n * (`<sourcePath>.ack.json`) so `--ack` works regardless of how the\n * credential path was supplied.\n */\n sourcePath?: string\n identityPath?: string\n signerPath?: string\n}\n\nexport interface HavenCredentialAllowance {\n token: string\n amount: string\n resetMinutes: number | null\n}\n\nexport interface HavenCredentialSource {\n credentialsPath?: string\n identityPath?: string\n signerPath?: string\n}\n\ninterface RawCredentialFile {\n api_key?: unknown\n apiKey?: unknown\n delegate_key?: unknown\n delegateKey?: unknown\n delegate_address?: unknown\n delegateAddress?: unknown\n agent_id?: unknown\n agentId?: unknown\n /** #2908: what `@haven_ai/connect` writes from this release on. */\n account_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */\n safe_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */\n safeAddress?: unknown\n chain_id?: unknown\n chainId?: unknown\n network?: unknown\n api_url?: unknown\n apiUrl?: unknown\n hosted_mcp_url?: unknown\n hostedMcpUrl?: unknown\n allowance_summary?: unknown\n allowanceSummary?: unknown\n agent_budget?: unknown\n agentBudget?: unknown\n}\n\n/**\n * Load Haven agent credentials for the MCP server.\n *\n * Resolution order — earlier sources win, later sources are fallbacks:\n *\n * 1. Explicit `path` argument (typically from `--credentials <path>`).\n * 2. `HAVEN_CREDENTIALS` env var pointing at a credential JSON file.\n * 3. Inline env vars: `HAVEN_API_KEY` + `HAVEN_DELEGATE_KEY` (+ optional\n * `HAVEN_AGENT_ID`, `HAVEN_ACCOUNT_ADDRESS` and `HAVEN_API_URL`). The\n * pre-#2908 spellings `HAVEN_WALLET_ADDRESS` / `HAVEN_SAFE_ADDRESS` are\n * retired as of #2914.\n *\n * The inline-env path exists so that runtime config snippets emitted by the\n * Haven dashboard (Claude Desktop / Cursor / generic MCP configs) can be a\n * single self-contained block — paste the snippet, restart the runtime, done.\n * The values still live only in the agent operator's process environment;\n * Haven's backend never sees the delegate key either way.\n */\nexport async function loadCredentials(\n source: string | HavenCredentialSource | undefined = process.env.HAVEN_CREDENTIALS,\n): Promise<HavenCredentialFile> {\n if (typeof source === 'string') {\n return loadCredentialsFromFile(source)\n }\n if (source?.credentialsPath) {\n return loadCredentialsFromFile(source.credentialsPath)\n }\n if (source?.identityPath || source?.signerPath) {\n if (!source.identityPath || !source.signerPath) {\n throw new Error('Haven split credentials require both --identity and --signer paths.')\n }\n return loadCredentialsFromSplitFiles(source.identityPath, source.signerPath)\n }\n\n const envCreds = loadCredentialsFromEnv()\n if (envCreds) return envCreds\n\n throw new Error(\n 'No Haven credentials found. Set HAVEN_CREDENTIALS to a Haven agent credential JSON file, ' +\n 'pass --credentials <path>, or set HAVEN_API_KEY and HAVEN_DELEGATE_KEY environment variables.',\n )\n}\n\nasync function loadCredentialsFromFile(path: string): Promise<HavenCredentialFile> {\n let rawText: string\n try {\n rawText = await readFile(path, 'utf8')\n } catch (err) {\n throw new Error(`Could not read Haven credentials at ${path}: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n await warnIfCredentialFilePermissive(path)\n\n let raw: RawCredentialFile\n try {\n raw = JSON.parse(rawText) as RawCredentialFile\n } catch {\n throw new Error('Haven credentials must be JSON with api_key and delegate_key fields.')\n }\n\n const apiKey = stringField(raw.api_key ?? raw.apiKey)\n const delegateKey = stringField(raw.delegate_key ?? raw.delegateKey)\n\n if (!apiKey) {\n throw new Error('Haven credentials are missing api_key.')\n }\n if (!delegateKey) {\n throw new Error('Haven MCP requires delegate_key so payments can be signed locally.')\n }\n\n const accountAddress = readAccountAddressField(raw)\n return {\n apiKey,\n delegateKey,\n agentId: stringField(raw.agent_id ?? raw.agentId),\n accountAddress,\n delegateAddress: stringField(raw.delegate_address ?? raw.delegateAddress),\n chainId: numberField(raw.chain_id ?? raw.chainId),\n network: stringField(raw.network),\n apiUrl: stringField(raw.api_url ?? raw.apiUrl),\n allowanceSummary: allowanceSummaryField(raw.allowance_summary ?? raw.allowanceSummary ?? raw.agent_budget ?? raw.agentBudget),\n sourcePath: path,\n }\n}\n\nasync function loadCredentialsFromSplitFiles(identityPath: string, signerPath: string): Promise<HavenCredentialFile> {\n const identity = await readJsonFile(identityPath, 'Haven identity credentials')\n const signer = await readJsonFile(signerPath, 'Haven signer credentials')\n\n await warnIfCredentialFilePermissive(identityPath)\n await warnIfCredentialFilePermissive(signerPath)\n\n const apiKey = stringField(identity.api_key ?? identity.apiKey)\n const delegateKey = stringField(signer.delegate_key ?? signer.delegateKey)\n\n if (!apiKey) {\n throw new Error('Haven identity credentials are missing api_key.')\n }\n if (!delegateKey) {\n throw new Error('Haven signer credentials are missing delegate_key.')\n }\n\n return {\n apiKey,\n delegateKey,\n agentId: matchingStringField(\n 'agent_id',\n identity.agent_id ?? identity.agentId,\n signer.agent_id ?? signer.agentId,\n ),\n accountAddress: matchingStringField(\n 'account_address',\n readAccountAddressField(identity),\n readAccountAddressField(signer),\n { caseInsensitive: true },\n ),\n delegateAddress: matchingStringField(\n 'delegate_address',\n signer.delegate_address ?? signer.delegateAddress,\n identity.delegate_address ?? identity.delegateAddress,\n { caseInsensitive: true },\n ),\n chainId: matchingNumberField(\n 'chain_id',\n identity.chain_id ?? identity.chainId,\n signer.chain_id ?? signer.chainId,\n ),\n network: matchingStringField(\n 'network',\n identity.network,\n signer.network,\n { caseInsensitive: true },\n ),\n apiUrl: stringField(identity.api_url ?? identity.apiUrl),\n allowanceSummary: allowanceSummaryField(\n identity.allowance_summary ??\n identity.allowanceSummary ??\n identity.agent_budget ??\n identity.agentBudget,\n ),\n sourcePath: identityPath,\n identityPath,\n signerPath,\n }\n}\n\nasync function readJsonFile(path: string, label: string): Promise<RawCredentialFile> {\n let rawText: string\n try {\n rawText = await readFile(path, 'utf8')\n } catch (err) {\n throw new Error(`Could not read ${label} at ${path}: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n try {\n return JSON.parse(rawText) as RawCredentialFile\n } catch {\n throw new Error(`${label} must be JSON.`)\n }\n}\n\nfunction loadCredentialsFromEnv(): HavenCredentialFile | null {\n const apiKey = stringField(process.env.HAVEN_API_KEY)\n const delegateKey = stringField(process.env.HAVEN_DELEGATE_KEY)\n\n if (!apiKey && !delegateKey) return null\n\n if (!apiKey) {\n throw new Error('HAVEN_DELEGATE_KEY is set but HAVEN_API_KEY is missing.')\n }\n if (!delegateKey) {\n throw new Error('HAVEN_API_KEY is set but HAVEN_DELEGATE_KEY is missing. Haven MCP requires a delegate key so payments can be signed locally.')\n }\n\n return {\n apiKey,\n delegateKey,\n agentId: stringField(process.env.HAVEN_AGENT_ID),\n accountAddress: readAccountAddressEnv(process.env),\n chainId: numberField(process.env.HAVEN_CHAIN_ID),\n network: stringField(process.env.HAVEN_NETWORK),\n apiUrl: stringField(process.env.HAVEN_API_URL),\n }\n}\n\n/**\n * The account address off a credential FILE: `account_address` (what\n * `@haven_ai/connect` writes from #2908 on) first, then the two pre-#2908\n * spellings.\n *\n * The two old fallbacks are PERMANENT (#2906, decision 2a) — a credential\n * file on disk never rewrites itself, and a runtime that stopped reading\n * `safe_address` would silently lose the address (and change the consent\n * hash) for every agent connected before this release.\n *\n * Exported for the mutation tests: dropping `account_address` fails the\n * new-shape test, dropping either old key fails the old-shape test.\n */\nexport function readAccountAddressField(\n raw: Pick<RawCredentialFile, 'account_address' | 'safe_address' | 'safeAddress'>,\n): string | undefined {\n return stringField(raw.account_address ?? raw.safe_address ?? raw.safeAddress)\n}\n\n/**\n * The account address off the environment: `HAVEN_ACCOUNT_ADDRESS` (the\n * survivor, decided on #2906). The two names the dashboard handoff emitted\n * before #2908 — `HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` — were\n * window-scoped and are retired as of #2914.\n */\nexport function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefined {\n const current = stringField(env.HAVEN_ACCOUNT_ADDRESS)\n\n // Retired, but REFUSED rather than ignored — the same rule the backend\n // applies to retired request names, for the same reason and with more at\n // stake. Silently dropping these would not merely leave the address unset:\n // `accountAddress` is what `haven_sign_sweep_delegate` passes as\n // `expectedSafe`, and an undefined `expectedSafe` SKIPS the check that a\n // sweep's `to` matches the account in the local credential (see\n // `core.ts`). An operator who upgrades without touching env would lose a\n // money-path cross-check and get no signal at all.\n //\n // The verdict keys on RELIANCE, not presence, so a handoff that still\n // exports both names alongside the new one keeps working:\n // retired alone -> throw\n // both, same value -> accept the new one\n // both, disagreeing -> throw\n for (const name of ['HAVEN_WALLET_ADDRESS', 'HAVEN_SAFE_ADDRESS'] as const) {\n const retired = stringField(env[name])\n if (!retired) continue\n if (!current) {\n throw new Error(\n `${name} is retired (#2906) — Haven accounts are addressed as accounts, not Safes. ` +\n 'Set HAVEN_ACCOUNT_ADDRESS to the same value. Refusing rather than ignoring it, ' +\n 'because an unset account address silently skips the sweep-destination check.',\n )\n }\n if (retired.toLowerCase() !== current.toLowerCase()) {\n throw new Error(\n `${name} and HAVEN_ACCOUNT_ADDRESS were both set to different addresses. ` +\n 'Remove the retired name, or make them match — picking one silently would hide ' +\n 'the mismatch.',\n )\n }\n }\n\n return current\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction numberField(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim() && /^\\d+$/.test(value.trim())) return Number(value.trim())\n return undefined\n}\n\nfunction matchingStringField(\n label: string,\n preferred: unknown,\n fallback: unknown,\n options: { caseInsensitive?: boolean } = {},\n): string | undefined {\n const preferredValue = stringField(preferred)\n const fallbackValue = stringField(fallback)\n if (\n preferredValue &&\n fallbackValue &&\n !sameCredentialValue(preferredValue, fallbackValue, options.caseInsensitive)\n ) {\n throw mismatchedSplitCredentialError(label)\n }\n return preferredValue ?? fallbackValue\n}\n\nfunction matchingNumberField(label: string, preferred: unknown, fallback: unknown): number | undefined {\n const preferredValue = numberField(preferred)\n const fallbackValue = numberField(fallback)\n if (preferredValue !== undefined && fallbackValue !== undefined && preferredValue !== fallbackValue) {\n throw mismatchedSplitCredentialError(label)\n }\n return preferredValue ?? fallbackValue\n}\n\nfunction sameCredentialValue(first: string, second: string, caseInsensitive = false): boolean {\n return caseInsensitive ? first.toLowerCase() === second.toLowerCase() : first === second\n}\n\nfunction mismatchedSplitCredentialError(label: string): Error {\n return new Error(\n `Haven split credentials have mismatched ${label} values. ` +\n 'Recreate the identity and signer credential files from the same Haven agent.',\n )\n}\n\nfunction allowanceSummaryField(value: unknown): HavenCredentialAllowance[] | undefined {\n if (!Array.isArray(value)) return undefined\n const allowances = value.flatMap((item) => {\n if (!item || typeof item !== 'object') return []\n const raw = item as Record<string, unknown>\n const token = stringField(raw.token ?? raw.token_symbol ?? raw.tokenSymbol)\n const amount = stringField(raw.amount ?? raw.allowance_amount ?? raw.allowanceAmount)\n const reset = raw.resetMinutes ?? raw.reset_minutes ?? raw.reset_period_min ?? raw.resetPeriodMin\n if (!token || !amount) return []\n return [{\n token,\n amount,\n resetMinutes: reset === null ? null : numberField(reset) ?? null,\n }]\n })\n return allowances.length > 0 ? allowances : undefined\n}\n\n/**\n * Warn (but do not block) when the credential file is readable by users\n * other than the owner. The check is best-effort: it only runs on POSIX\n * filesystems where the stat mode bits map cleanly. Windows ACLs require\n * `icacls`-style introspection that doesn't fit a single stat call, so we\n * skip the check there and the dashboard handoff text guides the user\n * separately.\n *\n * Exported for testing.\n */\nexport async function warnIfCredentialFilePermissive(\n path: string,\n log: (message: string) => void = (message) => process.stderr.write(`${message}\\n`),\n platform: NodeJS.Platform = process.platform,\n): Promise<void> {\n if (platform === 'win32') return\n\n let mode: number\n try {\n const stats = await stat(path)\n mode = stats.mode\n } catch {\n // The credential read already failed cleanly above if the file is\n // unreadable. A stat failure here is not worth blocking on.\n return\n }\n\n const groupOrOther = mode & 0o077\n if (groupOrOther !== 0) {\n const octal = (mode & 0o777).toString(8).padStart(4, '0')\n log(\n `haven-mcp: warning: credential file at ${path} is readable beyond the owner ` +\n `(mode ${octal}). Run: chmod 600 ${path}`,\n )\n }\n}\n","/**\n * #3419: the task-budget old-signer recovery notice, LOCAL surface.\n *\n * The hosted builder of the same name lives in\n * `packages/mcp-server/src/tools/support/signer-compat.ts`; this package\n * cannot import it (no dependency on the hosted package — they are separate\n * runtimes, and a runtime dependency the other way would drag the hosted\n * server's connector channel into every local install), so the shape is\n * duplicated here ON PURPOSE and pinned identical by two tests:\n * `packages/mcp/src/task-budgets.test.ts` (fields present on the local\n * handoffs) and `packages/mcp-server/src/hosted-signer-integration.test.ts`\n * (hosted and local builders agree field-for-field, from the same SDK\n * constant).\n *\n * The SINGLE SOURCES are shared, not copied: `TASK_SIGN_CONTEXT_VERSION`\n * comes from `@haven_ai/sdk` (the same constant the backend emits and the\n * signer's `SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS` derives from), and the\n * recovery route is built from the same `connectorUpgradeCommand()` the\n * signer's own update hints use. What is pinned to `'0.6.0-alpha.0'` here is\n * the same ONE fact the hosted constant pins: the first `@haven_ai/signer`\n * release whose `haven_sign` accepts the `task_budget_id` argument form\n * (#3329) — `client-releases.data.ts` is the record, and the hosted\n * package's `TASK_BUDGET_MIN_SIGNER_VERSION` (the exported constant the\n * cross-package pin ties to it) carries the identical value.\n *\n * Like the hosted notice this is ADVISORY DATA on the handoff result, never a\n * gate: the local runtime cannot see the signer either, and the signer keeps\n * enforcing its own versions at the sign-context fetch.\n */\nimport { TASK_SIGN_CONTEXT_VERSION, connectorUpgradeCommand } from '@haven_ai/sdk'\n\n/**\n * The first `@haven_ai/signer` release whose `haven_sign` accepts the\n * `task_budget_id` argument form (#3329). ONE constant on this surface, with\n * exactly one job: the value `signer_compatibility.min_signer_version`\n * reports on the two task-budget handoffs below. The hosted package exports\n * `TASK_BUDGET_MIN_SIGNER_VERSION` with the same value, tied to the same\n * release record (`client-releases.data.ts`) by its cross-package pin.\n */\nexport const TASK_BUDGET_MIN_SIGNER_VERSION = '0.6.0-alpha.0'\n\n/** The capability key both runtimes report in `signer_compatibility.signer_capability`. */\nexport const SIGNER_CAPABILITY_KEY = 'haven/signer-compatibility'\n\n/**\n * The recovery notice every result that hands off to\n * `haven_sign { task_budget_id }` carries — the local twin of the hosted\n * `taskSignerCompatibilityNotice()`. Field-for-field the same shape:\n *\n * - `task_sign_context_version` — from the SDK's single source;\n * - `min_signer_version` — the constant above;\n * - `signer_capability` — the existing capability key;\n * - `check` / `fallback` — the recovery sentence as prose and as data: the\n * trigger substring (the generic refusal every pre-0.6.0 signer answers,\n * both historic lines begin with it), then close the pending budget, update\n * via the connector doctor and its printed repair line, reopen. No relay\n * fallback exists for this signing context (an `eip712_delegation` payload\n * the 0.5.x unbound allowlist refuses and a 0.4.x signer must not be\n * steered into), so none is named.\n */\nexport function taskSignerCompatibilityNotice() {\n return {\n task_sign_context_version: TASK_SIGN_CONTEXT_VERSION,\n min_signer_version: TASK_BUDGET_MIN_SIGNER_VERSION,\n signer_capability: SIGNER_CAPABILITY_KEY,\n check:\n 'Call next_tool with next_arguments EXACTLY as given — the signer fetches the exact bytes ' +\n 'by task_budget_id. If haven_sign answers SIGNING_ERROR with a message starting \"Pass ' +\n \"payment_id (preferred for delegation-rail x402\\\", the signer predates task budgets and signed \" +\n 'nothing: first close this budget with haven_close_task_budget { task_budget_id } to release ' +\n `it, then update the connector by running \\`${connectorUpgradeCommand()}\\` and the repair ` +\n 'line it prints, then open the budget again.',\n fallback:\n 'haven_sign answered SIGNING_ERROR with a message starting \"Pass payment_id (preferred for ' +\n 'delegation-rail x402\" — the signer predates task budgets and signed nothing: call ' +\n 'haven_close_task_budget { task_budget_id } to release the pending budget, then update the ' +\n `connector by running \\`${connectorUpgradeCommand()}\\` and the repair line it prints, ` +\n 'then open the budget again. There is no relay fallback for this signing context.',\n }\n}\n","/**\n * Local (stdio) MCP tool handlers. This package runs in the AGENT OPERATOR'S\n * OWN environment — it reads the local credential file and signs locally; the\n * hosted backend is not in the loop for the merchant call. So `merchant_url`\n * passed to `haven.fetch` below is NOT an SSRF surface: the agent is the\n * principal paying a merchant IT chose, on its own machine — the same trust\n * position as running `curl`. There is no server reflecting attacker input\n * into an internal request. (Hosted, multi-tenant fetches live in mcp-server,\n * which is where URL-hardening would matter.)\n */\nimport {\n AgentPaymentFailureCode,\n AgentPaymentNextAction,\n HavenApiError,\n HavenClient,\n HavenError,\n HavenPaymentStateError,\n HavenSigningError,\n composeDescription,\n discoverMerchantMcpUrl,\n resolveTokenFromAddress,\n sameUrl,\n toolDescriptions as sharedDescriptions,\n verifyPaymentReceipt,\n type HavenClientUpdate,\n type PaymentReceipt,\n type X402Quote,\n type X402ResumeState,\n} from '@haven_ai/sdk'\nimport { taskSignerCompatibilityNotice } from './signer-compat.js'\nimport { z } from 'zod/v3'\n\nconst headersSchema = z.record(z.string(), z.string()).optional()\n\nexport type HavenMcpToolName =\n | 'haven_send'\n | 'haven_pay_mcp_tool'\n | 'haven_quote_x402'\n | 'haven_pay_x402_quote'\n | 'haven_pay_x402'\n | 'haven_resume_x402_payment'\n | 'haven_get_payment_status'\n | 'haven_get_resume_state'\n | 'haven_get_agent'\n | 'haven_get_allowances'\n | 'haven_list_receipts'\n | 'haven_verify_receipt'\n | 'haven_sweep_delegate'\n | 'haven_discover_tools'\n | 'haven_submit_catalog_entry'\n | 'haven_open_task_budget'\n | 'haven_close_task_budget'\n | 'haven_submit'\n\n/**\n * #3100 (epic #3105, decision 4): the structured hint on a local discovery\n * entry — a pay tool with arguments it accepts VERBATIM, or the reason no\n * verbatim hint exists for the row (decision 3's omitted-plus-reason shape).\n */\nexport type DiscoveryHint =\n | {\n suggested_tool: 'haven_pay_mcp_tool'\n suggested_arguments: { merchant_url: string; tool_name: string; arguments?: Record<string, unknown> }\n }\n | { suggested_tool: 'haven_pay_x402'; suggested_arguments: { url: string } }\n | { suggested_tool_omitted_reason: string }\n\n/** One `haven_discover_tools` entry on the local surface (wire-shaped). */\nexport type DiscoveryEntry = {\n id: string\n name: string\n description: string | null\n category: string | null\n resource_url: string\n rail: string\n protocol: string\n tool_name: string | null\n tool_arguments: Record<string, unknown> | null\n price_display: string | null\n price_atomic: string | null\n asset: string | null\n network: string | null\n status: string\n verified_at: string | null\n source?: string\n domain_verified?: boolean\n verified_payable?: boolean\n} & DiscoveryHint\n\nexport const toolSchemas = {\n haven_send: {\n asset: z.enum(['ETH', 'USDC']),\n recipient: z.string().min(1),\n amount: z.string().min(1),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n /** #3329: spend against an open task budget instead of the agent's period budget. */\n task_budget_id: z.string().min(1).optional(),\n /**\n * #3330: spend against an open sub-budget this agent HOLDS (it is the\n * sub-agent B) instead of the agent's own budget. Mutually exclusive\n * with task_budget_id — the backend refuses a body naming both.\n */\n sub_budget_id: z.string().min(1).optional(),\n },\n haven_pay_mcp_tool: {\n merchant_url: z.string().url(),\n tool_name: z.string().min(1),\n arguments: z.record(z.string(), z.unknown()).optional(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n },\n haven_quote_x402: {\n url: z.string().url(),\n method: z.string().optional(),\n headers: headersSchema,\n body: z.string().optional(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n },\n haven_pay_x402_quote: {\n quote: z.unknown(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n /** #3329: spend against an open task budget instead of the agent's period budget. */\n task_budget_id: z.string().min(1).optional(),\n /** #3330: spend against an open sub-budget this agent holds (it is sub-agent B). Mutually exclusive with task_budget_id. */\n sub_budget_id: z.string().min(1).optional(),\n },\n haven_pay_x402: {\n url: z.string().url(),\n method: z.string().optional(),\n headers: headersSchema,\n body: z.string().optional(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n /** #3329: spend against an open task budget instead of the agent's period budget. */\n task_budget_id: z.string().min(1).optional(),\n /** #3330: spend against an open sub-budget this agent holds (it is sub-agent B). Mutually exclusive with task_budget_id. */\n sub_budget_id: z.string().min(1).optional(),\n },\n haven_resume_x402_payment: {\n payment_id: z.string().optional(),\n resume_state: z.unknown().optional(),\n },\n haven_get_payment_status: {\n payment_id: z.string(),\n },\n haven_get_resume_state: {\n payment_id: z.string(),\n },\n haven_get_agent: {},\n haven_get_allowances: {},\n haven_sweep_delegate: {},\n haven_discover_tools: {\n category: z.string().optional(),\n search: z.string().optional(),\n rail: z.enum(['x402', 'mpp']).optional(),\n verified: z.enum(['any', 'verified', 'operator']).optional(),\n },\n haven_submit_catalog_entry: {\n resource_url: z.string().min(1),\n website: z.string().optional(),\n },\n haven_list_receipts: {\n limit: z.number().int().min(1).max(100).optional(),\n /** #3128: the previous page's next_cursor (a receipt id). */\n cursor: z.string().min(1).optional(),\n /** #3423: drop each row's payload echoes; the default shape is unchanged. */\n compact: z\n .boolean()\n .optional()\n .describe('true drops challengePayload, selectedPayment and protocolReceiptPayload from each row; omit for the full row.'),\n },\n haven_verify_receipt: {\n receipt: z.unknown(),\n },\n // #3329: a budget for one task that ends by itself — a short-lived child of\n // the agent's own budget, capped and time-boxed independently of the period\n // reset.\n haven_open_task_budget: {\n max_amount_human: z.string().min(1),\n ttl_minutes: z.number().int().min(1).max(1440),\n recipient: z.string().optional(),\n label: z.string().max(120).optional(),\n token: z.string().optional(),\n },\n haven_close_task_budget: {\n task_budget_id: z.string().min(1),\n },\n // #3329: relays a signature from the local signer — either the open/close\n // signature for a task budget, or (schema parity with the hosted surface)\n // a direct-payment signature by payment_id. Exactly one of task_budget_id /\n // payment_id, never both or neither.\n haven_submit: {\n task_budget_id: z.string().min(1).optional(),\n payment_id: z.string().min(1).optional(),\n signature: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'signature must be a 0x-prefixed hex string'),\n },\n// #3101: keys survive on the type (see the hosted server's contracts.ts).\n} as const satisfies Record<HavenMcpToolName, z.ZodRawShape>\n\n// #3329: outcome language only — never \"delegation\", \"caveat\" or \"UserOp\".\nconst OPEN_TASK_BUDGET_DESCRIPTION = [\n 'Open a budget for one task that ends by itself: a spending cap, good for at most ttl_minutes,',\n 'reserved out of the agent\\'s own budget and separate from its period reset.',\n 'Pass max_amount_human (whole tokens, e.g. \"5\" for 5 USDC), ttl_minutes (1-1440), and optionally',\n 'recipient (pins every payment against this task budget to one address), label, and token',\n '(defaults to USDC). Returns { task_budget, next_action: \"sign\", next_tool, next_arguments } —',\n 'call next_tool with next_arguments EXACTLY as given to get a signature, then relay it with',\n 'haven_submit. Spending anything above the reserved amount, past the deadline, or to a',\n 'different recipient than the one pinned here is declined on the spot — nothing is queued.',\n 'A recipient pin is checked against where each payment first goes: haven_pay_x402 and',\n 'haven_pay_x402_quote first move funds into the agent\\'s own wallet, so a budget pinned to a',\n 'merchant is declined there — pin only budgets meant for haven_send.',\n].join(' ')\n\nconst CLOSE_TASK_BUDGET_DESCRIPTION = [\n 'End a task budget early, before its deadline, releasing whatever of its cap was unspent back',\n 'to the agent\\'s own budget. Pass task_budget_id. If the budget was never signed (still pending),',\n 'this ends it immediately with { task_budget, status: \"closed\" } and nothing was ever reserved',\n 'on-chain. Otherwise it returns a signature request: { task_budget, next_action: \"sign\",',\n 'next_tool, next_arguments } — call next_tool with next_arguments EXACTLY as given, then relay',\n 'the signature with haven_submit. A task budget past its own deadline closes immediately, the',\n 'same as the pending case.',\n].join(' ')\n\nconst SUBMIT_DESCRIPTION = [\n 'Relay a signature from the local signer. Pass exactly one of task_budget_id (from',\n 'haven_open_task_budget or haven_close_task_budget) or payment_id — never both, never neither —',\n 'plus signature. For a task budget this opens or closes it on-chain and returns { task_budget,',\n 'status }; a close in progress may return { task_budget, status: \"closed\", close_tx_hash }.',\n].join(' ')\n\n/**\n * MCP tool descriptions, composed from the shared semantic source in\n * `@haven_ai/sdk`'s `tool-descriptions.ts`. Keeping both the SDK tool-calling\n * surface and the MCP surface pointed at the same prose source means new\n * guidance lands in both places at once and a parity test can catch drift.\n */\nexport const toolDescriptions: Record<HavenMcpToolName, string> = {\n haven_send: composeDescription(sharedDescriptions.send),\n haven_pay_mcp_tool: composeDescription(sharedDescriptions.payMcpTool),\n haven_quote_x402: composeDescription(sharedDescriptions.quoteX402),\n haven_pay_x402_quote: composeDescription(sharedDescriptions.payX402),\n haven_pay_x402: composeDescription(sharedDescriptions.payX402OneShot),\n haven_resume_x402_payment: composeDescription(sharedDescriptions.resumeX402),\n haven_get_payment_status: composeDescription(sharedDescriptions.getPaymentStatus),\n haven_get_resume_state: composeDescription(sharedDescriptions.getResumeState),\n haven_get_agent: composeDescription(sharedDescriptions.getAgent),\n haven_get_allowances: composeDescription(sharedDescriptions.getAllowances),\n haven_sweep_delegate: composeDescription(sharedDescriptions.sweep_delegate),\n haven_discover_tools: composeDescription(sharedDescriptions.discoverTools),\n haven_submit_catalog_entry: composeDescription(sharedDescriptions.submitCatalogEntry),\n haven_list_receipts: composeDescription(sharedDescriptions.listReceipts),\n haven_verify_receipt: composeDescription(sharedDescriptions.verifyReceipt),\n haven_open_task_budget: OPEN_TASK_BUDGET_DESCRIPTION,\n haven_close_task_budget: CLOSE_TASK_BUDGET_DESCRIPTION,\n haven_submit: SUBMIT_DESCRIPTION,\n}\n\nexport interface ToolSuccess<T> {\n success: true\n data: T\n /**\n * Non-fatal notices about the CALL, not about its result (#2366).\n *\n * Additive and optional: a caller that ignores it sees exactly what it saw\n * before. It exists so a deprecation can be announced on the surface that\n * observes it — the alternative was a divergence nothing ever told anyone to\n * leave, which is how `idempotencyKey` survived #2312 and #2348.\n */\n warnings?: string[]\n /**\n * #3303: the backend's `client_update` hint when this package is behind the\n * version the deployment recommends (`required: false`) or below its\n * minimum (`required: true`). `upgrade_command` starts the update: for the\n * connector-installed packages it is the connector doctor, which prints the\n * repair line to run next (#3412).\n */\n client_update?: HavenClientUpdate\n}\n\nexport interface ToolFailure {\n success: false\n code: string\n message: string\n /** Structured hint pointing the agent at the correct tool for this operation. */\n suggested_tool?: string\n statusCode?: number\n paymentId?: string\n status?: string\n phase?: string\n /**\n * @deprecated since #3103 — read `next_action`. Kept with the same value for\n * one release (the #2908 pattern) and removed in the release after the one\n * carrying #3103.\n */\n nextAction?: string\n /**\n * #3103 (epic #3105, decision 10): the same value as `nextAction`, spelled\n * the way the hosted server and the signer spell it. Dual-emitted for one\n * release (the #2908 pattern) before `nextAction` is dropped.\n */\n next_action?: string\n /** #3101 (epic #3105, decision 7): the typed next-step family, additive; `next_tool` never null. */\n next_tool?: string\n next_tool_server?: string\n next_tool_name?: string\n next_tool_server_role?: 'hosted' | 'signer'\n next_arguments?: Record<string, unknown>\n next_tool_omitted_reason?: string\n resume_state?: unknown\n body?: unknown\n /**\n * #2983: carried on `MERCHANT_NOT_READY` — mirrors the hosted MCP's\n * `retry_with_new_quote` (`mcp-context.ts`'s `merchantNotReadyErrorFor`).\n * Genuinely retryable: nothing about the CALL was wrong, the merchant's\n * own wallet needs to recover first.\n */\n retry_with_new_quote?: boolean\n /** #3303: as on {@link ToolSuccess}; on a 426 `client_outdated` refusal it is always `required: true`. */\n client_update?: HavenClientUpdate\n}\n\nexport type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure\n\nexport function createToolHandlers(haven: HavenClient): Record<HavenMcpToolName, (input: unknown) => Promise<ToolPayload>> {\n return {\n haven_send: async (input) => {\n // #2366/#3411: resolved OUTSIDE the payload so any `preflight` warning\n // can ride on the success, and BEFORE anything is contacted so a legacy\n // `idempotencyKey` refuses without spending.\n const pf = preflight('haven_send', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n return runTool(async () => {\n try {\n const result = await haven.pay({\n token: args.asset,\n amount: args.amount,\n to: args.recipient,\n // #1207/#3411: was accepted by the schema but silently dropped — now\n // carried to the backend's replay contract via the resolved carrier.\n idempotencyKey: args.resolvedIdempotencyKey,\n // #3329: spend against an open task budget instead of the\n // agent's period budget, when the caller names one.\n ...(typeof args.task_budget_id === 'string' ? { taskBudgetId: args.task_budget_id } : {}),\n // #3330: spend through a sub-budget this agent holds (it is\n // sub-agent B). Exactly one of the two ids, never both.\n ...(typeof args.sub_budget_id === 'string' ? { subBudgetId: args.sub_budget_id } : {}),\n })\n return {\n payment_id: result.paymentId,\n status: result.status,\n tx_hash: result.txHash ?? null,\n asset: args.asset,\n amount: args.amount,\n recipient: args.recipient,\n }\n } catch (err) {\n if (err instanceof HavenPaymentStateError && isPendingApproval(err.status)) {\n // #2101: retained fail-closed (see `isPendingApproval` below), but it\n // used to return a bare status string whose only explanation lived in\n // MCP_INSTRUCTIONS' now-deleted \"pending_approval means stop\" line.\n // Carry the verdict IN BAND rather than leaning on the general\n // unrecognised-status rule: this branch is the one place a model can\n // still meet the status, and it must not read as \"poll and wait\".\n return {\n payment_id: err.paymentId,\n status: 'pending_approval',\n next_action: 'stop_and_tell_user',\n message:\n 'This payment is not payable and nothing is queued for anyone to approve — ' +\n 'stop and tell the user, then ask the wallet owner to grant or raise the ' +\n 'agent budget in Haven. Do not retry, re-sign, or poll.',\n asset: args.asset,\n amount: args.amount,\n recipient: args.recipient,\n }\n }\n throw err\n }\n }, warnings)\n },\n\n haven_pay_mcp_tool: async (input) => {\n // #2366: hoisted out of `runTool` so a refusal is a refusal rather than\n // a success carrying one as its payload. (`warnings` no longer fires for\n // idempotency-key spelling since #3411 — the legacy spelling is refused,\n // not warned on — but the field stays hoisted here for any future\n // non-fatal notice `preflight` needs to attach to a success.)\n const pf = preflight('haven_pay_mcp_tool', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n return runTool(async () => {\n const envelope = buildMcpToolsCallEnvelope(args.tool_name as string, args.arguments as Record<string, unknown> | undefined)\n const init: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(envelope),\n }\n // #1301: a base merchant URL is accepted, mirroring the hosted MCP's\n // #1271 discovery. `haven.fetch()` already resolves a 402 itself\n // (pays and retries) — it never hands a 402 back to us, and a\n // successfully-paid retry that the merchant rejects THROWS from\n // inside the SDK rather than returning a non-ok Response (see\n // `retryX402Request`). So any Response this call returns with\n // `.ok === false` can only be the UNTOUCHED first-hop response to a\n // URL that never spoke 402 at all — free-tool 200s and paid 200s\n // both stay `.ok === true` and never reach this branch. That is the\n // local flow's equivalent of the hosted probe's\n // `X402UnexpectedStatusError` (#1300): \"this URL isn't the MCP\n // endpoint,\" expressed as a Response instead of a thrown error.\n let merchantUrl = args.merchant_url as string\n const idempotencyKey = args.resolvedIdempotencyKey\n const attempt = () => haven.fetch(merchantUrl, init, { idempotencyKey })\n\n let response = await attempt()\n if (!response.ok) {\n // #2983: mirror the hosted `merchantNotReadyErrorFor` — an honest,\n // machine-readable merchant refusal is reported as itself, BEFORE\n // the #1301 \"wrong endpoint\" discovery heuristic ever runs. Without\n // this, every local `merchant_not_ready` 503 fell into the\n // discovery path below and came back as \"no discovery document was\n // found\", discarding the merchant's own reason entirely — the same\n // misreport #2979 fixed on the hosted side.\n const notReady = await merchantNotReadyErrorFor(response)\n if (notReady) throw notReady\n const discovered = await discoverMerchantMcpUrl(merchantUrl)\n // Trailing-slash/case echoes of the input are \"same URL\" — spend\n // the one retry only on a genuinely different endpoint.\n if (!discovered || sameUrl(discovered, merchantUrl)) {\n throw discoveryMissError(response, merchantUrl, discovered)\n }\n const inputUrl = merchantUrl\n merchantUrl = discovered\n const retryResponse = await attempt()\n if (!retryResponse.ok) {\n const notReadyAtDiscovered = await merchantNotReadyErrorFor(retryResponse)\n if (notReadyAtDiscovered) throw notReadyAtDiscovered\n // Label which URL failed — the agent otherwise cannot tell the\n // discovered endpoint's miss from the original probe's.\n throw discoveryMissError(retryResponse, merchantUrl, discovered, inputUrl)\n }\n response = retryResponse\n }\n const payload = await responsePayload(response)\n return {\n ...payload,\n // The RESOLVED endpoint (#1271/#1301), not the input as given.\n merchant_url: merchantUrl,\n ...(merchantUrl !== args.merchant_url ? { merchant_url_discovered_from: args.merchant_url } : {}),\n }\n }, warnings)\n },\n\n haven_quote_x402: async (input) => {\n const pf = preflight('haven_quote_x402', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n try {\n const data = await haven.quoteX402(args.url, requestInit(args), { idempotencyKey: args.resolvedIdempotencyKey })\n return warnings.length > 0 ? { success: true, data, warnings } : { success: true, data }\n } catch (err) {\n // #1328: quoteX402 still refuses a MACHINE-PAYMENT-CHALLENGE response as\n // a defensive shape guard, but nothing in Haven produces that header\n // anymore (the mpp_demo route it was built for is retired) — fall\n // through to the generic error rather than suggesting a deleted tool.\n return normalizeError(err)\n }\n },\n\n haven_pay_x402_quote: async (input) => {\n const pf = preflight('haven_pay_x402_quote', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n const quote = args.quote as Record<string, unknown> | null | undefined\n // Guard before network calls so the agent gets actionable guidance rather\n // than an opaque SDK error.\n if (!quote || typeof quote !== 'object') {\n return wrongTool(\n 'WRONG_TOOL',\n 'The quote argument is missing or is not a valid x402 quote object. Call haven_quote_x402 first to obtain a quote, or use haven_pay_x402 to handle the full probe → pay → retry round trip automatically.',\n 'haven_quote_x402',\n )\n }\n if (!quote.paymentRequired) {\n return wrongTool(\n 'WRONG_TOOL',\n 'The quote is missing the required paymentRequired field. Call haven_quote_x402 first to obtain a valid x402 quote.',\n 'haven_quote_x402',\n )\n }\n return runTool(async () => {\n const response = await haven.payX402Quote(args.quote as X402Quote, {\n idempotencyKey: args.resolvedIdempotencyKey,\n ...(typeof args.task_budget_id === 'string' ? { taskBudgetId: args.task_budget_id } : {}),\n ...(typeof args.sub_budget_id === 'string' ? { subBudgetId: args.sub_budget_id } : {}),\n })\n return responsePayload(response)\n }, warnings)\n },\n\n haven_pay_x402: async (input) => {\n const pf = preflight('haven_pay_x402', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n return runTool(async () => {\n const response = await haven.fetch(args.url, requestInit(args), {\n idempotencyKey: args.resolvedIdempotencyKey,\n ...(typeof args.task_budget_id === 'string' ? { taskBudgetId: args.task_budget_id } : {}),\n ...(typeof args.sub_budget_id === 'string' ? { subBudgetId: args.sub_budget_id } : {}),\n })\n return responsePayload(response)\n }, warnings)\n },\n\n haven_resume_x402_payment: async (input) => {\n const args = objectInput('haven_resume_x402_payment', input)\n // #1328: the mpp rail resume_state branch is retired along with\n // haven_resume_mpp_payment — any non-x402 rail is now just a\n // state-mismatch, not a \"use this other tool\" redirect.\n return runTool(async () => {\n const state = await resumeState(args, 'x402')\n const response = await haven.resumeX402Payment(state)\n return responsePayload(response)\n })\n },\n\n haven_get_payment_status: async (input) => {\n const args = objectInput('haven_get_payment_status', input)\n // #1310/#1311: shared with mcp-server's haven_get_payment_status\n // handler — see HavenClient.getPaymentStatusWithPostPurchaseAllowance\n // in @haven_ai/sdk for the single home of this \"settled x402 only\"\n // attach logic (was duplicated verbatim in both packages) and for why\n // `funded_but_unsettled` is excluded from \"settled\".\n return runTool(async () => haven.getPaymentStatusWithPostPurchaseAllowance(args.payment_id))\n },\n\n haven_get_resume_state: async (input) => {\n const args = objectInput('haven_get_resume_state', input)\n return runTool(async () => haven.getResumeState(args.payment_id))\n },\n\n haven_get_agent: async () => runTool(async () => haven.getAgentSummary()),\n haven_get_allowances: async () => runTool(async () => haven.getAllowances()),\n haven_sweep_delegate: async () => runTool(async () => haven.sweepDelegate()),\n haven_discover_tools: async (input) => {\n const args = objectInput('haven_discover_tools', input)\n return runTool(async () => {\n const entries = await haven.discoverTools({\n category: typeof args.category === 'string' ? args.category : undefined,\n search: typeof args.search === 'string' ? args.search : undefined,\n rail: args.rail === 'x402' || args.rail === 'mpp' ? args.rail : undefined,\n verified: args.verified === 'verified' || args.verified === 'operator' ? args.verified : undefined,\n })\n return entries.map((entry): DiscoveryEntry => ({\n id: entry.id,\n name: entry.name,\n description: entry.description,\n category: entry.category,\n resource_url: entry.resourceUrl,\n rail: entry.rail,\n protocol: entry.protocol,\n tool_name: entry.toolName,\n tool_arguments: entry.toolArguments,\n price_display: entry.priceDisplay,\n price_atomic: entry.priceAtomic,\n asset: entry.asset,\n network: entry.network,\n status: entry.status,\n verified_at: entry.verifiedAt,\n source: entry.source,\n domain_verified: entry.domainVerified,\n verified_payable: entry.verifiedPayable,\n // Which Haven pay tool reaches this entry from the local MCP surface,\n // and — #3100 (epic #3105, decision 4) — the arguments that tool\n // accepts VERBATIM, spelled in ITS vocabulary (`merchant_url`, not\n // the entry's `resource_url`). The local surface keeps pointing at\n // its pay tools: they need no cap, so a verbatim hint exists.\n // #1328: the 'mpp' rail's only-ever catalog row (the Haven MPP demo\n // resource) is delisted with the mpp_demo retirement, so this\n // fallback is unreachable today; it stays x402 rather than naming a\n // deleted tool in case a future non-demo 'mpp' rail entry appears.\n // A row without a tool_name cannot get a verbatim hint —\n // haven_pay_mcp_tool requires tool_name — so it gets the REASON\n // instead of a hint its own tool refuses (haven-reviewer on #3113;\n // the epic's \"omitted + reason, never null\" shape, decision 3).\n ...(entry.protocol === 'mcp'\n ? entry.toolName\n ? {\n suggested_tool: 'haven_pay_mcp_tool',\n suggested_arguments: {\n merchant_url: entry.resourceUrl,\n tool_name: entry.toolName,\n ...(entry.toolArguments ? { arguments: entry.toolArguments } : {}),\n },\n }\n : {\n suggested_tool_omitted_reason:\n 'this catalog row carries no tool_name, which haven_pay_mcp_tool requires; ' +\n 'read the merchant\\'s tool list yourself, then call haven_pay_mcp_tool with ' +\n 'merchant_url, tool_name and arguments',\n }\n : {\n suggested_tool: 'haven_pay_x402',\n suggested_arguments: { url: entry.resourceUrl },\n }),\n }))\n })\n },\n haven_submit_catalog_entry: async (input) => {\n const args = objectInput('haven_submit_catalog_entry', input)\n return runTool(async () => {\n const submission = await haven.submitCatalogEntry(\n String(args.resource_url),\n typeof args.website === 'string' ? { website: args.website } : undefined,\n )\n return {\n id: submission.id,\n verify_token: submission.verifyToken,\n status: submission.status,\n }\n })\n },\n haven_list_receipts: async (input) => {\n const args = objectInput('haven_list_receipts', input)\n // #3128: same page shape as the hosted runtime.\n return runTool(async () =>\n haven.listReceiptsPage({ limit: args.limit, cursor: args.cursor, compact: args.compact === true }),\n )\n },\n haven_verify_receipt: async (input) => {\n const args = objectInput('haven_verify_receipt', input)\n return runTool(async () => verifyPaymentReceipt(args.receipt as PaymentReceipt))\n },\n\n haven_open_task_budget: async (input) => {\n const args = objectInput('haven_open_task_budget', input)\n return runTool(async () => {\n const token = await resolveTaskBudgetToken(haven, typeof args.token === 'string' ? args.token : undefined)\n const maxAmountAtomic = humanToAtomicOrNull(args.max_amount_human as string, token.decimals)\n if (maxAmountAtomic === null) {\n throw new HavenApiError(\n `max_amount_human (\"${args.max_amount_human}\") is not a valid decimal amount for ` +\n `${token.symbol} (${token.decimals} decimal places). Nothing was reserved.`,\n 400,\n )\n }\n const result = await haven.openTaskBudget({\n tokenAddress: token.address,\n maxAmountAtomic,\n ttlSeconds: Number(args.ttl_minutes) * 60,\n recipientAddress: typeof args.recipient === 'string' ? args.recipient : undefined,\n label: typeof args.label === 'string' ? args.label : undefined,\n })\n // #3419: the same recovery notice the hosted task-budget handoffs\n // carry (same builder, the SDK's TASK_SIGN_CONTEXT_VERSION) — an old\n // signer strips the unknown task_budget_id key exactly the same way\n // on the local surface.\n return {\n task_budget: result.taskBudget,\n next_action: 'sign',\n next_tool: 'mcp__haven-signer__haven_sign',\n next_arguments: { task_budget_id: result.taskBudget.id },\n signer_compatibility: taskSignerCompatibilityNotice(),\n }\n })\n },\n\n haven_close_task_budget: async (input) => {\n const args = objectInput('haven_close_task_budget', input)\n return runTool(async () => {\n const result = await haven.closeTaskBudget(args.task_budget_id as string)\n if (result.status === 'closed') {\n return { task_budget: result.taskBudget, status: 'closed' as const }\n }\n // #3419: same notice as the open handoff above — this result also\n // hands the agent to haven_sign { task_budget_id }.\n return {\n task_budget: result.taskBudget,\n next_action: 'sign',\n next_tool: 'mcp__haven-signer__haven_sign',\n next_arguments: { task_budget_id: args.task_budget_id },\n signer_compatibility: taskSignerCompatibilityNotice(),\n }\n })\n },\n\n haven_submit: async (input) => {\n const args = objectInput('haven_submit', input)\n const hasTaskBudget = typeof args.task_budget_id === 'string' && args.task_budget_id.length > 0\n const hasPayment = typeof args.payment_id === 'string' && args.payment_id.length > 0\n if (hasTaskBudget === hasPayment) {\n return {\n success: false,\n code: 'INVALID_INPUT',\n message:\n 'haven_submit takes exactly one of task_budget_id or payment_id, never both or ' +\n 'neither. Nothing was relayed.',\n }\n }\n return runTool(async () => {\n if (hasTaskBudget) {\n const result = await haven.submitTaskBudget(args.task_budget_id as string, args.signature as string)\n return {\n task_budget: result.taskBudget,\n status: result.status,\n ...(result.closeTxHash !== undefined ? { close_tx_hash: result.closeTxHash } : {}),\n }\n }\n // #3329: payment_id has no caller on the local surface today — the\n // local runtime signs and submits a direct payment inline through\n // haven.pay(), so a bare signature relay by payment_id has nothing to\n // do here. Declared for schema parity with the hosted surface\n // (captain contract §5); refuses rather than guessing at behavior.\n throw new HavenApiError(\n 'haven_submit with payment_id is not supported on the local MCP surface: haven_send ' +\n 'signs and submits a direct payment in one call, so there is no separate relay step. ' +\n 'Use haven_submit with task_budget_id to relay a task-budget open/close signature.',\n 400,\n )\n })\n },\n }\n\n async function resumeState(\n args: { payment_id?: string; resume_state?: unknown },\n rail: 'x402',\n ): Promise<X402ResumeState> {\n const state =\n args.resume_state ??\n (args.payment_id ? await haven.getResumeState(args.payment_id) : undefined)\n\n if (!state || typeof state !== 'object') {\n throw new HavenApiError(`haven_resume_${rail}_payment requires resume_state or payment_id.`, 400)\n }\n\n if ((state as { rail?: unknown }).rail !== rail) {\n throw new HavenApiError(`Resume state is not for the ${rail} rail.`, 409, state)\n }\n\n return state as X402ResumeState\n }\n}\n\n/**\n * RETAINED DELIBERATELY, and unreachable from any live rail (#2101). The same\n * reasoning as the hosted server's copy in\n * `packages/mcp-server/src/tools/support/quote-response.ts` (it was\n * `tools.ts` until #2808 moved the predicate into shared support):\n * no rail mints a payment-level `pending` / `pending_approval` any more (410 on\n * the legacy rail per #1986; 403/502 at prepare with nothing written on the\n * delegation rail; `approval_requests` dropped by #2055), but the one branch it\n * guards is fail-CLOSED — it stops the agent rather than continuing. What was\n * removed is the agent-visible promise: `MCP_INSTRUCTIONS` no longer tells a\n * model to branch on this status or to wait for an approval.\n */\nfunction isPendingApproval(status: string | undefined): boolean {\n return status === 'pending' || status === 'pending_approval'\n}\n\n/**\n * Build a structured wrong-tool ToolFailure pointing the agent at the right tool.\n * `code` should be 'WRONG_TOOL' (wrong operation entirely) or 'WRONG_RAIL' (right\n * operation but wrong payment protocol — x402 vs MPP).\n */\nfunction wrongTool(code: string, message: string, suggested_tool?: string): ToolFailure {\n return { success: false, code, message, suggested_tool }\n}\n\n/**\n * The one spelling — the #2366 window is over (#3411).\n *\n * Haven's wire convention is snake_case, and the hosted MCP surface already\n * follows it. This package shipped `idempotencyKey` and is PUBLISHED, so the\n * rename could not be a single release: an installed caller passing the old\n * name had to keep working for a window, and be told to move. Owner decision\n * 2026-09-06 — accept both, warn on the old, drop it later. The removal\n * condition: the warning first shipped on the `alpha`/`latest` channel in\n * `0.1.35-alpha.0` (npm, published 2026-09-07); `latest` is many releases\n * past it. The window is closed.\n *\n * `idempotencyKey` stays DECLARED in every schema above and is now REFUSED by\n * name with `IDEMPOTENCY_KEY_RENAMED`, rather than simply deleted from the\n * schema. Deleting it would let the MCP SDK's default `z.object` strip mode\n * silently drop an undeclared key before the handler ever ran — the exact\n * #2348 failure this refusal exists to prevent, since a dropped idempotency\n * key turns a retry into a second spend. Sending BOTH spellings is refused\n * the same way, because the legacy name being present at all is the refusal\n * condition — there is no longer a \"resolve the disagreement\" step.\n */\n/**\n * Parse the input and resolve the idempotency-key spelling, in one step (#2366).\n *\n * Both have to happen BEFORE `runTool`, because a `ToolFailure` returned from\n * inside its callback becomes `data` — a refusal wearing a success. But moving\n * `objectInput` out on its own lost the normalisation `runTool` was giving its\n * schema errors, which turned two \"rejects at schema level\" tests red. So the\n * pair is hoisted together and normalised here, and every caller gets the same\n * two exits: a failure to return, or args plus any warnings to carry.\n */\nfunction preflight<TName extends HavenMcpToolName>(\n name: TName,\n input: unknown,\n): { args: Record<string, any>; warnings: string[] } | ToolFailure {\n let args: Record<string, any>\n try {\n args = objectInput(name, input)\n } catch (err) {\n return normalizeError(err)\n }\n const idem = resolveIdempotencyKey(args)\n if ('success' in idem) return idem\n // #3411: carried under a name distinct from the refused `idempotencyKey`\n // input field, so it cannot be confused with — or accidentally re-trigger\n // — the refusal in `resolveIdempotencyKey` below. The snake_case key still\n // reaches the SDK from here.\n if (idem.key !== undefined) args = { ...args, resolvedIdempotencyKey: idem.key }\n return { args, warnings: idem.warnings }\n}\n\nexport function resolveIdempotencyKey(\n args: Record<string, unknown>,\n): { key?: string; warnings: string[] } | ToolFailure {\n const modern = typeof args.idempotency_key === 'string' ? args.idempotency_key : undefined\n const legacy = typeof args.idempotencyKey === 'string' ? args.idempotencyKey : undefined\n\n // #3411: the #2366 window is over. `idempotencyKey` is refused by NAME,\n // whether or not `idempotency_key` was also sent — the schema still\n // DECLARES it (see toolSchemas above) so the MCP SDK does not silently\n // strip it before this code runs (the #2348 failure); it is refused here\n // instead, before anything is contacted or spent.\n if (legacy !== undefined) {\n return {\n success: false,\n code: 'IDEMPOTENCY_KEY_RENAMED',\n message:\n 'idempotencyKey has been renamed to idempotency_key and is no longer accepted. ' +\n 'Send idempotency_key instead. Nothing was contacted or spent.',\n }\n }\n if (modern !== undefined) return { key: modern, warnings: [] }\n return { warnings: [] }\n}\n\n/** Build a JSON-RPC 2.0 tools/call envelope for an MCP merchant. */\nfunction buildMcpToolsCallEnvelope(\n toolName: string,\n args?: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n jsonrpc: '2.0',\n id: `haven-mcp-${Date.now()}`,\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: args ?? {},\n },\n }\n}\n\nfunction objectInput<TName extends HavenMcpToolName>(\n name: TName,\n input: unknown,\n): Record<string, any> {\n return z.object(toolSchemas[name]).parse(input ?? {})\n}\n\nfunction requestInit(input: { method?: string; headers?: Record<string, string>; body?: string }): RequestInit | undefined {\n if (!input.method && !input.headers && input.body === undefined) return undefined\n return {\n method: input.method,\n headers: input.headers,\n body: input.body,\n }\n}\n\nasync function runTool<T>(fn: () => Promise<T>, warnings: string[] = []): Promise<ToolPayload<T>> {\n try {\n const data = await fn()\n // #2366: attached only when there is something to say, so a caller that\n // sends the current spelling sees the response shape it always saw.\n return warnings.length > 0 ? { success: true, data, warnings } : { success: true, data }\n } catch (err) {\n return normalizeError(err)\n }\n}\n\nasync function responsePayload(response: Response): Promise<Record<string, unknown>> {\n const text = await response.text()\n return {\n status: response.status,\n statusText: response.statusText,\n headers: Object.fromEntries(response.headers.entries()),\n body: parseMaybeJson(text),\n }\n}\n\n/**\n * #3329: `haven_open_task_budget` takes a symbol-or-address plus a HUMAN\n * amount, but the SDK's `openTaskBudget` takes atomic units against a\n * resolved token address — the same split `haven_check_funds` bridges on the\n * hosted surface. This agent's own allowances are the source of truth for\n * which tokens it may spend at all, so a symbol resolves against THOSE (never\n * a guess), and decimals come from the SDK's own chain registry.\n */\nasync function resolveTaskBudgetToken(\n haven: HavenClient,\n symbolOrAddress: string | undefined,\n): Promise<{ address: string; symbol: string; decimals: number }> {\n const wanted = (symbolOrAddress ?? 'USDC').toLowerCase()\n const { allowances } = await haven.getAllowances()\n const isAddress = /^0x[0-9a-fA-F]{40}$/.test(wanted)\n const match = isAddress\n ? allowances.find((a) => a.tokenAddress.toLowerCase() === wanted)\n : allowances.find((a) => (a.tokenSymbol ?? '').toLowerCase() === wanted)\n if (!match) {\n const known = allowances.map((a) => `${a.tokenSymbol} (${a.tokenAddress})`)\n throw new HavenApiError(\n `token \"${symbolOrAddress ?? 'USDC'}\" is not the symbol or address of any allowance this ` +\n `agent holds${known.length > 0 ? ` (it holds: ${known.join(', ')})` : ' (it holds none)'}. ` +\n 'Nothing was reserved.',\n 400,\n )\n }\n const resolved = resolveTokenFromAddress(match.tokenAddress)\n return { address: match.tokenAddress, symbol: match.tokenSymbol, decimals: resolved?.decimals ?? 6 }\n}\n\n/** A plain decimal string (\"5\", \"0.25\") to atomic units, or null if it does not fit `decimals`. */\nfunction humanToAtomicOrNull(human: string, decimals: number): string | null {\n if (!/^[0-9]+(\\.[0-9]+)?$/.test(human)) return null\n const [whole, frac = ''] = human.split('.')\n if (frac.length > decimals) return null\n const atomic = BigInt(whole || '0') * 10n ** BigInt(decimals) + BigInt(frac.padEnd(decimals, '0') || '0')\n return atomic.toString()\n}\n\nfunction parseMaybeJson(text: string): unknown {\n if (!text) return null\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\n/**\n * #2983: the local-flow counterpart of mcp-server's `HostedToolError` for the\n * `MERCHANT_NOT_READY` failure — carries the same wire fields\n * (`code`, `next_action`, `retry_with_new_quote`) `normalizeError` below\n * reads off it. Not a `HavenApiError`: that class's `code` is hardcoded to\n * `'API_ERROR'`, and this failure needs its own code on the wire.\n */\nclass MerchantNotReadyError extends Error {\n readonly code = AgentPaymentFailureCode.MerchantNotReady\n readonly statusCode = 503\n readonly nextAction = AgentPaymentNextAction.StopAndTellUser\n // Genuinely retryable — unlike a rejection, nothing about THIS call was\n // wrong; the merchant's own wallet needs to recover first.\n readonly retryWithNewQuote = true\n\n constructor(message: string) {\n super(message)\n this.name = 'MerchantNotReadyError'\n }\n}\n\n/**\n * #2983: mirrors mcp-server's `merchantNotReadyErrorFor` (`mcp-context.ts`)\n * for the local runtime. Only the merchant's OWN refusal shape — `503\n * { error: 'merchant_not_ready', reason_code, settlements_remaining,\n * retry_after_s }` — maps here. A bare 503 (a load balancer, an HTML outage\n * page, a non-JSON body) is not a capacity signal and keeps going through\n * the #1301 discovery path. `response.clone()` because the caller still\n * needs to read the ORIGINAL response (for `discoveryMissError`'s status)\n * when this returns null.\n */\nasync function merchantNotReadyErrorFor(response: Response): Promise<MerchantNotReadyError | null> {\n if (response.status !== 503) return null\n let body: unknown\n try {\n body = await response.clone().json()\n } catch {\n return null\n }\n if (!body || typeof body !== 'object' || (body as Record<string, unknown>).error !== 'merchant_not_ready') {\n return null\n }\n const { reason_code, settlements_remaining, retry_after_s } = body as Record<string, unknown>\n return new MerchantNotReadyError(\n 'The merchant refused this call: it cannot settle a payment right now' +\n (typeof reason_code === 'string' ? ` (reason_code: ${reason_code})` : '') +\n (typeof settlements_remaining === 'number'\n ? `, settlements_remaining: ${settlements_remaining}`\n : '') +\n '. No payment was created.' +\n (typeof retry_after_s === 'number'\n ? ` Retry after approximately ${retry_after_s}s.`\n : ' This is often transient; retry later.'),\n )\n}\n\n/**\n * #1301: the local-flow counterpart of mcp-server's `withDiscoveryGuidance`\n * (kept there, not shared — that helper rewrites a thrown `HavenApiError`;\n * this one builds a fresh failure from a non-ok `Response`, since the local\n * `haven.fetch()` idiom never throws for a non-402 answer). Keeps the\n * original probe status authoritative, but tells the agent what discovery\n * tried — the pre-#1301 local failure mode was a silent pass-through of\n * whatever the base path served.\n */\nfunction discoveryMissError(\n response: Response,\n merchantUrl: string,\n discovered: string | null,\n discoveredFromUrl?: string,\n): HavenApiError {\n const base = discoveredFromUrl\n ? `Merchant call to ${merchantUrl} failed with HTTP ${response.status} ` +\n `(at the DISCOVERED endpoint ${merchantUrl}, resolved from ${discoveredFromUrl} ` +\n `via the merchant discovery document).`\n : `Merchant call to ${merchantUrl} failed with HTTP ${response.status}.`\n const guidance = discoveredFromUrl\n ? ''\n : discovered\n ? ` Same-origin discovery resolved the same URL (${discovered}), which still did not answer successfully.`\n : ` No same-origin discovery document was found at /.well-known/haven-demo-merchant or /. ` +\n `If ${merchantUrl} is a base merchant URL, pass the exact MCP endpoint instead (often <origin>/mcp).`\n return new HavenApiError(`${base}${guidance}`, response.status || 400)\n}\n\nfunction normalizeError(err: unknown): ToolFailure {\n if (err instanceof MerchantNotReadyError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n nextAction: err.nextAction,\n next_action: err.nextAction,\n retry_with_new_quote: err.retryWithNewQuote,\n // #3103: the local runtime's one decision site — no tool can act until\n // the merchant recovers; the message carries retry_after_s.\n next_tool_omitted_reason: 'the merchant needs to recover first; re-quote after the retry_after_s in the message',\n }\n }\n\n if (err instanceof HavenPaymentStateError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n status: err.status,\n phase: err.phase,\n nextAction: err.nextAction,\n next_action: err.nextAction,\n resume_state: err.resumeState,\n body: err.body,\n }\n }\n\n if (err instanceof HavenSigningError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n }\n }\n\n if (err instanceof HavenApiError) {\n const body = err.body as Record<string, unknown> | undefined\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n phase: stringOrUndefined(body?.phase),\n nextAction:\n stringOrUndefined(body?.nextAction) ??\n stringOrUndefined(body?.next_action) ??\n AgentPaymentNextAction.StopAndTellUser,\n next_action:\n stringOrUndefined(body?.nextAction) ??\n stringOrUndefined(body?.next_action) ??\n AgentPaymentNextAction.StopAndTellUser,\n // #3303: a backend refusal that already names why no tool follows (the\n // 426 `client_outdated` does) keeps that reason at the top level.\n ...(typeof body?.next_tool_omitted_reason === 'string'\n ? { next_tool_omitted_reason: body.next_tool_omitted_reason }\n : {}),\n body: err.body,\n }\n }\n\n if (err instanceof HavenError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n }\n }\n\n return {\n success: false,\n code: 'UNKNOWN_ERROR',\n message: err instanceof Error ? err.message : String(err),\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n next_action: AgentPaymentNextAction.StopAndTellUser,\n // #3103: the second local decision site — nothing structured can follow an\n // error this runtime did not recognise.\n next_tool_omitted_reason: 'an error this runtime does not recognise; tell the user what the message says',\n }\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined\n}\n","import { createHash } from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport type { HavenAllowance, HavenAllowanceSummary, HavenClient } from '@haven_ai/sdk'\nimport { formatTokenAmount, resolveTokenBySymbol } from '@haven_ai/sdk'\nimport { toolDescriptions, toolSchemas, type HavenMcpToolName } from './tools.js'\n\n/**\n * First-launch consent gate for the Haven MCP server.\n *\n * Why this exists (option A of issue #163): an agent runtime that loads a\n * Haven credential file is about to expose Haven payment tools to a model.\n * Before the server starts taking JSON-RPC calls we want the operator to\n * acknowledge — exactly once per credential + tool set — what those tools\n * can do and what the on-chain budget actually is. The agent's budget\n * delegation and its caveat enforcers remain the policy primitive; this gate\n * is informational rather than enforcement.\n *\n * #2086: the copy below used to describe the legacy Safe AllowanceModule and\n * an approval queue that would catch an over-budget payment. Both are gone —\n * the AllowanceModule rail is retired (#1986) and the approval queue's table\n * with it (#2055) — so the gate was promising an operator a human backstop\n * that does not exist. It is now one accurate description of the delegation\n * rail rather than rail-aware prose, because the delegation rail is the only\n * rail that can pay at all: a legacy account gets HTTP 410 from the payment\n * paths, so a second branch here would describe a state no reader can be in.\n *\n * Resolution:\n * - `HAVEN_MCP_ACK=<hash>` env var matching the current consent hash → pass.\n * - `HAVEN_MCP_ACK=skip` → pass (intended for CI / scripted setups).\n * - sidecar file `<credentials>.ack.json` containing `{ ack: <hash> }` → pass.\n * - `--ack` CLI flag → write the sidecar file, print the consent block, pass.\n * - otherwise → print the consent block to stderr and exit non-zero.\n *\n * The hash binds the api-key prefix to the registered tool set and the\n * agent's current allowance summary, so a configuration change re-triggers\n * the prompt.\n */\n\nexport interface ConsentInput {\n apiKeyPrefix: string\n /** Haven API base URL the credential will hit. */\n apiUrl?: string\n /** Agent identity from the credential file, when present. */\n agentId?: string\n /** Haven wallet the agent spends from. */\n accountAddress?: string\n /** Agent's delegate EOA — the local signer. */\n delegateAddress?: string\n /** Chain the agent operates on. */\n chainId?: number\n toolNames: readonly HavenMcpToolName[]\n /**\n * #3410: every amount here is ATOMIC (smallest on-chain units, e.g. 6\n * decimals for USDC — `1000000` is one USDC, never \"1000000 tokens\"). Both\n * producers agree: the live read takes `onchain.amount`, and the seed takes\n * the credential file's `allowance_amount` — both atomic. `renderConsentBlock`\n * converts for display through the token registry and falls back to an\n * explicit `(atomic units)` label when the token is unknown; the consent\n * hash deliberately covers the atomic string, so a display change alone\n * never re-prompts the operator.\n *\n * Known limitation (#3410, stated not fixed): the seed is setup-time data.\n * If the wallet owner edits the budget after setup AND the live read then\n * fails, the screen shows the stale seed budget as if it were current.\n */\n allowanceSummary: readonly { token: string; amount: string; resetMinutes: number | null }[]\n}\n\nexport interface ConsentDecision {\n /** True if the gate is satisfied and the server may start. */\n ok: boolean\n /** Hash representing the current consent surface. */\n hash: string\n /** Reason the gate accepted (or rejected) the run. */\n reason:\n | 'env_var_match'\n | 'env_var_skip'\n | 'ack_file_match'\n | 'wrote_ack_file'\n | 'env_var_mismatch'\n | 'no_acknowledgement'\n}\n\nexport interface ConsentOptions {\n /** Path to the credential file; used to locate the sidecar `<path>.ack.json`. */\n credentialsPath?: string\n /** When true, write the sidecar file with the current hash and accept. */\n writeAck?: boolean\n /** Override the environment lookup (testing). */\n env?: Record<string, string | undefined>\n /** Override the writable stream the consent block is printed to (testing). */\n out?: { write: (chunk: string) => unknown }\n}\n\nexport function computeConsentHash(input: ConsentInput): string {\n const allowanceCanonical = [...input.allowanceSummary]\n .map((a) => `${a.token}:${a.amount}:${a.resetMinutes ?? 'none'}`)\n .sort()\n .join('|')\n const toolCanonical = [...input.toolNames].sort().join(',')\n // Identity fields are included in the hash so swapping the credential\n // to a different Haven wallet / delegate / chain — even one with an\n // identical allowance set — invalidates the prior sidecar and re-prompts\n // the operator. Addresses are normalised to lowercase so casing changes\n // in the credential file don't gratuitously re-prompt.\n const identity = [\n input.apiKeyPrefix,\n input.apiUrl ?? '',\n input.agentId ?? '',\n (input.accountAddress ?? '').toLowerCase(),\n (input.delegateAddress ?? '').toLowerCase(),\n input.chainId ?? '',\n ].join('|')\n return createHash('sha256')\n .update(`${identity}\\n${toolCanonical}\\n${allowanceCanonical}`)\n .digest('hex')\n .slice(0, 16)\n}\n\nexport function renderConsentBlock(input: ConsentInput, hash: string): string {\n const lines: string[] = [\n '',\n '────────────────────────────────────────────────────────────',\n 'Haven MCP server — first-launch consent',\n '────────────────────────────────────────────────────────────',\n '',\n `Credential: ${input.apiKeyPrefix}…`,\n ]\n if (input.apiUrl) lines.push(`Haven API: ${input.apiUrl}`)\n if (input.agentId) lines.push(`Agent ID: ${input.agentId}`)\n if (input.accountAddress) lines.push(`Haven wallet: ${input.accountAddress}`)\n if (input.delegateAddress) lines.push(`Delegate (local signer): ${input.delegateAddress}`)\n if (typeof input.chainId === 'number') lines.push(`Chain ID: ${input.chainId}`)\n lines.push('')\n lines.push('Confirm these match the Haven wallet and chain you intend the')\n lines.push('agent runtime to use. The delegate above is the only key that')\n lines.push('signs payments — it lives in this process, not on Haven\\'s backend.')\n lines.push('')\n lines.push('Tools this server will expose to your agent runtime:')\n for (const name of input.toolNames) {\n lines.push(` • ${name}`)\n lines.push(` ${toolDescriptions[name]}`)\n }\n lines.push('')\n if (input.allowanceSummary.length === 0) {\n lines.push('On-chain budget: none configured.')\n lines.push(' Until the wallet owner grants this agent a budget in Haven,')\n lines.push(' every payment it attempts is declined on-chain.')\n } else {\n lines.push('On-chain budget (the real spend gate — enforced by the agent\\'s')\n lines.push('signed delegation, not by Haven):')\n for (const a of input.allowanceSummary) {\n const reset = a.resetMinutes ? ` per ${a.resetMinutes} min` : ' (no reset)'\n lines.push(` • up to ${describeBudgetAmount(a, input.chainId)}${reset}`)\n }\n }\n lines.push('')\n lines.push('Anything above the on-chain budget is declined before any money')\n lines.push('moves — it is not queued, and no one is asked to review it. If the')\n lines.push('agent needs more room, the wallet owner grants or raises the budget')\n lines.push('in Haven. Revoking the agent on-chain disables every MCP tool that')\n lines.push('would spend.')\n lines.push('')\n lines.push(`Consent hash: ${hash}`)\n lines.push('')\n lines.push('To acknowledge, EITHER:')\n lines.push(` • set HAVEN_MCP_ACK=${hash} in this process\\'s environment, OR`)\n lines.push(' • re-run with --ack to write the acknowledgement next to your')\n lines.push(' credential file (sidecar <credentials>.ack.json).')\n lines.push('')\n lines.push('────────────────────────────────────────────────────────────')\n lines.push('')\n return lines.join('\\n')\n}\n\n/** Resolve the consent gate. Does not exit the process; the caller decides. */\nexport async function ensureConsent(\n input: ConsentInput,\n options: ConsentOptions = {},\n): Promise<ConsentDecision> {\n const env = options.env ?? process.env\n const out = options.out ?? process.stderr\n const hash = computeConsentHash(input)\n\n // 1) Explicit skip — for CI and scripted environments.\n if (env.HAVEN_MCP_ACK === 'skip') {\n return { ok: true, hash, reason: 'env_var_skip' }\n }\n\n // 2) Env var hash match.\n if (typeof env.HAVEN_MCP_ACK === 'string' && env.HAVEN_MCP_ACK.length > 0) {\n if (env.HAVEN_MCP_ACK === hash) {\n return { ok: true, hash, reason: 'env_var_match' }\n }\n out.write(renderConsentBlock(input, hash))\n out.write(\n `HAVEN_MCP_ACK was set but did not match the current consent hash.\\n` +\n `Expected: ${hash}\\n` +\n `Got: ${env.HAVEN_MCP_ACK}\\n` +\n `Re-acknowledge with the new hash above, or run with --ack.\\n\\n`,\n )\n return { ok: false, hash, reason: 'env_var_mismatch' }\n }\n\n // 3) Sidecar ack file (only meaningful when we loaded from a file).\n const ackPath = sidecarPath(options.credentialsPath)\n if (ackPath) {\n const stored = await readAckFile(ackPath)\n if (stored?.ack === hash) {\n return { ok: true, hash, reason: 'ack_file_match' }\n }\n }\n\n // 4) --ack: write the sidecar and accept.\n if (options.writeAck && ackPath) {\n out.write(renderConsentBlock(input, hash))\n await writeAckFile(ackPath, hash)\n out.write(`Wrote acknowledgement to ${ackPath}\\n\\n`)\n return { ok: true, hash, reason: 'wrote_ack_file' }\n }\n\n // 5) Otherwise: print and refuse.\n out.write(renderConsentBlock(input, hash))\n return { ok: false, hash, reason: 'no_acknowledgement' }\n}\n\nfunction sidecarPath(credentialsPath?: string): string | null {\n if (!credentialsPath) return null\n return resolve(`${credentialsPath}.ack.json`)\n}\n\nasync function readAckFile(path: string): Promise<{ ack?: string } | null> {\n try {\n const raw = await readFile(path, 'utf8')\n const parsed = JSON.parse(raw) as { ack?: unknown }\n return { ack: typeof parsed.ack === 'string' ? parsed.ack : undefined }\n } catch {\n return null\n }\n}\n\nasync function writeAckFile(path: string, hash: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(\n path,\n JSON.stringify({ ack: hash, at: new Date().toISOString() }, null, 2),\n 'utf8',\n )\n}\n\nexport interface CredentialIdentitySeed {\n apiKey: string\n apiUrl?: string\n agentId?: string\n /** Account address from the credential file, used as a fallback. */\n accountAddress?: string\n /** Delegate address from the credential file, used before live allowance metadata is available. */\n delegateAddress?: string\n /** Chain from the credential file, used as a fallback. */\n chainId?: number\n /**\n * Intended agent budget from the setup flow, used before on-chain approval\n * is visible. #3410: every amount is ATOMIC — the connector writes the\n * credential file's `allowance_amount` straight from the setup response's\n * `agent_budget`, and the backend puts `budget_atomic` there.\n */\n allowanceSummary?: readonly { token: string; amount: string; resetMinutes: number | null }[]\n}\n\n/**\n * Build the consent input from credential identity plus a live allowance\n * lookup. The on-chain (or configured) allowance is what the operator\n * actually cares about — that's the real spend ceiling — but we also bind\n * the hash to the Haven wallet / delegate / chain so a credential swap\n * cannot quietly reuse a prior sidecar acknowledgement.\n *\n * If `getAllowances()` fails (e.g. backend unreachable on first launch) we\n * fall through to whatever identity fields the credential file provided,\n * so the operator at least sees the tool list and the api-key prefix.\n */\nexport async function consentInputFromClient(\n haven: HavenClient,\n seed: CredentialIdentitySeed,\n toolNames: readonly HavenMcpToolName[],\n): Promise<ConsentInput> {\n let allowanceSummary: ConsentInput['allowanceSummary'] = seed.allowanceSummary ?? []\n let accountAddress = seed.accountAddress\n let delegateAddress: string | undefined = seed.delegateAddress\n let chainId: number | undefined = seed.chainId\n\n try {\n const summary = await haven.getAllowances()\n const list: HavenAllowance[] = isAllowanceSummary(summary)\n ? summary.allowances\n : Array.isArray(summary)\n ? (summary as HavenAllowance[])\n : []\n if (isAllowanceSummary(summary)) {\n accountAddress = summary.accountAddress ?? accountAddress\n delegateAddress = summary.delegateAddress\n chainId = typeof summary.chainId === 'number' ? summary.chainId : chainId\n }\n const liveAllowanceSummary = list.map((a) => ({\n token: a.tokenSymbol ?? 'UNKNOWN',\n // #3410: `onchain.amount` is the atomic budget (`budget_atomic` on the\n // backend). The old `a.configuredAmount` fallback here was unreachable\n // — `onchain` is required in the SDK types and dereferenced\n // unconditionally, so a response without it throws into the seed path —\n // and it was the one HUMAN-decimal value in this chain; a human number\n // must never reach an atomic field. '0' keeps the (defensive) shape for\n // a malformed onchain object without inventing a unit.\n amount: a.onchain?.amount ?? '0',\n resetMinutes:\n typeof a.onchain?.resetTimeMin === 'number'\n ? a.onchain.resetTimeMin\n : typeof a.resetPeriodMin === 'number'\n ? a.resetPeriodMin\n : null,\n }))\n allowanceSummary = liveAllowanceSummary\n } catch {\n // Identity falls back to what the credential file gave us.\n }\n\n return {\n apiKeyPrefix: derivePrefix(seed.apiKey),\n apiUrl: seed.apiUrl,\n agentId: seed.agentId,\n accountAddress,\n delegateAddress,\n chainId,\n toolNames,\n allowanceSummary,\n }\n}\n\nfunction isAllowanceSummary(value: unknown): value is HavenAllowanceSummary {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'allowances' in value &&\n Array.isArray((value as { allowances: unknown }).allowances)\n )\n}\n\n/**\n * Use the leading characters of the api key (which already begins with the\n * non-secret `sk_agent_` prefix) as a stable, low-information identifier.\n * Twelve characters is enough to disambiguate credentials in front of a\n * human but not enough to reveal the secret.\n */\nfunction derivePrefix(apiKey: string): string {\n return apiKey.slice(0, 12)\n}\n\n/**\n * #3410: one budget, one display form. The consent screen is the surface\n * whose job is informed consent — an atomic number printed as whole tokens\n * overstates the budget a millionfold — so every amount is rendered in whole\n * tokens when the token is known (`resolveTokenBySymbol` over the same\n * registry the SDK's address-based reads use) and carries an explicit\n * `(atomic units)` label when it is not, mirroring connect's\n * `describeApprovedBudget` fallback. This is DISPLAY ONLY: the consent hash\n * keeps covering the raw atomic string, byte-identical to what every\n * installed sidecar acknowledged before this change.\n */\nfunction describeBudgetAmount(a: { token: string; amount: string }, chainId: number | undefined): string {\n const token = chainId === undefined ? null : resolveTokenBySymbol(chainId, a.token)\n if (!token) return `${a.amount} ${a.token} (atomic units)`\n return `${formatTokenAmount(a.amount, token.decimals)} ${a.token}`\n}\n\n/** Convenience: the canonical tool list registered by the server. */\nexport function registeredToolNames(): HavenMcpToolName[] {\n return Object.keys(toolSchemas) as HavenMcpToolName[]\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n HavenClient,\n havenClientIdentity,\n isSupportedNodeVersion,\n unsupportedNodeVersionMessage,\n type HavenClientUpdate,\n} from '@haven_ai/sdk'\nimport { loadCredentials, type HavenCredentialFile } from './credentials.js'\nimport {\n createToolHandlers,\n toolDescriptions,\n toolSchemas,\n type HavenMcpToolName,\n type ToolPayload,\n} from './tools.js'\nimport {\n consentInputFromClient,\n ensureConsent,\n registeredToolNames,\n type ConsentDecision,\n} from './consent.js'\n\nexport interface HavenMcpServerOptions {\n credentialsPath?: string\n identityPath?: string\n signerPath?: string\n credentials?: HavenCredentialFile\n /**\n * When true, write the consent sidecar file (`<credentials>.ack.json`)\n * with the current consent hash and proceed. Surfaced via the `--ack`\n * CLI flag.\n */\n writeAck?: boolean\n /**\n * When true, skip the consent gate entirely. Reserved for tests and\n * controlled embedding — production CLIs should not set this.\n */\n skipConsent?: boolean\n /** Overridable so the Node-floor refusal is testable without spawning a Node. */\n nodeVersion?: string\n}\n\nexport interface ResolvedHavenClient {\n client: HavenClient\n credentials: HavenCredentialFile\n}\n\nexport async function createHavenClient(options: HavenMcpServerOptions = {}): Promise<HavenClient> {\n const { client } = await resolveHavenClient(options)\n return client\n}\n\nexport async function resolveHavenClient(options: HavenMcpServerOptions = {}): Promise<ResolvedHavenClient> {\n // The choke point (#1161 review): `runStdioServer`, `createHavenClient` and\n // `createHavenMcpServer` all funnel through here, and the client built below\n // is delegate-key-bound — `pay()`, `sign()` and the x402 paths activate the\n // moment `delegateKey` is set. Guarding only the stdio entrypoint would leave\n // the embedding constructors reaching a signing-capable client on an\n // unsupported runtime, which is this issue's own bug one layer down.\n assertSupportedNodeVersion(options.nodeVersion)\n\n const credentialSource = options.credentialsPath || options.identityPath || options.signerPath\n ? {\n credentialsPath: options.credentialsPath,\n identityPath: options.identityPath,\n signerPath: options.signerPath,\n }\n : undefined\n const credentials = options.credentials ?? await loadCredentials(credentialSource)\n const client = new HavenClient({\n apiKey: credentials.apiKey,\n delegateKey: credentials.delegateKey,\n baseUrl: credentials.apiUrl,\n // #3303: name this package, not the SDK inside it, so the backend's\n // update hint and refusal speak about what the user actually installed.\n clientIdentity: havenClientIdentity(MCP_NAME, MCP_VERSION),\n })\n return { client, credentials }\n}\n\nexport async function createHavenMcpServer(options: HavenMcpServerOptions = {}): Promise<McpServer> {\n const haven = await createHavenClient(options)\n return buildMcpServer(haven)\n}\n\n/**\n * Build an MCP server bound to the supplied Haven client.\n *\n * Each tool dispatch is wrapped in `haven.withRequestContext` so every\n * Haven API request the dispatch issues carries `X-Haven-MCP-Tool: <name>`\n * — and *only* that dispatch's requests see the header. The SDK uses an\n * `AsyncLocalStorage` for the context, so two tool calls running\n * concurrently cannot leak headers into each other and the backend\n * `agent_tool_invocations` rows are always attributed to the right tool.\n */\nexport const MCP_NAME = '@haven_ai/mcp'\nexport const MCP_VERSION = '0.7.0-alpha.0'\n\n/**\n * MCP `instructions` — the critical path, surfaced to the model at\n * `initialize`. Shorter than the hosted server's: this runtime signs\n * in-process with the delegate key it holds, so there is no separate\n * haven-signer namespace or payment_id signing step to describe. Kept free\n * of any version literal; a guard test in `server.test.ts` pins that.\n */\nexport const MCP_INSTRUCTIONS = [\n 'Haven local MCP server: signs in-process with the delegate key it holds on',\n 'this machine — the key never leaves this process. Call haven_get_agent',\n 'first, every session: identity, readiness, and live remaining budget in',\n 'one call. Do not guess the wallet, network, or budget.',\n '',\n 'To pay: haven_discover_tools to find a payable service, then',\n 'haven_pay_mcp_tool for MCP merchants or haven_pay_x402 for any x402',\n 'paywall. Tool responses carry next_action (nextAction is the same value, kept one more',\n 'release) and, when no tool follows, next_tool_omitted_reason — follow them; description prose',\n 'is fallback, not the source of truth.',\n '',\n 'A payment outside the agent budget is declined before any money moves. Haven',\n 'holds no approval queue, so there is nothing to poll and no approval will',\n 'ever arrive for it. On a decline, or on any status you do not',\n 'recognise, stop and tell the user: do not retry or re-sign, and ask them to',\n 'grant or raise the budget in Haven. Spend authority is enforced on-chain by',\n 'the user\\'s account; Haven never holds keys and cannot override it.',\n].join('\\n')\n\nexport function buildMcpServer(haven: HavenClient): McpServer {\n const server = new McpServer(\n {\n name: MCP_NAME,\n version: MCP_VERSION,\n },\n { instructions: MCP_INSTRUCTIONS },\n )\n\n const handlers = createToolHandlers(haven)\n const registerTool = (server as any).tool.bind(server)\n for (const name of Object.keys(toolSchemas) as HavenMcpToolName[]) {\n registerTool(\n name,\n toolDescriptions[name],\n toolSchemas[name],\n async (args: unknown) =>\n haven.withRequestContext({ 'X-Haven-MCP-Tool': name }, async () =>\n toMcpResult(withClientUpdate(await handlers[name](args), haven.clientUpdate())),\n ),\n )\n }\n\n return server\n}\n\n/**\n * Refuse to start on an unsupported Node (#1161).\n *\n * Same reasoning as the signer's identical guard: install-time enforcement\n * cannot see a Node downgrade after setup, or a version manager handing the\n * agent runtime a different Node than the shell that connected. The local MCP\n * server drives payment construction against the signer, so it is held to the\n * package's declared floor rather than whatever happens to boot.\n */\nexport function assertSupportedNodeVersion(nodeVersion: string = process.versions.node): void {\n if (isSupportedNodeVersion(nodeVersion)) return\n const err: NodeJS.ErrnoException = new Error(\n unsupportedNodeVersionMessage({ subject: 'The Haven MCP server', nodeVersion }),\n )\n err.code = 'HAVEN_MCP_UNSUPPORTED_NODE'\n throw err\n}\n\nexport async function runStdioServer(options: HavenMcpServerOptions = {}): Promise<void> {\n // Asserted inside resolveHavenClient — the choke point every key-bound path\n // shares — so it still runs here, before credentials are read.\n const { client: haven, credentials } = await resolveHavenClient(options)\n\n if (!options.skipConsent) {\n const decision = await runConsentGate(haven, credentials, options)\n if (!decision.ok) {\n // The consent block has already been printed by `ensureConsent`.\n const err: NodeJS.ErrnoException = new Error(\n decision.reason === 'env_var_mismatch'\n ? 'Haven MCP consent acknowledgement does not match the current configuration.'\n : 'Haven MCP server requires a one-time consent acknowledgement before starting.',\n )\n err.code = 'HAVEN_MCP_NO_CONSENT'\n throw err\n }\n }\n\n const server = buildMcpServer(haven)\n await server.connect(new StdioServerTransport())\n}\n\nexport async function runConsentGate(\n haven: HavenClient,\n credentials: HavenCredentialFile,\n options: HavenMcpServerOptions,\n): Promise<ConsentDecision> {\n const toolNames = registeredToolNames()\n const input = await consentInputFromClient(\n haven,\n {\n apiKey: credentials.apiKey,\n apiUrl: credentials.apiUrl,\n agentId: credentials.agentId,\n accountAddress: credentials.accountAddress,\n delegateAddress: credentials.delegateAddress,\n chainId: credentials.chainId,\n allowanceSummary: credentials.allowanceSummary,\n },\n toolNames,\n )\n // Prefer the path actually used to load credentials (covers\n // HAVEN_CREDENTIALS as well as --credentials). If neither file path is\n // available the operator must use HAVEN_MCP_ACK; --ack has nowhere to\n // write a sidecar in that case.\n const credentialsPath = options.identityPath ?? options.credentialsPath ?? credentials.sourcePath\n return ensureConsent(input, {\n credentialsPath,\n writeAck: options.writeAck,\n })\n}\n\n/**\n * #3303: attach the backend's `client_update` hint — the one THIS dispatch's\n * own requests received — to the tool result, so an agent on an outdated\n * runtime reads the update command on the call it made, success or failure.\n */\nexport function withClientUpdate(payload: ToolPayload, hint: HavenClientUpdate | undefined): ToolPayload {\n if (!hint || payload.client_update) return payload\n return { ...payload, client_update: hint }\n}\n\nfunction toMcpResult(payload: ToolPayload) {\n return {\n isError: !payload.success,\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(payload, null, 2),\n },\n ],\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/credentials.ts","../src/signer-compat.ts","../src/tools.ts","../src/consent.ts","../src/server.ts"],"names":["sharedDescriptions","readFile","HavenClient"],"mappings":"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","file":"index.js","sourcesContent":["import { readFile, stat } from 'node:fs/promises'\n\nexport interface HavenCredentialFile {\n apiKey: string\n delegateKey: string\n agentId?: string\n /** The Haven account (smart account) the agent spends from. */\n accountAddress?: string\n delegateAddress?: string\n chainId?: number\n network?: string\n apiUrl?: string\n allowanceSummary?: readonly HavenCredentialAllowance[]\n /**\n * Absolute path the credentials were loaded from, if any. Set when the\n * caller pointed at a JSON file via `--credentials` or `HAVEN_CREDENTIALS`;\n * left undefined when credentials came purely from environment variables.\n * The MCP server uses this to locate the consent sidecar\n * (`<sourcePath>.ack.json`) so `--ack` works regardless of how the\n * credential path was supplied.\n */\n sourcePath?: string\n identityPath?: string\n signerPath?: string\n}\n\nexport interface HavenCredentialAllowance {\n token: string\n amount: string\n resetMinutes: number | null\n}\n\nexport interface HavenCredentialSource {\n credentialsPath?: string\n identityPath?: string\n signerPath?: string\n}\n\ninterface RawCredentialFile {\n api_key?: unknown\n apiKey?: unknown\n delegate_key?: unknown\n delegateKey?: unknown\n delegate_address?: unknown\n delegateAddress?: unknown\n agent_id?: unknown\n agentId?: unknown\n /** #2908: what `@haven_ai/connect` writes from this release on. */\n account_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */\n safe_address?: unknown\n /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */\n safeAddress?: unknown\n chain_id?: unknown\n chainId?: unknown\n network?: unknown\n api_url?: unknown\n apiUrl?: unknown\n hosted_mcp_url?: unknown\n hostedMcpUrl?: unknown\n allowance_summary?: unknown\n allowanceSummary?: unknown\n agent_budget?: unknown\n agentBudget?: unknown\n}\n\n/**\n * Load Haven agent credentials for the MCP server.\n *\n * Resolution order — earlier sources win, later sources are fallbacks:\n *\n * 1. Explicit `path` argument (typically from `--credentials <path>`).\n * 2. `HAVEN_CREDENTIALS` env var pointing at a credential JSON file.\n * 3. Inline env vars: `HAVEN_API_KEY` + `HAVEN_DELEGATE_KEY` (+ optional\n * `HAVEN_AGENT_ID`, `HAVEN_ACCOUNT_ADDRESS` and `HAVEN_API_URL`). The\n * pre-#2908 spellings `HAVEN_WALLET_ADDRESS` / `HAVEN_SAFE_ADDRESS` are\n * retired as of #2914.\n *\n * The inline-env path exists so that runtime config snippets emitted by the\n * Haven dashboard (Claude Desktop / Cursor / generic MCP configs) can be a\n * single self-contained block — paste the snippet, restart the runtime, done.\n * The values still live only in the agent operator's process environment;\n * Haven's backend never sees the delegate key either way.\n */\nexport async function loadCredentials(\n source: string | HavenCredentialSource | undefined = process.env.HAVEN_CREDENTIALS,\n): Promise<HavenCredentialFile> {\n if (typeof source === 'string') {\n return loadCredentialsFromFile(source)\n }\n if (source?.credentialsPath) {\n return loadCredentialsFromFile(source.credentialsPath)\n }\n if (source?.identityPath || source?.signerPath) {\n if (!source.identityPath || !source.signerPath) {\n throw new Error('Haven split credentials require both --identity and --signer paths.')\n }\n return loadCredentialsFromSplitFiles(source.identityPath, source.signerPath)\n }\n\n const envCreds = loadCredentialsFromEnv()\n if (envCreds) return envCreds\n\n throw new Error(\n 'No Haven credentials found. Set HAVEN_CREDENTIALS to a Haven agent credential JSON file, ' +\n 'pass --credentials <path>, or set HAVEN_API_KEY and HAVEN_DELEGATE_KEY environment variables.',\n )\n}\n\nasync function loadCredentialsFromFile(path: string): Promise<HavenCredentialFile> {\n let rawText: string\n try {\n rawText = await readFile(path, 'utf8')\n } catch (err) {\n throw new Error(`Could not read Haven credentials at ${path}: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n await warnIfCredentialFilePermissive(path)\n\n let raw: RawCredentialFile\n try {\n raw = JSON.parse(rawText) as RawCredentialFile\n } catch {\n throw new Error('Haven credentials must be JSON with api_key and delegate_key fields.')\n }\n\n const apiKey = stringField(raw.api_key ?? raw.apiKey)\n const delegateKey = stringField(raw.delegate_key ?? raw.delegateKey)\n\n if (!apiKey) {\n throw new Error('Haven credentials are missing api_key.')\n }\n if (!delegateKey) {\n throw new Error('Haven MCP requires delegate_key so payments can be signed locally.')\n }\n\n const accountAddress = readAccountAddressField(raw)\n return {\n apiKey,\n delegateKey,\n agentId: stringField(raw.agent_id ?? raw.agentId),\n accountAddress,\n delegateAddress: stringField(raw.delegate_address ?? raw.delegateAddress),\n chainId: numberField(raw.chain_id ?? raw.chainId),\n network: stringField(raw.network),\n apiUrl: stringField(raw.api_url ?? raw.apiUrl),\n allowanceSummary: allowanceSummaryField(raw.allowance_summary ?? raw.allowanceSummary ?? raw.agent_budget ?? raw.agentBudget),\n sourcePath: path,\n }\n}\n\nasync function loadCredentialsFromSplitFiles(identityPath: string, signerPath: string): Promise<HavenCredentialFile> {\n const identity = await readJsonFile(identityPath, 'Haven identity credentials')\n const signer = await readJsonFile(signerPath, 'Haven signer credentials')\n\n await warnIfCredentialFilePermissive(identityPath)\n await warnIfCredentialFilePermissive(signerPath)\n\n const apiKey = stringField(identity.api_key ?? identity.apiKey)\n const delegateKey = stringField(signer.delegate_key ?? signer.delegateKey)\n\n if (!apiKey) {\n throw new Error('Haven identity credentials are missing api_key.')\n }\n if (!delegateKey) {\n throw new Error('Haven signer credentials are missing delegate_key.')\n }\n\n return {\n apiKey,\n delegateKey,\n agentId: matchingStringField(\n 'agent_id',\n identity.agent_id ?? identity.agentId,\n signer.agent_id ?? signer.agentId,\n ),\n accountAddress: matchingStringField(\n 'account_address',\n readAccountAddressField(identity),\n readAccountAddressField(signer),\n { caseInsensitive: true },\n ),\n delegateAddress: matchingStringField(\n 'delegate_address',\n signer.delegate_address ?? signer.delegateAddress,\n identity.delegate_address ?? identity.delegateAddress,\n { caseInsensitive: true },\n ),\n chainId: matchingNumberField(\n 'chain_id',\n identity.chain_id ?? identity.chainId,\n signer.chain_id ?? signer.chainId,\n ),\n network: matchingStringField(\n 'network',\n identity.network,\n signer.network,\n { caseInsensitive: true },\n ),\n apiUrl: stringField(identity.api_url ?? identity.apiUrl),\n allowanceSummary: allowanceSummaryField(\n identity.allowance_summary ??\n identity.allowanceSummary ??\n identity.agent_budget ??\n identity.agentBudget,\n ),\n sourcePath: identityPath,\n identityPath,\n signerPath,\n }\n}\n\nasync function readJsonFile(path: string, label: string): Promise<RawCredentialFile> {\n let rawText: string\n try {\n rawText = await readFile(path, 'utf8')\n } catch (err) {\n throw new Error(`Could not read ${label} at ${path}: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n try {\n return JSON.parse(rawText) as RawCredentialFile\n } catch {\n throw new Error(`${label} must be JSON.`)\n }\n}\n\nfunction loadCredentialsFromEnv(): HavenCredentialFile | null {\n const apiKey = stringField(process.env.HAVEN_API_KEY)\n const delegateKey = stringField(process.env.HAVEN_DELEGATE_KEY)\n\n if (!apiKey && !delegateKey) return null\n\n if (!apiKey) {\n throw new Error('HAVEN_DELEGATE_KEY is set but HAVEN_API_KEY is missing.')\n }\n if (!delegateKey) {\n throw new Error('HAVEN_API_KEY is set but HAVEN_DELEGATE_KEY is missing. Haven MCP requires a delegate key so payments can be signed locally.')\n }\n\n return {\n apiKey,\n delegateKey,\n agentId: stringField(process.env.HAVEN_AGENT_ID),\n accountAddress: readAccountAddressEnv(process.env),\n chainId: numberField(process.env.HAVEN_CHAIN_ID),\n network: stringField(process.env.HAVEN_NETWORK),\n apiUrl: stringField(process.env.HAVEN_API_URL),\n }\n}\n\n/**\n * The account address off a credential FILE: `account_address` (what\n * `@haven_ai/connect` writes from #2908 on) first, then the two pre-#2908\n * spellings.\n *\n * The two old fallbacks are PERMANENT (#2906, decision 2a) — a credential\n * file on disk never rewrites itself, and a runtime that stopped reading\n * `safe_address` would silently lose the address (and change the consent\n * hash) for every agent connected before this release.\n *\n * Exported for the mutation tests: dropping `account_address` fails the\n * new-shape test, dropping either old key fails the old-shape test.\n */\nexport function readAccountAddressField(\n raw: Pick<RawCredentialFile, 'account_address' | 'safe_address' | 'safeAddress'>,\n): string | undefined {\n return stringField(raw.account_address ?? raw.safe_address ?? raw.safeAddress)\n}\n\n/**\n * The account address off the environment: `HAVEN_ACCOUNT_ADDRESS` (the\n * survivor, decided on #2906). The two names the dashboard handoff emitted\n * before #2908 — `HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` — were\n * window-scoped and are retired as of #2914.\n */\nexport function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefined {\n const current = stringField(env.HAVEN_ACCOUNT_ADDRESS)\n\n // Retired, but REFUSED rather than ignored — the same rule the backend\n // applies to retired request names, for the same reason and with more at\n // stake. Silently dropping these would not merely leave the address unset:\n // `accountAddress` is what `haven_sign_sweep_delegate` passes as\n // `expectedSafe`, and an undefined `expectedSafe` SKIPS the check that a\n // sweep's `to` matches the account in the local credential (see\n // `core.ts`). An operator who upgrades without touching env would lose a\n // money-path cross-check and get no signal at all.\n //\n // The verdict keys on RELIANCE, not presence, so a handoff that still\n // exports both names alongside the new one keeps working:\n // retired alone -> throw\n // both, same value -> accept the new one\n // both, disagreeing -> throw\n for (const name of ['HAVEN_WALLET_ADDRESS', 'HAVEN_SAFE_ADDRESS'] as const) {\n const retired = stringField(env[name])\n if (!retired) continue\n if (!current) {\n throw new Error(\n `${name} is retired (#2906) — Haven accounts are addressed as accounts, not Safes. ` +\n 'Set HAVEN_ACCOUNT_ADDRESS to the same value. Refusing rather than ignoring it, ' +\n 'because an unset account address silently skips the sweep-destination check.',\n )\n }\n if (retired.toLowerCase() !== current.toLowerCase()) {\n throw new Error(\n `${name} and HAVEN_ACCOUNT_ADDRESS were both set to different addresses. ` +\n 'Remove the retired name, or make them match — picking one silently would hide ' +\n 'the mismatch.',\n )\n }\n }\n\n return current\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction numberField(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim() && /^\\d+$/.test(value.trim())) return Number(value.trim())\n return undefined\n}\n\nfunction matchingStringField(\n label: string,\n preferred: unknown,\n fallback: unknown,\n options: { caseInsensitive?: boolean } = {},\n): string | undefined {\n const preferredValue = stringField(preferred)\n const fallbackValue = stringField(fallback)\n if (\n preferredValue &&\n fallbackValue &&\n !sameCredentialValue(preferredValue, fallbackValue, options.caseInsensitive)\n ) {\n throw mismatchedSplitCredentialError(label)\n }\n return preferredValue ?? fallbackValue\n}\n\nfunction matchingNumberField(label: string, preferred: unknown, fallback: unknown): number | undefined {\n const preferredValue = numberField(preferred)\n const fallbackValue = numberField(fallback)\n if (preferredValue !== undefined && fallbackValue !== undefined && preferredValue !== fallbackValue) {\n throw mismatchedSplitCredentialError(label)\n }\n return preferredValue ?? fallbackValue\n}\n\nfunction sameCredentialValue(first: string, second: string, caseInsensitive = false): boolean {\n return caseInsensitive ? first.toLowerCase() === second.toLowerCase() : first === second\n}\n\nfunction mismatchedSplitCredentialError(label: string): Error {\n return new Error(\n `Haven split credentials have mismatched ${label} values. ` +\n 'Recreate the identity and signer credential files from the same Haven agent.',\n )\n}\n\nfunction allowanceSummaryField(value: unknown): HavenCredentialAllowance[] | undefined {\n if (!Array.isArray(value)) return undefined\n const allowances = value.flatMap((item) => {\n if (!item || typeof item !== 'object') return []\n const raw = item as Record<string, unknown>\n const token = stringField(raw.token ?? raw.token_symbol ?? raw.tokenSymbol)\n const amount = stringField(raw.amount ?? raw.allowance_amount ?? raw.allowanceAmount)\n const reset = raw.resetMinutes ?? raw.reset_minutes ?? raw.reset_period_min ?? raw.resetPeriodMin\n if (!token || !amount) return []\n return [{\n token,\n amount,\n resetMinutes: reset === null ? null : numberField(reset) ?? null,\n }]\n })\n return allowances.length > 0 ? allowances : undefined\n}\n\n/**\n * Warn (but do not block) when the credential file is readable by users\n * other than the owner. The check is best-effort: it only runs on POSIX\n * filesystems where the stat mode bits map cleanly. Windows ACLs require\n * `icacls`-style introspection that doesn't fit a single stat call, so we\n * skip the check there and the dashboard handoff text guides the user\n * separately.\n *\n * Exported for testing.\n */\nexport async function warnIfCredentialFilePermissive(\n path: string,\n log: (message: string) => void = (message) => process.stderr.write(`${message}\\n`),\n platform: NodeJS.Platform = process.platform,\n): Promise<void> {\n if (platform === 'win32') return\n\n let mode: number\n try {\n const stats = await stat(path)\n mode = stats.mode\n } catch {\n // The credential read already failed cleanly above if the file is\n // unreadable. A stat failure here is not worth blocking on.\n return\n }\n\n const groupOrOther = mode & 0o077\n if (groupOrOther !== 0) {\n const octal = (mode & 0o777).toString(8).padStart(4, '0')\n log(\n `haven-mcp: warning: credential file at ${path} is readable beyond the owner ` +\n `(mode ${octal}). Run: chmod 600 ${path}`,\n )\n }\n}\n","/**\n * #3419: the task-budget old-signer recovery notice, LOCAL surface.\n *\n * The hosted builder of the same name lives in\n * `packages/mcp-server/src/tools/support/signer-compat.ts`; this package\n * cannot import it (no dependency on the hosted package — they are separate\n * runtimes, and a runtime dependency the other way would drag the hosted\n * server's connector channel into every local install), so the shape is\n * duplicated here ON PURPOSE and pinned identical by two tests:\n * `packages/mcp/src/task-budgets.test.ts` (fields present on the local\n * handoffs) and `packages/mcp-server/src/hosted-signer-integration.test.ts`\n * (hosted and local builders agree field-for-field, from the same SDK\n * constant).\n *\n * The SINGLE SOURCES are shared, not copied: `TASK_SIGN_CONTEXT_VERSION`\n * comes from `@haven_ai/sdk` (the same constant the backend emits and the\n * signer's `SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS` derives from), and the\n * recovery route is built from the same `connectorUpgradeCommand()` the\n * signer's own update hints use. What is pinned to `'0.6.0-alpha.0'` here is\n * the same ONE fact the hosted constant pins: the first `@haven_ai/signer`\n * release whose `haven_sign` accepts the `task_budget_id` argument form\n * (#3329) — `client-releases.data.ts` is the record, and the hosted\n * package's `TASK_BUDGET_MIN_SIGNER_VERSION` (the exported constant the\n * cross-package pin ties to it) carries the identical value.\n *\n * Like the hosted notice this is ADVISORY DATA on the handoff result, never a\n * gate: the local runtime cannot see the signer either, and the signer keeps\n * enforcing its own versions at the sign-context fetch.\n */\nimport { TASK_SIGN_CONTEXT_VERSION, connectorUpgradeCommand } from '@haven_ai/sdk'\n\n/**\n * The first `@haven_ai/signer` release whose `haven_sign` accepts the\n * `task_budget_id` argument form (#3329). ONE constant on this surface, with\n * exactly one job: the value `signer_compatibility.min_signer_version`\n * reports on the two task-budget handoffs below. The hosted package exports\n * `TASK_BUDGET_MIN_SIGNER_VERSION` with the same value, tied to the same\n * release record (`client-releases.data.ts`) by its cross-package pin.\n */\nexport const TASK_BUDGET_MIN_SIGNER_VERSION = '0.6.0-alpha.0'\n\n/** The capability key both runtimes report in `signer_compatibility.signer_capability`. */\nexport const SIGNER_CAPABILITY_KEY = 'haven/signer-compatibility'\n\n/**\n * The recovery notice every result that hands off to\n * `haven_sign { task_budget_id }` carries — the local twin of the hosted\n * `taskSignerCompatibilityNotice()`. Field-for-field the same shape:\n *\n * - `task_sign_context_version` — from the SDK's single source;\n * - `min_signer_version` — the constant above;\n * - `signer_capability` — the existing capability key;\n * - `check` / `fallback` — the recovery sentence as prose and as data: the\n * trigger substring (the generic refusal every pre-0.6.0 signer answers,\n * both historic lines begin with it), then close the pending budget, update\n * via the connector doctor and its printed repair line, reopen. No relay\n * fallback exists for this signing context (an `eip712_delegation` payload\n * the 0.5.x unbound allowlist refuses and a 0.4.x signer must not be\n * steered into), so none is named.\n */\nexport function taskSignerCompatibilityNotice() {\n return {\n task_sign_context_version: TASK_SIGN_CONTEXT_VERSION,\n min_signer_version: TASK_BUDGET_MIN_SIGNER_VERSION,\n signer_capability: SIGNER_CAPABILITY_KEY,\n check:\n 'Call next_tool with next_arguments EXACTLY as given — the signer fetches the exact bytes ' +\n 'by task_budget_id. If haven_sign answers SIGNING_ERROR with a message starting \"Pass ' +\n \"payment_id (preferred for delegation-rail x402\\\", the signer predates task budgets and signed \" +\n 'nothing: first close this budget with haven_close_task_budget { task_budget_id } to release ' +\n `it, then update the connector by running \\`${connectorUpgradeCommand()}\\` and the repair ` +\n 'line it prints, then open the budget again.',\n fallback:\n 'haven_sign answered SIGNING_ERROR with a message starting \"Pass payment_id (preferred for ' +\n 'delegation-rail x402\" — the signer predates task budgets and signed nothing: call ' +\n 'haven_close_task_budget { task_budget_id } to release the pending budget, then update the ' +\n `connector by running \\`${connectorUpgradeCommand()}\\` and the repair line it prints, ` +\n 'then open the budget again. There is no relay fallback for this signing context.',\n }\n}\n","/**\n * Local (stdio) MCP tool handlers. This package runs in the AGENT OPERATOR'S\n * OWN environment — it reads the local credential file and signs locally; the\n * hosted backend is not in the loop for the merchant call. So `merchant_url`\n * passed to `haven.fetch` below is NOT an SSRF surface: the agent is the\n * principal paying a merchant IT chose, on its own machine — the same trust\n * position as running `curl`. There is no server reflecting attacker input\n * into an internal request. (Hosted, multi-tenant fetches live in mcp-server,\n * which is where URL-hardening would matter.)\n */\nimport {\n AgentPaymentFailureCode,\n AgentPaymentNextAction,\n HavenApiError,\n HavenClient,\n HavenError,\n HavenPaymentStateError,\n HavenSigningError,\n composeDescription,\n discoverMerchantMcpUrl,\n resolveTokenFromAddress,\n sameUrl,\n toolDescriptions as sharedDescriptions,\n verifyPaymentReceipt,\n type HavenClientUpdate,\n type PaymentReceipt,\n type X402Quote,\n type X402ResumeState,\n} from '@haven_ai/sdk'\nimport { taskSignerCompatibilityNotice } from './signer-compat.js'\nimport { z } from 'zod/v3'\n\nconst headersSchema = z.record(z.string(), z.string()).optional()\n\nexport type HavenMcpToolName =\n | 'haven_send'\n | 'haven_pay_mcp_tool'\n | 'haven_quote_x402'\n | 'haven_pay_x402_quote'\n | 'haven_pay_x402'\n | 'haven_resume_x402_payment'\n | 'haven_get_payment_status'\n | 'haven_get_resume_state'\n | 'haven_get_agent'\n | 'haven_get_allowances'\n | 'haven_list_receipts'\n | 'haven_verify_receipt'\n | 'haven_sweep_delegate'\n | 'haven_discover_tools'\n | 'haven_submit_catalog_entry'\n | 'haven_open_task_budget'\n | 'haven_close_task_budget'\n | 'haven_get_task_budget'\n | 'haven_submit'\n\n/**\n * #3100 (epic #3105, decision 4): the structured hint on a local discovery\n * entry — a pay tool with arguments it accepts VERBATIM, or the reason no\n * verbatim hint exists for the row (decision 3's omitted-plus-reason shape).\n */\nexport type DiscoveryHint =\n | {\n suggested_tool: 'haven_pay_mcp_tool'\n suggested_arguments: { merchant_url: string; tool_name: string; arguments?: Record<string, unknown> }\n }\n | { suggested_tool: 'haven_pay_x402'; suggested_arguments: { url: string } }\n | { suggested_tool_omitted_reason: string }\n\n/** One `haven_discover_tools` entry on the local surface (wire-shaped). */\nexport type DiscoveryEntry = {\n id: string\n name: string\n description: string | null\n category: string | null\n resource_url: string\n rail: string\n protocol: string\n tool_name: string | null\n tool_arguments: Record<string, unknown> | null\n price_display: string | null\n price_atomic: string | null\n asset: string | null\n network: string | null\n status: string\n verified_at: string | null\n source?: string\n domain_verified?: boolean\n verified_payable?: boolean\n} & DiscoveryHint\n\nexport const toolSchemas = {\n haven_send: {\n asset: z.enum(['ETH', 'USDC']),\n recipient: z.string().min(1),\n amount: z.string().min(1),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n /** #3329: spend against an open task budget instead of the agent's period budget. */\n task_budget_id: z.string().min(1).optional(),\n /**\n * #3330: spend against an open sub-budget this agent HOLDS (it is the\n * sub-agent B) instead of the agent's own budget. Mutually exclusive\n * with task_budget_id — the backend refuses a body naming both.\n */\n sub_budget_id: z.string().min(1).optional(),\n },\n haven_pay_mcp_tool: {\n merchant_url: z.string().url(),\n tool_name: z.string().min(1),\n arguments: z.record(z.string(), z.unknown()).optional(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n },\n haven_quote_x402: {\n url: z.string().url(),\n method: z.string().optional(),\n headers: headersSchema,\n body: z.string().optional(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n },\n haven_pay_x402_quote: {\n quote: z.unknown(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n /** #3329: spend against an open task budget instead of the agent's period budget. */\n task_budget_id: z.string().min(1).optional(),\n /** #3330: spend against an open sub-budget this agent holds (it is sub-agent B). Mutually exclusive with task_budget_id. */\n sub_budget_id: z.string().min(1).optional(),\n },\n haven_pay_x402: {\n url: z.string().url(),\n method: z.string().optional(),\n headers: headersSchema,\n body: z.string().optional(),\n idempotency_key: z.string().optional(),\n /** REMOVED (#3411): declared only so the resolver can refuse it by name, never accepted. */\n idempotencyKey: z.string().optional().describe('REMOVED (#3411): refused — send idempotency_key'),\n /** #3329: spend against an open task budget instead of the agent's period budget. */\n task_budget_id: z.string().min(1).optional(),\n /** #3330: spend against an open sub-budget this agent holds (it is sub-agent B). Mutually exclusive with task_budget_id. */\n sub_budget_id: z.string().min(1).optional(),\n },\n haven_resume_x402_payment: {\n payment_id: z.string().optional(),\n resume_state: z.unknown().optional(),\n },\n haven_get_payment_status: {\n payment_id: z.string(),\n },\n haven_get_resume_state: {\n payment_id: z.string(),\n },\n haven_get_agent: {},\n haven_get_allowances: {},\n haven_sweep_delegate: {},\n haven_discover_tools: {\n category: z.string().optional(),\n search: z.string().optional(),\n rail: z.enum(['x402', 'mpp']).optional(),\n verified: z.enum(['any', 'verified', 'operator']).optional(),\n },\n haven_submit_catalog_entry: {\n resource_url: z.string().min(1),\n website: z.string().optional(),\n },\n haven_list_receipts: {\n limit: z.number().int().min(1).max(100).optional(),\n /** #3128: the previous page's next_cursor (a receipt id). */\n cursor: z.string().min(1).optional(),\n /** #3423: drop each row's payload echoes; the default shape is unchanged. */\n compact: z\n .boolean()\n .optional()\n .describe('true drops challengePayload, selectedPayment and protocolReceiptPayload from each row; omit for the full row.'),\n },\n haven_verify_receipt: {\n receipt: z.unknown(),\n },\n // #3329: a budget for one task that ends by itself — a short-lived child of\n // the agent's own budget, capped and time-boxed independently of the period\n // reset.\n haven_open_task_budget: {\n max_amount_human: z.string().min(1),\n ttl_minutes: z.number().int().min(1).max(1440),\n recipient: z.string().optional(),\n label: z.string().max(120).optional(),\n token: z.string().optional(),\n },\n haven_close_task_budget: {\n task_budget_id: z.string().min(1),\n },\n // #3518: read ONE task budget by id, any status — the status check a close\n // refusal's \"re-check the budget's status\" points at, on the local surface\n // too (schema and wording parity with the hosted read).\n haven_get_task_budget: {\n task_budget_id: z.string().min(1),\n },\n // #3329 / #3506: relays a signature from the local signer — the open/close\n // signature for a task budget or a sub-budget row, or (schema parity with\n // the hosted surface) a direct-payment signature by payment_id. Exactly one\n // of task_budget_id / sub_budget_id / payment_id, never two or none.\n haven_submit: {\n task_budget_id: z.string().min(1).optional(),\n sub_budget_id: z.string().min(1).optional(),\n payment_id: z.string().min(1).optional(),\n signature: z\n .string()\n .regex(/^0x[0-9a-fA-F]+$/, 'signature must be a 0x-prefixed hex string'),\n },\n// #3101: keys survive on the type (see the hosted server's contracts.ts).\n} as const satisfies Record<HavenMcpToolName, z.ZodRawShape>\n\n// #3329: outcome language only — never \"delegation\", \"caveat\" or \"UserOp\".\nconst OPEN_TASK_BUDGET_DESCRIPTION = [\n 'Open a budget for one task that ends by itself: a spending cap, good for at most ttl_minutes,',\n 'reserved out of the agent\\'s own budget and separate from its period reset.',\n 'Pass max_amount_human (whole tokens, e.g. \"5\" for 5 USDC), ttl_minutes (1-1440), and optionally',\n 'recipient (pins every payment against this task budget to one address), label, and token',\n '(defaults to USDC). Returns { task_budget, next_action: \"sign\", next_tool, next_arguments } —',\n 'call next_tool with next_arguments EXACTLY as given to get a signature, then relay it with',\n 'haven_submit. Spending anything above the reserved amount, past the deadline, or to a',\n 'different recipient than the one pinned here is declined on the spot — nothing is queued.',\n 'A recipient pin is checked against where each payment first goes: haven_pay_x402 and',\n 'haven_pay_x402_quote first move funds into the agent\\'s own wallet, so a budget pinned to a',\n 'merchant is declined there — pin only budgets meant for haven_send.',\n].join(' ')\n\nconst CLOSE_TASK_BUDGET_DESCRIPTION = [\n 'End a task budget early, before its deadline, releasing whatever of its cap was unspent back',\n 'to the agent\\'s own budget. Pass task_budget_id. If the budget was never signed (still pending),',\n 'this ends it immediately with { task_budget, status: \"closed\" } and nothing was ever reserved',\n 'on-chain. Otherwise it returns a signature request: { task_budget, next_action: \"sign\",',\n 'next_tool, next_arguments } — call next_tool with next_arguments EXACTLY as given, then relay',\n 'the signature with haven_submit. A task budget past its own deadline closes immediately, the',\n 'same as the pending case.',\n].join(' ')\n\n// #3518: the status check a close refusal's \"re-check the budget's status\"\n// names — reads ONE task budget by id, any status (pending/closing rows\n// included; haven_get_agent lists them with their status too). Same wording\n// as the hosted read: the surfaces describe the same behavior.\nconst GET_TASK_BUDGET_DESCRIPTION = [\n 'Read one task budget by id, any status.',\n 'Returns { task_budget } with status (pending | open | closing | closed), isExpired, maxDisplay, recipientAddress, label and expiresAt —',\n 'the check to run after a close or submit refusal says to re-check the budget\\'s status.',\n 'haven_get_agent lists live task budgets only; this reads any one, closed or expired included.',\n].join(' ')\n\nconst SUBMIT_DESCRIPTION = [\n 'Relay a signature from the local signer. Pass exactly one of task_budget_id (from',\n 'haven_open_task_budget or haven_close_task_budget), sub_budget_id (from haven_get_agent',\n 'pendingSubBudgetSignatures[]) or payment_id — never two, never none — plus signature.',\n 'For a task budget this opens or closes it on-chain and returns { task_budget,',\n 'status }; a close in progress may return { task_budget, status: \"closed\", close_tx_hash }.',\n 'A sub_budget_id returns { sub_budget, status } with the next signer step, if one is owed.',\n].join(' ')\n\n/**\n * MCP tool descriptions, composed from the shared semantic source in\n * `@haven_ai/sdk`'s `tool-descriptions.ts`. Keeping both the SDK tool-calling\n * surface and the MCP surface pointed at the same prose source means new\n * guidance lands in both places at once and a parity test can catch drift.\n */\nexport const toolDescriptions: Record<HavenMcpToolName, string> = {\n haven_send: composeDescription(sharedDescriptions.send),\n haven_pay_mcp_tool: composeDescription(sharedDescriptions.payMcpTool),\n haven_quote_x402: composeDescription(sharedDescriptions.quoteX402),\n haven_pay_x402_quote: composeDescription(sharedDescriptions.payX402),\n haven_pay_x402: composeDescription(sharedDescriptions.payX402OneShot),\n haven_resume_x402_payment: composeDescription(sharedDescriptions.resumeX402),\n haven_get_payment_status: composeDescription(sharedDescriptions.getPaymentStatus),\n haven_get_resume_state: composeDescription(sharedDescriptions.getResumeState),\n haven_get_agent: composeDescription(sharedDescriptions.getAgent),\n haven_get_allowances: composeDescription(sharedDescriptions.getAllowances),\n haven_sweep_delegate: composeDescription(sharedDescriptions.sweep_delegate),\n haven_discover_tools: composeDescription(sharedDescriptions.discoverTools),\n haven_submit_catalog_entry: composeDescription(sharedDescriptions.submitCatalogEntry),\n haven_list_receipts: composeDescription(sharedDescriptions.listReceipts),\n haven_verify_receipt: composeDescription(sharedDescriptions.verifyReceipt),\n haven_open_task_budget: OPEN_TASK_BUDGET_DESCRIPTION,\n haven_close_task_budget: CLOSE_TASK_BUDGET_DESCRIPTION,\n haven_get_task_budget: GET_TASK_BUDGET_DESCRIPTION,\n haven_submit: SUBMIT_DESCRIPTION,\n}\n\nexport interface ToolSuccess<T> {\n success: true\n data: T\n /**\n * Non-fatal notices about the CALL, not about its result (#2366).\n *\n * Additive and optional: a caller that ignores it sees exactly what it saw\n * before. It exists so a deprecation can be announced on the surface that\n * observes it — the alternative was a divergence nothing ever told anyone to\n * leave, which is how `idempotencyKey` survived #2312 and #2348.\n */\n warnings?: string[]\n /**\n * #3303: the backend's `client_update` hint when this package is behind the\n * version the deployment recommends (`required: false`) or below its\n * minimum (`required: true`). `upgrade_command` starts the update: for the\n * connector-installed packages it is the connector doctor, which prints the\n * repair line to run next (#3412).\n */\n client_update?: HavenClientUpdate\n}\n\nexport interface ToolFailure {\n success: false\n code: string\n message: string\n /** Structured hint pointing the agent at the correct tool for this operation. */\n suggested_tool?: string\n statusCode?: number\n paymentId?: string\n status?: string\n phase?: string\n /**\n * @deprecated since #3103 — read `next_action`. Kept with the same value for\n * one release (the #2908 pattern) and removed in the release after the one\n * carrying #3103.\n */\n nextAction?: string\n /**\n * #3103 (epic #3105, decision 10): the same value as `nextAction`, spelled\n * the way the hosted server and the signer spell it. Dual-emitted for one\n * release (the #2908 pattern) before `nextAction` is dropped.\n */\n next_action?: string\n /** #3101 (epic #3105, decision 7): the typed next-step family, additive; `next_tool` never null. */\n next_tool?: string\n next_tool_server?: string\n next_tool_name?: string\n next_tool_server_role?: 'hosted' | 'signer'\n next_arguments?: Record<string, unknown>\n next_tool_omitted_reason?: string\n resume_state?: unknown\n body?: unknown\n /**\n * #2983: carried on `MERCHANT_NOT_READY` — mirrors the hosted MCP's\n * `retry_with_new_quote` (`mcp-context.ts`'s `merchantNotReadyErrorFor`).\n * Genuinely retryable: nothing about the CALL was wrong, the merchant's\n * own wallet needs to recover first.\n */\n retry_with_new_quote?: boolean\n /** #3303: as on {@link ToolSuccess}; on a 426 `client_outdated` refusal it is always `required: true`. */\n client_update?: HavenClientUpdate\n}\n\nexport type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure\n\n/**\n * #3506: the next step for a sub-budget row that still needs THIS agent's\n * signature — the signer's `haven_sign` with `sub_budget_id` (it fetches the\n * signing context itself), then `haven_submit` with the same id. Same shape as\n * the task-budget handoffs above (`next_action: 'sign'`, the signer tool, its\n * arguments).\n */\nfunction subBudgetSignStep(subBudgetId: string) {\n return {\n next_action: 'sign',\n next_tool: 'mcp__haven-signer__haven_sign',\n next_arguments: { sub_budget_id: subBudgetId },\n }\n}\n\n/**\n * #3506: `haven_submit { sub_budget_id }` — the DELEGATING agent's signature\n * for a sub-budget row: it opens a pending row, or relays a signed close. The\n * owner relay is no longer required. Mirrors the hosted handler in\n * `packages/mcp-server/src/tools/state-direct-recovery.ts`.\n *\n * A close can answer 409 `close_needs_reprepare` (the stored disable UserOp\n * is stale) or 502 `close_outcome_unconfirmed` (it was sent; the chain has\n * not finalised). Neither runtime has a close tool, so this handler does the\n * recovery the backend names: it calls `closeSubBudget` (idempotent in\n * effect, authority-reducing) — which reports `closed` if the disable\n * finalised, else prepares a fresh op for `haven_sign` — and for the\n * unconfirmed case says to retry this same call later.\n */\nasync function submitSubBudgetTool(haven: HavenClient, subBudgetId: string, signature: string): Promise<ToolPayload> {\n let result: Awaited<ReturnType<HavenClient['submitSubBudget']>>\n try {\n result = await haven.submitSubBudget(subBudgetId, signature)\n } catch (err) {\n const code =\n err instanceof HavenApiError ? (err.body as { error_code?: string } | undefined)?.error_code : undefined\n if (code === 'close_needs_reprepare') {\n let fresh: Awaited<ReturnType<HavenClient['closeSubBudget']>>\n try {\n fresh = await haven.closeSubBudget(subBudgetId)\n } catch (closeErr) {\n return normalizeError(closeErr)\n }\n if (fresh.status === 'closed') {\n return {\n success: true,\n data: {\n sub_budget: fresh.subBudget,\n status: 'closed',\n next_action: 'none',\n next_tool_omitted_reason: 'the sub-budget is closed on-chain; nothing further to sign or submit for it',\n },\n }\n }\n return {\n success: false,\n code: 'CLOSE_NEEDS_REPREPARE',\n message:\n 'The stored close operation for this sub-budget was stale, so nothing was relayed. Haven prepared a ' +\n 'fresh one: sign it with haven_sign, then call haven_submit again with the new signature.',\n statusCode: 409,\n ...subBudgetSignStep(subBudgetId),\n }\n }\n if (code === 'close_outcome_unconfirmed') {\n return {\n success: false,\n code: 'CLOSE_OUTCOME_UNCONFIRMED',\n message:\n 'The close operation was sent but its outcome is not confirmed yet (on Base that can take tens of ' +\n 'minutes). Wait, then call haven_submit again with the same arguments: it reports closed once the ' +\n 'chain has finalised the disable, or prepares a fresh operation to sign if the earlier one did not land.',\n statusCode: 502,\n next_action: 'check_status_later',\n next_tool: 'haven_submit',\n next_arguments: { sub_budget_id: subBudgetId, signature },\n }\n }\n return normalizeError(err)\n }\n return runTool(async () => {\n const submitted = {\n sub_budget: result.subBudget,\n status: result.status,\n ...(result.closeTxHash !== undefined ? { close_tx_hash: result.closeTxHash } : {}),\n }\n if (result.status === 'closed') {\n return {\n ...submitted,\n next_action: 'none',\n next_tool_omitted_reason: 'the sub-budget is closed on-chain; nothing further to sign or submit for it',\n }\n }\n // Opened: if the tree's other row is still pending, signing it is next\n // (the grant stays unusable until BOTH rows are open).\n let pending: Awaited<ReturnType<HavenClient['listPendingSubBudgetSignatures']>> | null\n try {\n pending = await haven.listPendingSubBudgetSignatures()\n } catch {\n pending = null\n }\n if (pending === null) {\n return {\n ...submitted,\n next_action: 'check_status_later',\n next_tool: 'haven_get_agent',\n next_arguments: {},\n reason:\n 'This sub-budget row is open, but Haven could not say whether its tree has another row ' +\n 'awaiting your signature. Call haven_get_agent and sign any pendingSubBudgetSignatures row.',\n }\n }\n const tree = result.subBudget.parentSubBudgetId ?? result.subBudget.id\n const sibling = pending.find(\n (row) =>\n row.purpose === 'open' &&\n row.subBudgetId !== result.subBudget.id &&\n (row.parentSubBudgetId ?? row.subBudgetId) === tree,\n )\n if (sibling) return { ...submitted, ...subBudgetSignStep(sibling.subBudgetId) }\n return {\n ...submitted,\n next_action: 'none',\n next_tool_omitted_reason:\n 'no other row of this sub-budget awaits your signature, so the sub-budget is fully open ' +\n 'and the sub-agent can spend through its grant',\n }\n })\n}\n\nexport function createToolHandlers(haven: HavenClient): Record<HavenMcpToolName, (input: unknown) => Promise<ToolPayload>> {\n return {\n haven_send: async (input) => {\n // #2366/#3411: resolved OUTSIDE the payload so any `preflight` warning\n // can ride on the success, and BEFORE anything is contacted so a legacy\n // `idempotencyKey` refuses without spending.\n const pf = preflight('haven_send', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n return runTool(async () => {\n try {\n const result = await haven.pay({\n token: args.asset,\n amount: args.amount,\n to: args.recipient,\n // #1207/#3411: was accepted by the schema but silently dropped — now\n // carried to the backend's replay contract via the resolved carrier.\n idempotencyKey: args.resolvedIdempotencyKey,\n // #3329: spend against an open task budget instead of the\n // agent's period budget, when the caller names one.\n ...(typeof args.task_budget_id === 'string' ? { taskBudgetId: args.task_budget_id } : {}),\n // #3330: spend through a sub-budget this agent holds (it is\n // sub-agent B). Exactly one of the two ids, never both.\n ...(typeof args.sub_budget_id === 'string' ? { subBudgetId: args.sub_budget_id } : {}),\n })\n return {\n payment_id: result.paymentId,\n status: result.status,\n tx_hash: result.txHash ?? null,\n asset: args.asset,\n amount: args.amount,\n recipient: args.recipient,\n }\n } catch (err) {\n if (err instanceof HavenPaymentStateError && isPendingApproval(err.status)) {\n // #2101: retained fail-closed (see `isPendingApproval` below), but it\n // used to return a bare status string whose only explanation lived in\n // MCP_INSTRUCTIONS' now-deleted \"pending_approval means stop\" line.\n // Carry the verdict IN BAND rather than leaning on the general\n // unrecognised-status rule: this branch is the one place a model can\n // still meet the status, and it must not read as \"poll and wait\".\n return {\n payment_id: err.paymentId,\n status: 'pending_approval',\n next_action: 'stop_and_tell_user',\n message:\n 'This payment is not payable and nothing is queued for anyone to approve — ' +\n 'stop and tell the user, then ask the wallet owner to grant or raise the ' +\n 'agent budget in Haven. Do not retry, re-sign, or poll.',\n asset: args.asset,\n amount: args.amount,\n recipient: args.recipient,\n }\n }\n throw err\n }\n }, warnings)\n },\n\n haven_pay_mcp_tool: async (input) => {\n // #2366: hoisted out of `runTool` so a refusal is a refusal rather than\n // a success carrying one as its payload. (`warnings` no longer fires for\n // idempotency-key spelling since #3411 — the legacy spelling is refused,\n // not warned on — but the field stays hoisted here for any future\n // non-fatal notice `preflight` needs to attach to a success.)\n const pf = preflight('haven_pay_mcp_tool', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n return runTool(async () => {\n const envelope = buildMcpToolsCallEnvelope(args.tool_name as string, args.arguments as Record<string, unknown> | undefined)\n const init: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(envelope),\n }\n // #1301: a base merchant URL is accepted, mirroring the hosted MCP's\n // #1271 discovery. `haven.fetch()` already resolves a 402 itself\n // (pays and retries) — it never hands a 402 back to us, and a\n // successfully-paid retry that the merchant rejects THROWS from\n // inside the SDK rather than returning a non-ok Response (see\n // `retryX402Request`). So any Response this call returns with\n // `.ok === false` can only be the UNTOUCHED first-hop response to a\n // URL that never spoke 402 at all — free-tool 200s and paid 200s\n // both stay `.ok === true` and never reach this branch. That is the\n // local flow's equivalent of the hosted probe's\n // `X402UnexpectedStatusError` (#1300): \"this URL isn't the MCP\n // endpoint,\" expressed as a Response instead of a thrown error.\n let merchantUrl = args.merchant_url as string\n const idempotencyKey = args.resolvedIdempotencyKey\n const attempt = () => haven.fetch(merchantUrl, init, { idempotencyKey })\n\n let response = await attempt()\n if (!response.ok) {\n // #2983: mirror the hosted `merchantNotReadyErrorFor` — an honest,\n // machine-readable merchant refusal is reported as itself, BEFORE\n // the #1301 \"wrong endpoint\" discovery heuristic ever runs. Without\n // this, every local `merchant_not_ready` 503 fell into the\n // discovery path below and came back as \"no discovery document was\n // found\", discarding the merchant's own reason entirely — the same\n // misreport #2979 fixed on the hosted side.\n const notReady = await merchantNotReadyErrorFor(response)\n if (notReady) throw notReady\n const discovered = await discoverMerchantMcpUrl(merchantUrl)\n // Trailing-slash/case echoes of the input are \"same URL\" — spend\n // the one retry only on a genuinely different endpoint.\n if (!discovered || sameUrl(discovered, merchantUrl)) {\n throw discoveryMissError(response, merchantUrl, discovered)\n }\n const inputUrl = merchantUrl\n merchantUrl = discovered\n const retryResponse = await attempt()\n if (!retryResponse.ok) {\n const notReadyAtDiscovered = await merchantNotReadyErrorFor(retryResponse)\n if (notReadyAtDiscovered) throw notReadyAtDiscovered\n // Label which URL failed — the agent otherwise cannot tell the\n // discovered endpoint's miss from the original probe's.\n throw discoveryMissError(retryResponse, merchantUrl, discovered, inputUrl)\n }\n response = retryResponse\n }\n const payload = await responsePayload(response)\n return {\n ...payload,\n // The RESOLVED endpoint (#1271/#1301), not the input as given.\n merchant_url: merchantUrl,\n ...(merchantUrl !== args.merchant_url ? { merchant_url_discovered_from: args.merchant_url } : {}),\n }\n }, warnings)\n },\n\n haven_quote_x402: async (input) => {\n const pf = preflight('haven_quote_x402', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n try {\n const data = await haven.quoteX402(args.url, requestInit(args), { idempotencyKey: args.resolvedIdempotencyKey })\n return warnings.length > 0 ? { success: true, data, warnings } : { success: true, data }\n } catch (err) {\n // #1328: quoteX402 still refuses a MACHINE-PAYMENT-CHALLENGE response as\n // a defensive shape guard, but nothing in Haven produces that header\n // anymore (the mpp_demo route it was built for is retired) — fall\n // through to the generic error rather than suggesting a deleted tool.\n return normalizeError(err)\n }\n },\n\n haven_pay_x402_quote: async (input) => {\n const pf = preflight('haven_pay_x402_quote', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n const quote = args.quote as Record<string, unknown> | null | undefined\n // Guard before network calls so the agent gets actionable guidance rather\n // than an opaque SDK error.\n if (!quote || typeof quote !== 'object') {\n return wrongTool(\n 'WRONG_TOOL',\n 'The quote argument is missing or is not a valid x402 quote object. Call haven_quote_x402 first to obtain a quote, or use haven_pay_x402 to handle the full probe → pay → retry round trip automatically.',\n 'haven_quote_x402',\n )\n }\n if (!quote.paymentRequired) {\n return wrongTool(\n 'WRONG_TOOL',\n 'The quote is missing the required paymentRequired field. Call haven_quote_x402 first to obtain a valid x402 quote.',\n 'haven_quote_x402',\n )\n }\n return runTool(async () => {\n const response = await haven.payX402Quote(args.quote as X402Quote, {\n idempotencyKey: args.resolvedIdempotencyKey,\n ...(typeof args.task_budget_id === 'string' ? { taskBudgetId: args.task_budget_id } : {}),\n ...(typeof args.sub_budget_id === 'string' ? { subBudgetId: args.sub_budget_id } : {}),\n })\n return responsePayload(response)\n }, warnings)\n },\n\n haven_pay_x402: async (input) => {\n const pf = preflight('haven_pay_x402', input)\n if ('success' in pf) return pf\n const { args, warnings } = pf\n return runTool(async () => {\n const response = await haven.fetch(args.url, requestInit(args), {\n idempotencyKey: args.resolvedIdempotencyKey,\n ...(typeof args.task_budget_id === 'string' ? { taskBudgetId: args.task_budget_id } : {}),\n ...(typeof args.sub_budget_id === 'string' ? { subBudgetId: args.sub_budget_id } : {}),\n })\n return responsePayload(response)\n }, warnings)\n },\n\n haven_resume_x402_payment: async (input) => {\n const args = objectInput('haven_resume_x402_payment', input)\n // #1328: the mpp rail resume_state branch is retired along with\n // haven_resume_mpp_payment — any non-x402 rail is now just a\n // state-mismatch, not a \"use this other tool\" redirect.\n return runTool(async () => {\n const state = await resumeState(args, 'x402')\n const response = await haven.resumeX402Payment(state)\n return responsePayload(response)\n })\n },\n\n haven_get_payment_status: async (input) => {\n const args = objectInput('haven_get_payment_status', input)\n // #1310/#1311: shared with mcp-server's haven_get_payment_status\n // handler — see HavenClient.getPaymentStatusWithPostPurchaseAllowance\n // in @haven_ai/sdk for the single home of this \"settled x402 only\"\n // attach logic (was duplicated verbatim in both packages) and for why\n // `funded_but_unsettled` is excluded from \"settled\".\n return runTool(async () => haven.getPaymentStatusWithPostPurchaseAllowance(args.payment_id))\n },\n\n haven_get_resume_state: async (input) => {\n const args = objectInput('haven_get_resume_state', input)\n return runTool(async () => haven.getResumeState(args.payment_id))\n },\n\n haven_get_agent: async () =>\n runTool(async () => {\n const summary = await haven.getAgentSummary()\n // #3506: each owner-issued sub-budget row awaiting THIS agent's\n // signature names its own next step (haven_sign { sub_budget_id }).\n if (!Array.isArray(summary.pendingSubBudgetSignatures)) return summary\n return {\n ...summary,\n pendingSubBudgetSignatures: summary.pendingSubBudgetSignatures.map((row) => ({\n ...row,\n ...subBudgetSignStep(row.subBudgetId),\n })),\n }\n }),\n haven_get_allowances: async () => runTool(async () => haven.getAllowances()),\n haven_sweep_delegate: async () => runTool(async () => haven.sweepDelegate()),\n haven_discover_tools: async (input) => {\n const args = objectInput('haven_discover_tools', input)\n return runTool(async () => {\n const entries = await haven.discoverTools({\n category: typeof args.category === 'string' ? args.category : undefined,\n search: typeof args.search === 'string' ? args.search : undefined,\n rail: args.rail === 'x402' || args.rail === 'mpp' ? args.rail : undefined,\n verified: args.verified === 'verified' || args.verified === 'operator' ? args.verified : undefined,\n })\n return entries.map((entry): DiscoveryEntry => ({\n id: entry.id,\n name: entry.name,\n description: entry.description,\n category: entry.category,\n resource_url: entry.resourceUrl,\n rail: entry.rail,\n protocol: entry.protocol,\n tool_name: entry.toolName,\n tool_arguments: entry.toolArguments,\n price_display: entry.priceDisplay,\n price_atomic: entry.priceAtomic,\n asset: entry.asset,\n network: entry.network,\n status: entry.status,\n verified_at: entry.verifiedAt,\n source: entry.source,\n domain_verified: entry.domainVerified,\n verified_payable: entry.verifiedPayable,\n // Which Haven pay tool reaches this entry from the local MCP surface,\n // and — #3100 (epic #3105, decision 4) — the arguments that tool\n // accepts VERBATIM, spelled in ITS vocabulary (`merchant_url`, not\n // the entry's `resource_url`). The local surface keeps pointing at\n // its pay tools: they need no cap, so a verbatim hint exists.\n // #1328: the 'mpp' rail's only-ever catalog row (the Haven MPP demo\n // resource) is delisted with the mpp_demo retirement, so this\n // fallback is unreachable today; it stays x402 rather than naming a\n // deleted tool in case a future non-demo 'mpp' rail entry appears.\n // A row without a tool_name cannot get a verbatim hint —\n // haven_pay_mcp_tool requires tool_name — so it gets the REASON\n // instead of a hint its own tool refuses (haven-reviewer on #3113;\n // the epic's \"omitted + reason, never null\" shape, decision 3).\n ...(entry.protocol === 'mcp'\n ? entry.toolName\n ? {\n suggested_tool: 'haven_pay_mcp_tool',\n suggested_arguments: {\n merchant_url: entry.resourceUrl,\n tool_name: entry.toolName,\n ...(entry.toolArguments ? { arguments: entry.toolArguments } : {}),\n },\n }\n : {\n suggested_tool_omitted_reason:\n 'this catalog row carries no tool_name, which haven_pay_mcp_tool requires; ' +\n 'read the merchant\\'s tool list yourself, then call haven_pay_mcp_tool with ' +\n 'merchant_url, tool_name and arguments',\n }\n : {\n suggested_tool: 'haven_pay_x402',\n suggested_arguments: { url: entry.resourceUrl },\n }),\n }))\n })\n },\n haven_submit_catalog_entry: async (input) => {\n const args = objectInput('haven_submit_catalog_entry', input)\n return runTool(async () => {\n const submission = await haven.submitCatalogEntry(\n String(args.resource_url),\n typeof args.website === 'string' ? { website: args.website } : undefined,\n )\n return {\n id: submission.id,\n verify_token: submission.verifyToken,\n status: submission.status,\n }\n })\n },\n haven_list_receipts: async (input) => {\n const args = objectInput('haven_list_receipts', input)\n // #3128: same page shape as the hosted runtime.\n return runTool(async () =>\n haven.listReceiptsPage({ limit: args.limit, cursor: args.cursor, compact: args.compact === true }),\n )\n },\n haven_verify_receipt: async (input) => {\n const args = objectInput('haven_verify_receipt', input)\n return runTool(async () => verifyPaymentReceipt(args.receipt as PaymentReceipt))\n },\n\n haven_open_task_budget: async (input) => {\n const args = objectInput('haven_open_task_budget', input)\n return runTool(async () => {\n const token = await resolveTaskBudgetToken(haven, typeof args.token === 'string' ? args.token : undefined)\n const maxAmountAtomic = humanToAtomicOrNull(args.max_amount_human as string, token.decimals)\n if (maxAmountAtomic === null) {\n throw new HavenApiError(\n `max_amount_human (\"${args.max_amount_human}\") is not a valid decimal amount for ` +\n `${token.symbol} (${token.decimals} decimal places). Nothing was reserved.`,\n 400,\n )\n }\n const result = await haven.openTaskBudget({\n tokenAddress: token.address,\n maxAmountAtomic,\n ttlSeconds: Number(args.ttl_minutes) * 60,\n recipientAddress: typeof args.recipient === 'string' ? args.recipient : undefined,\n label: typeof args.label === 'string' ? args.label : undefined,\n })\n // #3419: the same recovery notice the hosted task-budget handoffs\n // carry (same builder, the SDK's TASK_SIGN_CONTEXT_VERSION) — an old\n // signer strips the unknown task_budget_id key exactly the same way\n // on the local surface.\n return {\n task_budget: result.taskBudget,\n next_action: 'sign',\n next_tool: 'mcp__haven-signer__haven_sign',\n next_arguments: { task_budget_id: result.taskBudget.id },\n signer_compatibility: taskSignerCompatibilityNotice(),\n }\n })\n },\n\n haven_close_task_budget: async (input) => {\n const args = objectInput('haven_close_task_budget', input)\n return runTool(async () => {\n const result = await haven.closeTaskBudget(args.task_budget_id as string)\n if (result.status === 'closed') {\n return { task_budget: result.taskBudget, status: 'closed' as const }\n }\n // #3419: same notice as the open handoff above — this result also\n // hands the agent to haven_sign { task_budget_id }.\n return {\n task_budget: result.taskBudget,\n next_action: 'sign',\n next_tool: 'mcp__haven-signer__haven_sign',\n next_arguments: { task_budget_id: args.task_budget_id },\n signer_compatibility: taskSignerCompatibilityNotice(),\n }\n })\n },\n\n // #3518: read ONE task budget by id, any status — the status check a\n // close/submit refusal's \"re-check the budget's status\" points at. The\n // SDK relays `GET /task-budgets/:id` (the backend route answers any\n // status) and a 404 carries the backend's own message through runTool.\n haven_get_task_budget: async (input) => {\n const args = objectInput('haven_get_task_budget', input)\n return runTool(async () => {\n const taskBudget = await haven.getTaskBudget(args.task_budget_id as string)\n return { task_budget: taskBudget }\n })\n },\n\n haven_submit: async (input) => {\n const args = objectInput('haven_submit', input)\n const hasTaskBudget = typeof args.task_budget_id === 'string' && args.task_budget_id.length > 0\n const hasSubBudget = typeof args.sub_budget_id === 'string' && args.sub_budget_id.length > 0\n const hasPayment = typeof args.payment_id === 'string' && args.payment_id.length > 0\n if ([hasTaskBudget, hasSubBudget, hasPayment].filter(Boolean).length !== 1) {\n return {\n success: false,\n code: 'INVALID_INPUT',\n message:\n 'haven_submit takes exactly one of payment_id, task_budget_id or sub_budget_id, never two ' +\n 'or none. Nothing was relayed.',\n }\n }\n if (hasSubBudget) {\n return submitSubBudgetTool(haven, args.sub_budget_id as string, args.signature as string)\n }\n return runTool(async () => {\n if (hasTaskBudget) {\n const result = await haven.submitTaskBudget(args.task_budget_id as string, args.signature as string)\n return {\n task_budget: result.taskBudget,\n status: result.status,\n ...(result.closeTxHash !== undefined ? { close_tx_hash: result.closeTxHash } : {}),\n }\n }\n // #3329: payment_id has no caller on the local surface today — the\n // local runtime signs and submits a direct payment inline through\n // haven.pay(), so a bare signature relay by payment_id has nothing to\n // do here. Declared for schema parity with the hosted surface\n // (captain contract §5); refuses rather than guessing at behavior.\n throw new HavenApiError(\n 'haven_submit with payment_id is not supported on the local MCP surface: haven_send ' +\n 'signs and submits a direct payment in one call, so there is no separate relay step. ' +\n 'Use haven_submit with task_budget_id or sub_budget_id to relay a budget open/close signature.',\n 400,\n )\n })\n },\n }\n\n async function resumeState(\n args: { payment_id?: string; resume_state?: unknown },\n rail: 'x402',\n ): Promise<X402ResumeState> {\n const state =\n args.resume_state ??\n (args.payment_id ? await haven.getResumeState(args.payment_id) : undefined)\n\n if (!state || typeof state !== 'object') {\n throw new HavenApiError(`haven_resume_${rail}_payment requires resume_state or payment_id.`, 400)\n }\n\n if ((state as { rail?: unknown }).rail !== rail) {\n throw new HavenApiError(`Resume state is not for the ${rail} rail.`, 409, state)\n }\n\n return state as X402ResumeState\n }\n}\n\n/**\n * RETAINED DELIBERATELY, and unreachable from any live rail (#2101). The same\n * reasoning as the hosted server's copy in\n * `packages/mcp-server/src/tools/support/quote-response.ts` (it was\n * `tools.ts` until #2808 moved the predicate into shared support):\n * no rail mints a payment-level `pending` / `pending_approval` any more (410 on\n * the legacy rail per #1986; 403/502 at prepare with nothing written on the\n * delegation rail; `approval_requests` dropped by #2055), but the one branch it\n * guards is fail-CLOSED — it stops the agent rather than continuing. What was\n * removed is the agent-visible promise: `MCP_INSTRUCTIONS` no longer tells a\n * model to branch on this status or to wait for an approval.\n */\nfunction isPendingApproval(status: string | undefined): boolean {\n return status === 'pending' || status === 'pending_approval'\n}\n\n/**\n * Build a structured wrong-tool ToolFailure pointing the agent at the right tool.\n * `code` should be 'WRONG_TOOL' (wrong operation entirely) or 'WRONG_RAIL' (right\n * operation but wrong payment protocol — x402 vs MPP).\n */\nfunction wrongTool(code: string, message: string, suggested_tool?: string): ToolFailure {\n return { success: false, code, message, suggested_tool }\n}\n\n/**\n * The one spelling — the #2366 window is over (#3411).\n *\n * Haven's wire convention is snake_case, and the hosted MCP surface already\n * follows it. This package shipped `idempotencyKey` and is PUBLISHED, so the\n * rename could not be a single release: an installed caller passing the old\n * name had to keep working for a window, and be told to move. Owner decision\n * 2026-09-06 — accept both, warn on the old, drop it later. The removal\n * condition: the warning first shipped on the `alpha`/`latest` channel in\n * `0.1.35-alpha.0` (npm, published 2026-09-07); `latest` is many releases\n * past it. The window is closed.\n *\n * `idempotencyKey` stays DECLARED in every schema above and is now REFUSED by\n * name with `IDEMPOTENCY_KEY_RENAMED`, rather than simply deleted from the\n * schema. Deleting it would let the MCP SDK's default `z.object` strip mode\n * silently drop an undeclared key before the handler ever ran — the exact\n * #2348 failure this refusal exists to prevent, since a dropped idempotency\n * key turns a retry into a second spend. Sending BOTH spellings is refused\n * the same way, because the legacy name being present at all is the refusal\n * condition — there is no longer a \"resolve the disagreement\" step.\n */\n/**\n * Parse the input and resolve the idempotency-key spelling, in one step (#2366).\n *\n * Both have to happen BEFORE `runTool`, because a `ToolFailure` returned from\n * inside its callback becomes `data` — a refusal wearing a success. But moving\n * `objectInput` out on its own lost the normalisation `runTool` was giving its\n * schema errors, which turned two \"rejects at schema level\" tests red. So the\n * pair is hoisted together and normalised here, and every caller gets the same\n * two exits: a failure to return, or args plus any warnings to carry.\n */\nfunction preflight<TName extends HavenMcpToolName>(\n name: TName,\n input: unknown,\n): { args: Record<string, any>; warnings: string[] } | ToolFailure {\n let args: Record<string, any>\n try {\n args = objectInput(name, input)\n } catch (err) {\n return normalizeError(err)\n }\n const idem = resolveIdempotencyKey(args)\n if ('success' in idem) return idem\n // #3411: carried under a name distinct from the refused `idempotencyKey`\n // input field, so it cannot be confused with — or accidentally re-trigger\n // — the refusal in `resolveIdempotencyKey` below. The snake_case key still\n // reaches the SDK from here.\n if (idem.key !== undefined) args = { ...args, resolvedIdempotencyKey: idem.key }\n return { args, warnings: idem.warnings }\n}\n\nexport function resolveIdempotencyKey(\n args: Record<string, unknown>,\n): { key?: string; warnings: string[] } | ToolFailure {\n const modern = typeof args.idempotency_key === 'string' ? args.idempotency_key : undefined\n const legacy = typeof args.idempotencyKey === 'string' ? args.idempotencyKey : undefined\n\n // #3411: the #2366 window is over. `idempotencyKey` is refused by NAME,\n // whether or not `idempotency_key` was also sent — the schema still\n // DECLARES it (see toolSchemas above) so the MCP SDK does not silently\n // strip it before this code runs (the #2348 failure); it is refused here\n // instead, before anything is contacted or spent.\n if (legacy !== undefined) {\n return {\n success: false,\n code: 'IDEMPOTENCY_KEY_RENAMED',\n message:\n 'idempotencyKey has been renamed to idempotency_key and is no longer accepted. ' +\n 'Send idempotency_key instead. Nothing was contacted or spent.',\n }\n }\n if (modern !== undefined) return { key: modern, warnings: [] }\n return { warnings: [] }\n}\n\n/** Build a JSON-RPC 2.0 tools/call envelope for an MCP merchant. */\nfunction buildMcpToolsCallEnvelope(\n toolName: string,\n args?: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n jsonrpc: '2.0',\n id: `haven-mcp-${Date.now()}`,\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: args ?? {},\n },\n }\n}\n\nfunction objectInput<TName extends HavenMcpToolName>(\n name: TName,\n input: unknown,\n): Record<string, any> {\n return z.object(toolSchemas[name]).parse(input ?? {})\n}\n\nfunction requestInit(input: { method?: string; headers?: Record<string, string>; body?: string }): RequestInit | undefined {\n if (!input.method && !input.headers && input.body === undefined) return undefined\n return {\n method: input.method,\n headers: input.headers,\n body: input.body,\n }\n}\n\nasync function runTool<T>(fn: () => Promise<T>, warnings: string[] = []): Promise<ToolPayload<T>> {\n try {\n const data = await fn()\n // #2366: attached only when there is something to say, so a caller that\n // sends the current spelling sees the response shape it always saw.\n return warnings.length > 0 ? { success: true, data, warnings } : { success: true, data }\n } catch (err) {\n return normalizeError(err)\n }\n}\n\nasync function responsePayload(response: Response): Promise<Record<string, unknown>> {\n const text = await response.text()\n return {\n status: response.status,\n statusText: response.statusText,\n headers: Object.fromEntries(response.headers.entries()),\n body: parseMaybeJson(text),\n }\n}\n\n/**\n * #3329: `haven_open_task_budget` takes a symbol-or-address plus a HUMAN\n * amount, but the SDK's `openTaskBudget` takes atomic units against a\n * resolved token address — the same split `haven_check_funds` bridges on the\n * hosted surface. This agent's own allowances are the source of truth for\n * which tokens it may spend at all, so a symbol resolves against THOSE (never\n * a guess), and decimals come from the SDK's own chain registry.\n */\nasync function resolveTaskBudgetToken(\n haven: HavenClient,\n symbolOrAddress: string | undefined,\n): Promise<{ address: string; symbol: string; decimals: number }> {\n const wanted = (symbolOrAddress ?? 'USDC').toLowerCase()\n const { allowances } = await haven.getAllowances()\n const isAddress = /^0x[0-9a-fA-F]{40}$/.test(wanted)\n const match = isAddress\n ? allowances.find((a) => a.tokenAddress.toLowerCase() === wanted)\n : allowances.find((a) => (a.tokenSymbol ?? '').toLowerCase() === wanted)\n if (!match) {\n const known = allowances.map((a) => `${a.tokenSymbol} (${a.tokenAddress})`)\n throw new HavenApiError(\n `token \"${symbolOrAddress ?? 'USDC'}\" is not the symbol or address of any allowance this ` +\n `agent holds${known.length > 0 ? ` (it holds: ${known.join(', ')})` : ' (it holds none)'}. ` +\n 'Nothing was reserved.',\n 400,\n )\n }\n const resolved = resolveTokenFromAddress(match.tokenAddress)\n return { address: match.tokenAddress, symbol: match.tokenSymbol, decimals: resolved?.decimals ?? 6 }\n}\n\n/** A plain decimal string (\"5\", \"0.25\") to atomic units, or null if it does not fit `decimals`. */\nfunction humanToAtomicOrNull(human: string, decimals: number): string | null {\n if (!/^[0-9]+(\\.[0-9]+)?$/.test(human)) return null\n const [whole, frac = ''] = human.split('.')\n if (frac.length > decimals) return null\n const atomic = BigInt(whole || '0') * 10n ** BigInt(decimals) + BigInt(frac.padEnd(decimals, '0') || '0')\n return atomic.toString()\n}\n\nfunction parseMaybeJson(text: string): unknown {\n if (!text) return null\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\n/**\n * #2983: the local-flow counterpart of mcp-server's `HostedToolError` for the\n * `MERCHANT_NOT_READY` failure — carries the same wire fields\n * (`code`, `next_action`, `retry_with_new_quote`) `normalizeError` below\n * reads off it. Not a `HavenApiError`: that class's `code` is hardcoded to\n * `'API_ERROR'`, and this failure needs its own code on the wire.\n */\nclass MerchantNotReadyError extends Error {\n readonly code = AgentPaymentFailureCode.MerchantNotReady\n readonly statusCode = 503\n readonly nextAction = AgentPaymentNextAction.StopAndTellUser\n // Genuinely retryable — unlike a rejection, nothing about THIS call was\n // wrong; the merchant's own wallet needs to recover first.\n readonly retryWithNewQuote = true\n\n constructor(message: string) {\n super(message)\n this.name = 'MerchantNotReadyError'\n }\n}\n\n/**\n * #2983: mirrors mcp-server's `merchantNotReadyErrorFor` (`mcp-context.ts`)\n * for the local runtime. Only the merchant's OWN refusal shape — `503\n * { error: 'merchant_not_ready', reason_code, settlements_remaining,\n * retry_after_s }` — maps here. A bare 503 (a load balancer, an HTML outage\n * page, a non-JSON body) is not a capacity signal and keeps going through\n * the #1301 discovery path. `response.clone()` because the caller still\n * needs to read the ORIGINAL response (for `discoveryMissError`'s status)\n * when this returns null.\n */\nasync function merchantNotReadyErrorFor(response: Response): Promise<MerchantNotReadyError | null> {\n if (response.status !== 503) return null\n let body: unknown\n try {\n body = await response.clone().json()\n } catch {\n return null\n }\n if (!body || typeof body !== 'object' || (body as Record<string, unknown>).error !== 'merchant_not_ready') {\n return null\n }\n const { reason_code, settlements_remaining, retry_after_s } = body as Record<string, unknown>\n return new MerchantNotReadyError(\n 'The merchant refused this call: it cannot settle a payment right now' +\n (typeof reason_code === 'string' ? ` (reason_code: ${reason_code})` : '') +\n (typeof settlements_remaining === 'number'\n ? `, settlements_remaining: ${settlements_remaining}`\n : '') +\n '. No payment was created.' +\n (typeof retry_after_s === 'number'\n ? ` Retry after approximately ${retry_after_s}s.`\n : ' This is often transient; retry later.'),\n )\n}\n\n/**\n * #1301: the local-flow counterpart of mcp-server's `withDiscoveryGuidance`\n * (kept there, not shared — that helper rewrites a thrown `HavenApiError`;\n * this one builds a fresh failure from a non-ok `Response`, since the local\n * `haven.fetch()` idiom never throws for a non-402 answer). Keeps the\n * original probe status authoritative, but tells the agent what discovery\n * tried — the pre-#1301 local failure mode was a silent pass-through of\n * whatever the base path served.\n */\nfunction discoveryMissError(\n response: Response,\n merchantUrl: string,\n discovered: string | null,\n discoveredFromUrl?: string,\n): HavenApiError {\n const base = discoveredFromUrl\n ? `Merchant call to ${merchantUrl} failed with HTTP ${response.status} ` +\n `(at the DISCOVERED endpoint ${merchantUrl}, resolved from ${discoveredFromUrl} ` +\n `via the merchant discovery document).`\n : `Merchant call to ${merchantUrl} failed with HTTP ${response.status}.`\n const guidance = discoveredFromUrl\n ? ''\n : discovered\n ? ` Same-origin discovery resolved the same URL (${discovered}), which still did not answer successfully.`\n : ` No same-origin discovery document was found at /.well-known/haven-demo-merchant or /. ` +\n `If ${merchantUrl} is a base merchant URL, pass the exact MCP endpoint instead (often <origin>/mcp).`\n return new HavenApiError(`${base}${guidance}`, response.status || 400)\n}\n\nfunction normalizeError(err: unknown): ToolFailure {\n if (err instanceof MerchantNotReadyError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n nextAction: err.nextAction,\n next_action: err.nextAction,\n retry_with_new_quote: err.retryWithNewQuote,\n // #3103: the local runtime's one decision site — no tool can act until\n // the merchant recovers; the message carries retry_after_s.\n next_tool_omitted_reason: 'the merchant needs to recover first; re-quote after the retry_after_s in the message',\n }\n }\n\n if (err instanceof HavenPaymentStateError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n status: err.status,\n phase: err.phase,\n nextAction: err.nextAction,\n next_action: err.nextAction,\n resume_state: err.resumeState,\n body: err.body,\n }\n }\n\n if (err instanceof HavenSigningError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n }\n }\n\n if (err instanceof HavenApiError) {\n const body = err.body as Record<string, unknown> | undefined\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n phase: stringOrUndefined(body?.phase),\n nextAction:\n stringOrUndefined(body?.nextAction) ??\n stringOrUndefined(body?.next_action) ??\n AgentPaymentNextAction.StopAndTellUser,\n next_action:\n stringOrUndefined(body?.nextAction) ??\n stringOrUndefined(body?.next_action) ??\n AgentPaymentNextAction.StopAndTellUser,\n // #3303: a backend refusal that already names why no tool follows (the\n // 426 `client_outdated` does) keeps that reason at the top level.\n ...(typeof body?.next_tool_omitted_reason === 'string'\n ? { next_tool_omitted_reason: body.next_tool_omitted_reason }\n : {}),\n body: err.body,\n }\n }\n\n if (err instanceof HavenError) {\n return {\n success: false,\n code: err.code,\n message: err.message,\n statusCode: err.statusCode,\n paymentId: err.paymentId,\n }\n }\n\n return {\n success: false,\n code: 'UNKNOWN_ERROR',\n message: err instanceof Error ? err.message : String(err),\n nextAction: AgentPaymentNextAction.StopAndTellUser,\n next_action: AgentPaymentNextAction.StopAndTellUser,\n // #3103: the second local decision site — nothing structured can follow an\n // error this runtime did not recognise.\n next_tool_omitted_reason: 'an error this runtime does not recognise; tell the user what the message says',\n }\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined\n}\n","import { createHash } from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport type { HavenAllowance, HavenAllowanceSummary, HavenClient } from '@haven_ai/sdk'\nimport { formatTokenAmount, resolveTokenBySymbol } from '@haven_ai/sdk'\nimport { toolDescriptions, toolSchemas, type HavenMcpToolName } from './tools.js'\n\n/**\n * First-launch consent gate for the Haven MCP server.\n *\n * Why this exists (option A of issue #163): an agent runtime that loads a\n * Haven credential file is about to expose Haven payment tools to a model.\n * Before the server starts taking JSON-RPC calls we want the operator to\n * acknowledge — exactly once per credential + tool set — what those tools\n * can do and what the on-chain budget actually is. The agent's budget\n * delegation and its caveat enforcers remain the policy primitive; this gate\n * is informational rather than enforcement.\n *\n * #2086: the copy below used to describe the legacy Safe AllowanceModule and\n * an approval queue that would catch an over-budget payment. Both are gone —\n * the AllowanceModule rail is retired (#1986) and the approval queue's table\n * with it (#2055) — so the gate was promising an operator a human backstop\n * that does not exist. It is now one accurate description of the delegation\n * rail rather than rail-aware prose, because the delegation rail is the only\n * rail that can pay at all: a legacy account gets HTTP 410 from the payment\n * paths, so a second branch here would describe a state no reader can be in.\n *\n * Resolution:\n * - `HAVEN_MCP_ACK=<hash>` env var matching the current consent hash → pass.\n * - `HAVEN_MCP_ACK=skip` → pass (intended for CI / scripted setups).\n * - sidecar file `<credentials>.ack.json` containing `{ ack: <hash> }` → pass.\n * - `--ack` CLI flag → write the sidecar file, print the consent block, pass.\n * - otherwise → print the consent block to stderr and exit non-zero.\n *\n * The hash binds the api-key prefix to the registered tool set and the\n * agent's current allowance summary, so a configuration change re-triggers\n * the prompt.\n */\n\nexport interface ConsentInput {\n apiKeyPrefix: string\n /** Haven API base URL the credential will hit. */\n apiUrl?: string\n /** Agent identity from the credential file, when present. */\n agentId?: string\n /** Haven wallet the agent spends from. */\n accountAddress?: string\n /** Agent's delegate EOA — the local signer. */\n delegateAddress?: string\n /** Chain the agent operates on. */\n chainId?: number\n toolNames: readonly HavenMcpToolName[]\n /**\n * #3410: every amount here is ATOMIC (smallest on-chain units, e.g. 6\n * decimals for USDC — `1000000` is one USDC, never \"1000000 tokens\"). Both\n * producers agree: the live read takes `onchain.amount`, and the seed takes\n * the credential file's `allowance_amount` — both atomic. `renderConsentBlock`\n * converts for display through the token registry and falls back to an\n * explicit `(atomic units)` label when the token is unknown; the consent\n * hash deliberately covers the atomic string, so a display change alone\n * never re-prompts the operator.\n *\n * Known limitation (#3410, stated not fixed): the seed is setup-time data.\n * If the wallet owner edits the budget after setup AND the live read then\n * fails, the screen shows the stale seed budget as if it were current.\n */\n allowanceSummary: readonly { token: string; amount: string; resetMinutes: number | null }[]\n}\n\nexport interface ConsentDecision {\n /** True if the gate is satisfied and the server may start. */\n ok: boolean\n /** Hash representing the current consent surface. */\n hash: string\n /** Reason the gate accepted (or rejected) the run. */\n reason:\n | 'env_var_match'\n | 'env_var_skip'\n | 'ack_file_match'\n | 'wrote_ack_file'\n | 'env_var_mismatch'\n | 'no_acknowledgement'\n}\n\nexport interface ConsentOptions {\n /** Path to the credential file; used to locate the sidecar `<path>.ack.json`. */\n credentialsPath?: string\n /** When true, write the sidecar file with the current hash and accept. */\n writeAck?: boolean\n /** Override the environment lookup (testing). */\n env?: Record<string, string | undefined>\n /** Override the writable stream the consent block is printed to (testing). */\n out?: { write: (chunk: string) => unknown }\n}\n\nexport function computeConsentHash(input: ConsentInput): string {\n const allowanceCanonical = [...input.allowanceSummary]\n .map((a) => `${a.token}:${a.amount}:${a.resetMinutes ?? 'none'}`)\n .sort()\n .join('|')\n const toolCanonical = [...input.toolNames].sort().join(',')\n // Identity fields are included in the hash so swapping the credential\n // to a different Haven wallet / delegate / chain — even one with an\n // identical allowance set — invalidates the prior sidecar and re-prompts\n // the operator. Addresses are normalised to lowercase so casing changes\n // in the credential file don't gratuitously re-prompt.\n const identity = [\n input.apiKeyPrefix,\n input.apiUrl ?? '',\n input.agentId ?? '',\n (input.accountAddress ?? '').toLowerCase(),\n (input.delegateAddress ?? '').toLowerCase(),\n input.chainId ?? '',\n ].join('|')\n return createHash('sha256')\n .update(`${identity}\\n${toolCanonical}\\n${allowanceCanonical}`)\n .digest('hex')\n .slice(0, 16)\n}\n\nexport function renderConsentBlock(input: ConsentInput, hash: string): string {\n const lines: string[] = [\n '',\n '────────────────────────────────────────────────────────────',\n 'Haven MCP server — first-launch consent',\n '────────────────────────────────────────────────────────────',\n '',\n `Credential: ${input.apiKeyPrefix}…`,\n ]\n if (input.apiUrl) lines.push(`Haven API: ${input.apiUrl}`)\n if (input.agentId) lines.push(`Agent ID: ${input.agentId}`)\n if (input.accountAddress) lines.push(`Haven wallet: ${input.accountAddress}`)\n if (input.delegateAddress) lines.push(`Delegate (local signer): ${input.delegateAddress}`)\n if (typeof input.chainId === 'number') lines.push(`Chain ID: ${input.chainId}`)\n lines.push('')\n lines.push('Confirm these match the Haven wallet and chain you intend the')\n lines.push('agent runtime to use. The delegate above is the only key that')\n lines.push('signs payments — it lives in this process, not on Haven\\'s backend.')\n lines.push('')\n lines.push('Tools this server will expose to your agent runtime:')\n for (const name of input.toolNames) {\n lines.push(` • ${name}`)\n lines.push(` ${toolDescriptions[name]}`)\n }\n lines.push('')\n if (input.allowanceSummary.length === 0) {\n lines.push('On-chain budget: none configured.')\n lines.push(' Until the wallet owner grants this agent a budget in Haven,')\n lines.push(' every payment it attempts is declined on-chain.')\n } else {\n lines.push('On-chain budget (the real spend gate — enforced by the agent\\'s')\n lines.push('signed delegation, not by Haven):')\n for (const a of input.allowanceSummary) {\n const reset = a.resetMinutes ? ` per ${a.resetMinutes} min` : ' (no reset)'\n lines.push(` • up to ${describeBudgetAmount(a, input.chainId)}${reset}`)\n }\n }\n lines.push('')\n lines.push('Anything above the on-chain budget is declined before any money')\n lines.push('moves — it is not queued, and no one is asked to review it. If the')\n lines.push('agent needs more room, the wallet owner grants or raises the budget')\n lines.push('in Haven. Revoking the agent on-chain disables every MCP tool that')\n lines.push('would spend.')\n lines.push('')\n lines.push(`Consent hash: ${hash}`)\n lines.push('')\n lines.push('To acknowledge, EITHER:')\n lines.push(` • set HAVEN_MCP_ACK=${hash} in this process\\'s environment, OR`)\n lines.push(' • re-run with --ack to write the acknowledgement next to your')\n lines.push(' credential file (sidecar <credentials>.ack.json).')\n lines.push('')\n lines.push('────────────────────────────────────────────────────────────')\n lines.push('')\n return lines.join('\\n')\n}\n\n/** Resolve the consent gate. Does not exit the process; the caller decides. */\nexport async function ensureConsent(\n input: ConsentInput,\n options: ConsentOptions = {},\n): Promise<ConsentDecision> {\n const env = options.env ?? process.env\n const out = options.out ?? process.stderr\n const hash = computeConsentHash(input)\n\n // 1) Explicit skip — for CI and scripted environments.\n if (env.HAVEN_MCP_ACK === 'skip') {\n return { ok: true, hash, reason: 'env_var_skip' }\n }\n\n // 2) Env var hash match.\n if (typeof env.HAVEN_MCP_ACK === 'string' && env.HAVEN_MCP_ACK.length > 0) {\n if (env.HAVEN_MCP_ACK === hash) {\n return { ok: true, hash, reason: 'env_var_match' }\n }\n out.write(renderConsentBlock(input, hash))\n out.write(\n `HAVEN_MCP_ACK was set but did not match the current consent hash.\\n` +\n `Expected: ${hash}\\n` +\n `Got: ${env.HAVEN_MCP_ACK}\\n` +\n `Re-acknowledge with the new hash above, or run with --ack.\\n\\n`,\n )\n return { ok: false, hash, reason: 'env_var_mismatch' }\n }\n\n // 3) Sidecar ack file (only meaningful when we loaded from a file).\n const ackPath = sidecarPath(options.credentialsPath)\n if (ackPath) {\n const stored = await readAckFile(ackPath)\n if (stored?.ack === hash) {\n return { ok: true, hash, reason: 'ack_file_match' }\n }\n }\n\n // 4) --ack: write the sidecar and accept.\n if (options.writeAck && ackPath) {\n out.write(renderConsentBlock(input, hash))\n await writeAckFile(ackPath, hash)\n out.write(`Wrote acknowledgement to ${ackPath}\\n\\n`)\n return { ok: true, hash, reason: 'wrote_ack_file' }\n }\n\n // 5) Otherwise: print and refuse.\n out.write(renderConsentBlock(input, hash))\n return { ok: false, hash, reason: 'no_acknowledgement' }\n}\n\nfunction sidecarPath(credentialsPath?: string): string | null {\n if (!credentialsPath) return null\n return resolve(`${credentialsPath}.ack.json`)\n}\n\nasync function readAckFile(path: string): Promise<{ ack?: string } | null> {\n try {\n const raw = await readFile(path, 'utf8')\n const parsed = JSON.parse(raw) as { ack?: unknown }\n return { ack: typeof parsed.ack === 'string' ? parsed.ack : undefined }\n } catch {\n return null\n }\n}\n\nasync function writeAckFile(path: string, hash: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(\n path,\n JSON.stringify({ ack: hash, at: new Date().toISOString() }, null, 2),\n 'utf8',\n )\n}\n\nexport interface CredentialIdentitySeed {\n apiKey: string\n apiUrl?: string\n agentId?: string\n /** Account address from the credential file, used as a fallback. */\n accountAddress?: string\n /** Delegate address from the credential file, used before live allowance metadata is available. */\n delegateAddress?: string\n /** Chain from the credential file, used as a fallback. */\n chainId?: number\n /**\n * Intended agent budget from the setup flow, used before on-chain approval\n * is visible. #3410: every amount is ATOMIC — the connector writes the\n * credential file's `allowance_amount` straight from the setup response's\n * `agent_budget`, and the backend puts `budget_atomic` there.\n */\n allowanceSummary?: readonly { token: string; amount: string; resetMinutes: number | null }[]\n}\n\n/**\n * Build the consent input from credential identity plus a live allowance\n * lookup. The on-chain (or configured) allowance is what the operator\n * actually cares about — that's the real spend ceiling — but we also bind\n * the hash to the Haven wallet / delegate / chain so a credential swap\n * cannot quietly reuse a prior sidecar acknowledgement.\n *\n * If `getAllowances()` fails (e.g. backend unreachable on first launch) we\n * fall through to whatever identity fields the credential file provided,\n * so the operator at least sees the tool list and the api-key prefix.\n */\nexport async function consentInputFromClient(\n haven: HavenClient,\n seed: CredentialIdentitySeed,\n toolNames: readonly HavenMcpToolName[],\n): Promise<ConsentInput> {\n let allowanceSummary: ConsentInput['allowanceSummary'] = seed.allowanceSummary ?? []\n let accountAddress = seed.accountAddress\n let delegateAddress: string | undefined = seed.delegateAddress\n let chainId: number | undefined = seed.chainId\n\n try {\n const summary = await haven.getAllowances()\n const list: HavenAllowance[] = isAllowanceSummary(summary)\n ? summary.allowances\n : Array.isArray(summary)\n ? (summary as HavenAllowance[])\n : []\n if (isAllowanceSummary(summary)) {\n accountAddress = summary.accountAddress ?? accountAddress\n delegateAddress = summary.delegateAddress\n chainId = typeof summary.chainId === 'number' ? summary.chainId : chainId\n }\n const liveAllowanceSummary = list.map((a) => ({\n token: a.tokenSymbol ?? 'UNKNOWN',\n // #3410: `onchain.amount` is the atomic budget (`budget_atomic` on the\n // backend). The old `a.configuredAmount` fallback here was unreachable\n // — `onchain` is required in the SDK types and dereferenced\n // unconditionally, so a response without it throws into the seed path —\n // and it was the one HUMAN-decimal value in this chain; a human number\n // must never reach an atomic field. '0' keeps the (defensive) shape for\n // a malformed onchain object without inventing a unit.\n amount: a.onchain?.amount ?? '0',\n resetMinutes:\n typeof a.onchain?.resetTimeMin === 'number'\n ? a.onchain.resetTimeMin\n : typeof a.resetPeriodMin === 'number'\n ? a.resetPeriodMin\n : null,\n }))\n allowanceSummary = liveAllowanceSummary\n } catch {\n // Identity falls back to what the credential file gave us.\n }\n\n return {\n apiKeyPrefix: derivePrefix(seed.apiKey),\n apiUrl: seed.apiUrl,\n agentId: seed.agentId,\n accountAddress,\n delegateAddress,\n chainId,\n toolNames,\n allowanceSummary,\n }\n}\n\nfunction isAllowanceSummary(value: unknown): value is HavenAllowanceSummary {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'allowances' in value &&\n Array.isArray((value as { allowances: unknown }).allowances)\n )\n}\n\n/**\n * Use the leading characters of the api key (which already begins with the\n * non-secret `sk_agent_` prefix) as a stable, low-information identifier.\n * Twelve characters is enough to disambiguate credentials in front of a\n * human but not enough to reveal the secret.\n */\nfunction derivePrefix(apiKey: string): string {\n return apiKey.slice(0, 12)\n}\n\n/**\n * #3410: one budget, one display form. The consent screen is the surface\n * whose job is informed consent — an atomic number printed as whole tokens\n * overstates the budget a millionfold — so every amount is rendered in whole\n * tokens when the token is known (`resolveTokenBySymbol` over the same\n * registry the SDK's address-based reads use) and carries an explicit\n * `(atomic units)` label when it is not, mirroring connect's\n * `describeApprovedBudget` fallback. This is DISPLAY ONLY: the consent hash\n * keeps covering the raw atomic string, byte-identical to what every\n * installed sidecar acknowledged before this change.\n */\nfunction describeBudgetAmount(a: { token: string; amount: string }, chainId: number | undefined): string {\n const token = chainId === undefined ? null : resolveTokenBySymbol(chainId, a.token)\n if (!token) return `${a.amount} ${a.token} (atomic units)`\n return `${formatTokenAmount(a.amount, token.decimals)} ${a.token}`\n}\n\n/** Convenience: the canonical tool list registered by the server. */\nexport function registeredToolNames(): HavenMcpToolName[] {\n return Object.keys(toolSchemas) as HavenMcpToolName[]\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n HavenClient,\n havenClientIdentity,\n isSupportedNodeVersion,\n unsupportedNodeVersionMessage,\n type HavenClientUpdate,\n} from '@haven_ai/sdk'\nimport { loadCredentials, type HavenCredentialFile } from './credentials.js'\nimport {\n createToolHandlers,\n toolDescriptions,\n toolSchemas,\n type HavenMcpToolName,\n type ToolPayload,\n} from './tools.js'\nimport {\n consentInputFromClient,\n ensureConsent,\n registeredToolNames,\n type ConsentDecision,\n} from './consent.js'\n\nexport interface HavenMcpServerOptions {\n credentialsPath?: string\n identityPath?: string\n signerPath?: string\n credentials?: HavenCredentialFile\n /**\n * When true, write the consent sidecar file (`<credentials>.ack.json`)\n * with the current consent hash and proceed. Surfaced via the `--ack`\n * CLI flag.\n */\n writeAck?: boolean\n /**\n * When true, skip the consent gate entirely. Reserved for tests and\n * controlled embedding — production CLIs should not set this.\n */\n skipConsent?: boolean\n /** Overridable so the Node-floor refusal is testable without spawning a Node. */\n nodeVersion?: string\n}\n\nexport interface ResolvedHavenClient {\n client: HavenClient\n credentials: HavenCredentialFile\n}\n\nexport async function createHavenClient(options: HavenMcpServerOptions = {}): Promise<HavenClient> {\n const { client } = await resolveHavenClient(options)\n return client\n}\n\nexport async function resolveHavenClient(options: HavenMcpServerOptions = {}): Promise<ResolvedHavenClient> {\n // The choke point (#1161 review): `runStdioServer`, `createHavenClient` and\n // `createHavenMcpServer` all funnel through here, and the client built below\n // is delegate-key-bound — `pay()`, `sign()` and the x402 paths activate the\n // moment `delegateKey` is set. Guarding only the stdio entrypoint would leave\n // the embedding constructors reaching a signing-capable client on an\n // unsupported runtime, which is this issue's own bug one layer down.\n assertSupportedNodeVersion(options.nodeVersion)\n\n const credentialSource = options.credentialsPath || options.identityPath || options.signerPath\n ? {\n credentialsPath: options.credentialsPath,\n identityPath: options.identityPath,\n signerPath: options.signerPath,\n }\n : undefined\n const credentials = options.credentials ?? await loadCredentials(credentialSource)\n const client = new HavenClient({\n apiKey: credentials.apiKey,\n delegateKey: credentials.delegateKey,\n baseUrl: credentials.apiUrl,\n // #3303: name this package, not the SDK inside it, so the backend's\n // update hint and refusal speak about what the user actually installed.\n clientIdentity: havenClientIdentity(MCP_NAME, MCP_VERSION),\n })\n return { client, credentials }\n}\n\nexport async function createHavenMcpServer(options: HavenMcpServerOptions = {}): Promise<McpServer> {\n const haven = await createHavenClient(options)\n return buildMcpServer(haven)\n}\n\n/**\n * Build an MCP server bound to the supplied Haven client.\n *\n * Each tool dispatch is wrapped in `haven.withRequestContext` so every\n * Haven API request the dispatch issues carries `X-Haven-MCP-Tool: <name>`\n * — and *only* that dispatch's requests see the header. The SDK uses an\n * `AsyncLocalStorage` for the context, so two tool calls running\n * concurrently cannot leak headers into each other and the backend\n * `agent_tool_invocations` rows are always attributed to the right tool.\n */\nexport const MCP_NAME = '@haven_ai/mcp'\nexport const MCP_VERSION = '0.8.0-alpha.0'\n\n/**\n * MCP `instructions` — the critical path, surfaced to the model at\n * `initialize`. Shorter than the hosted server's: this runtime signs\n * in-process with the delegate key it holds, so there is no separate\n * haven-signer namespace or payment_id signing step to describe. Kept free\n * of any version literal; a guard test in `server.test.ts` pins that.\n */\nexport const MCP_INSTRUCTIONS = [\n 'Haven local MCP server: signs in-process with the delegate key it holds on',\n 'this machine — the key never leaves this process. Call haven_get_agent',\n 'first, every session: identity, readiness, and live remaining budget in',\n 'one call. Do not guess the wallet, network, or budget.',\n '',\n 'To pay: haven_discover_tools to find a payable service, then',\n 'haven_pay_mcp_tool for MCP merchants or haven_pay_x402 for any x402',\n 'paywall. Tool responses carry next_action (nextAction is the same value, kept one more',\n 'release) and, when no tool follows, next_tool_omitted_reason — follow them; description prose',\n 'is fallback, not the source of truth.',\n '',\n 'A payment outside the agent budget is declined before any money moves. Haven',\n 'holds no approval queue, so there is nothing to poll and no approval will',\n 'ever arrive for it. On a decline, or on any status you do not',\n 'recognise, stop and tell the user: do not retry or re-sign, and ask them to',\n 'grant or raise the budget in Haven. Spend authority is enforced on-chain by',\n 'the user\\'s account; Haven never holds keys and cannot override it.',\n].join('\\n')\n\nexport function buildMcpServer(haven: HavenClient): McpServer {\n const server = new McpServer(\n {\n name: MCP_NAME,\n version: MCP_VERSION,\n },\n { instructions: MCP_INSTRUCTIONS },\n )\n\n const handlers = createToolHandlers(haven)\n const registerTool = (server as any).tool.bind(server)\n for (const name of Object.keys(toolSchemas) as HavenMcpToolName[]) {\n registerTool(\n name,\n toolDescriptions[name],\n toolSchemas[name],\n async (args: unknown) =>\n haven.withRequestContext({ 'X-Haven-MCP-Tool': name }, async () =>\n toMcpResult(withClientUpdate(await handlers[name](args), haven.clientUpdate())),\n ),\n )\n }\n\n return server\n}\n\n/**\n * Refuse to start on an unsupported Node (#1161).\n *\n * Same reasoning as the signer's identical guard: install-time enforcement\n * cannot see a Node downgrade after setup, or a version manager handing the\n * agent runtime a different Node than the shell that connected. The local MCP\n * server drives payment construction against the signer, so it is held to the\n * package's declared floor rather than whatever happens to boot.\n */\nexport function assertSupportedNodeVersion(nodeVersion: string = process.versions.node): void {\n if (isSupportedNodeVersion(nodeVersion)) return\n const err: NodeJS.ErrnoException = new Error(\n unsupportedNodeVersionMessage({ subject: 'The Haven MCP server', nodeVersion }),\n )\n err.code = 'HAVEN_MCP_UNSUPPORTED_NODE'\n throw err\n}\n\nexport async function runStdioServer(options: HavenMcpServerOptions = {}): Promise<void> {\n // Asserted inside resolveHavenClient — the choke point every key-bound path\n // shares — so it still runs here, before credentials are read.\n const { client: haven, credentials } = await resolveHavenClient(options)\n\n if (!options.skipConsent) {\n const decision = await runConsentGate(haven, credentials, options)\n if (!decision.ok) {\n // The consent block has already been printed by `ensureConsent`.\n const err: NodeJS.ErrnoException = new Error(\n decision.reason === 'env_var_mismatch'\n ? 'Haven MCP consent acknowledgement does not match the current configuration.'\n : 'Haven MCP server requires a one-time consent acknowledgement before starting.',\n )\n err.code = 'HAVEN_MCP_NO_CONSENT'\n throw err\n }\n }\n\n const server = buildMcpServer(haven)\n await server.connect(new StdioServerTransport())\n}\n\nexport async function runConsentGate(\n haven: HavenClient,\n credentials: HavenCredentialFile,\n options: HavenMcpServerOptions,\n): Promise<ConsentDecision> {\n const toolNames = registeredToolNames()\n const input = await consentInputFromClient(\n haven,\n {\n apiKey: credentials.apiKey,\n apiUrl: credentials.apiUrl,\n agentId: credentials.agentId,\n accountAddress: credentials.accountAddress,\n delegateAddress: credentials.delegateAddress,\n chainId: credentials.chainId,\n allowanceSummary: credentials.allowanceSummary,\n },\n toolNames,\n )\n // Prefer the path actually used to load credentials (covers\n // HAVEN_CREDENTIALS as well as --credentials). If neither file path is\n // available the operator must use HAVEN_MCP_ACK; --ack has nowhere to\n // write a sidecar in that case.\n const credentialsPath = options.identityPath ?? options.credentialsPath ?? credentials.sourcePath\n return ensureConsent(input, {\n credentialsPath,\n writeAck: options.writeAck,\n })\n}\n\n/**\n * #3303: attach the backend's `client_update` hint — the one THIS dispatch's\n * own requests received — to the tool result, so an agent on an outdated\n * runtime reads the update command on the call it made, success or failure.\n */\nexport function withClientUpdate(payload: ToolPayload, hint: HavenClientUpdate | undefined): ToolPayload {\n if (!hint || payload.client_update) return payload\n return { ...payload, client_update: hint }\n}\n\nfunction toMcpResult(payload: ToolPayload) {\n return {\n isError: !payload.success,\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(payload, null, 2),\n },\n ],\n }\n}\n"]}
|