Skip to content

Support Kernel wallet payment methods and payment_request items - #261

Draft
hiroTamada wants to merge 1 commit into
mainfrom
hypeship/kernel-wallet-payment-methods
Draft

hiroTamada wants to merge 1 commit into
mainfrom
hypeship/kernel-wallet-payment-methods

Conversation

@hiroTamada

Copy link
Copy Markdown
Contributor

Warning

Blocked on the @onkernel/sdk 0.133.0 release. This code is written against the 0.133.0 types, but 0.133.0 is not published yet; package.json and bun.lock still pin 0.132.0. A git pin to the release PR head does not install cleanly with bun (the SDK's prepare build is skipped, so the package has no dist/), so the dependency is left unchanged. Until the bump, CI's Type check fails on the new SDK types (payment_request items, the add_payment_method / remove_payment_method operation params); tests pass on both versions. Before merge: bun add @onkernel/sdk@0.133.0, commit package.json + bun.lock, and re-run CI.

Summary

The Kernel API now supports multiple cards per Kernel wallet and payment_request purchase items, gated per organization. This updates the vault tools to match, keeping the original single-card Kernel wallet contract working for organizations without the flags.

Wallets (manage_vault_wallets)

  • New add_payment_method and remove_payment_method (with payment_method_id) actions. Each one fetches the wallet first and submits only if it is a Kernel wallet that advertises the operation, matching how authorize works in manage_vault_cards. The result returns the projected payment method or removal status, a payment_methods observation hint, and guidance.
  • add_payment_method returns the card_enrollment url, but the embedded capture_token is still never returned.
  • Errors go through the Kernel error path, so 403 insufficient_scope, 409 purchase_unresolved / provider_revocation_pending and 429 Retry-After pass through.
  • Updated the description: a Kernel wallet may be connected and empty; enrollment urls go only to the intended cardholder; removal needs user confirmation and is not proof a payment did not occur; add and remove need vaults:write.
  • destructiveHint is now true, because removal deletes a stored card.

Cards (manage_vault_cards)

  • New item_type (card by default, or payment_request) for create/update. Link and Kernel can create payment_request items; AgentCard is refused locally. Updates to a payment request send type: payment_request; card updates still omit type.
  • The Kernel card spec accepts an optional payment_method_id. If omitted, the API selects the default card card and never another card. A Kernel payment_request requires it.
  • authorize also accepts payment_request items.

Responses and manage_vault_items

  • Payment methods now project status, status_reason, expires_at and action (name, url, expires_at, without capture_token). Item state projects payment_method_id and funding_status. Event data projects item_type, provider and payment_method_id_present.
  • Operation results project payment_method and payment_method_id, so invoking add_payment_method / remove_payment_method through manage_vault_items renders and gets guidance.
  • payment_request items are treated like cards in guidance, invocation hints, recovery_required handling, Link authorize error mapping and the confirm_transaction amount/currency check.
  • A remove_payment_method hint lists required_inputs: ["payment_method_id"].
  • Kernel wallet guidance covers empty wallets, method statuses and removal. It now says reconnect_required wallets refuse payment and deletion until upgraded, per the current API description. Kernel purchase guidance explains funding_status.
  • Updated docs/vault-payments.md.

Entitlements, tool names, registration, analytics and deprecated-params handling do not enumerate vault operations or item types, so they are unchanged.

Tests

Run locally with @onkernel/sdk 0.133.0 built from the release PR head and swapped into node_modules, without committing it:

  • bunx tsc --noEmit --incremental false: passes on 0.133.0. On the pinned 0.132.0 it fails only where the new SDK types are used.
  • bun test: 1161 pass, 0 fail on both 0.133.0 and 0.132.0.
  • bun run check:managed-auth-app: passes.
  • bunx prettier --check on changed files: passes. Repo-wide bun run format:check fails only on AGENTS.md, which this PR does not touch.
  • git diff --check: clean.
  • bun run lint was not run; it is broken under Next.js 16 per AGENTS.md.

Not run: no live MCP calls against the Kernel API with the flags on.

@vercel

vercel Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
mcp Error Error Oct 28, 2026 2:27pm UTC

@rgarcia rgarcia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. This fixes a real gap I hit on the current MCP: with a KERNEL wallet that advertises add_payment_method, there was no way through MCP to (a) get the card_enrollment url, because paymentMethodFields and vaultOperationResultFields dropped it, or (b) create a KERNEL card, because the strict kernelCardSpecSchema rejected payment_method_id, which the API requires when the wallet has no default card. The flow had to finish through the CLI. This PR closes both.

The SDK blocker is gone. main is on @onkernel/sdk 0.141.0, so the 0.133.0 pin isn't needed. I merged current main into this branch locally (no conflicts): tsc --noEmit is clean and bun test gives 1168 pass, 0 fail. CI is only red because it last ran against 0.132.0.

To get it across the line:

  1. Merge or rebase main and push so CI reruns against 0.141.0.
  2. Drop the "Blocked on 0.133.0" warning and the before-merge bun add step from the description.

Non-blocking notes:

  • paymentMethodFields.action lists expires_at, but VaultPaymentMethod.Action in 0.141.0 is only name, url and capture_token. Expiry is on the method itself, which you already project. It's harmless (it projects nothing); see the inline comment.
  • destructiveHint: true now covers create and payment_methods too, because annotations are per tool. That's the right conservative call; mentioning it in case clients start prompting on reads.
  • 0.141.0 also adds state.source (payment_method | single_use_card) on KERNEL cards. It may be worth projecting in a follow-up so agents can tell why payment_method_id and funding_status are absent. Keeping single_use_card out of the MCP input schema is correct, since card data should never pass through tool inputs.
  • I opened #270 to document that fill selectors must match exactly one element. Shopify's card iframes include hidden decoy inputs with the same name, which returns ambiguous_selector. It touches a different string in vault-items.ts, so the two PRs shouldn't conflict.
  • FYI, outside this repo: after a KERNEL card was filled and paid on a real Shopify checkout, the item still advertised only fill, not confirm_transaction. The MCP passes through available_operations, so if that's unexpected it's on the API side.

...fields("id provider type is_default status status_reason expires_at"),
display: fields("label brand last4"),
capabilities: { single_use_card: fields("eligible reasons") },
action: fields("name url expires_at"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: VaultPaymentMethod.Action in 0.141.0 has no expires_at (only name, url, capture_token). Expiry is on the payment method, which line 39 already projects. fields("name url") would match the SDK type.

This branch had an error being deployed

1 failed deployment
Preview — 0fe45631 Deployed Oct 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants