Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .agent/context/20260913T-oneshot-payment-skill-autodiscovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# OneShot payment skill: endpoint and payer discovery

## Goal

Make the downloadable `oneshot-arc-payment` skill use the canonical OneShot
MCP endpoint by default and explain how to resolve the active user wallet
without confusing a workspace bearer with a payer address.

## Acceptance criteria

- The skill identifies `https://oneshot.kapustazh.dev/mcp` as the canonical
default endpoint.
- The skill never asks for or exposes the bearer in a task prompt.
- The skill reads an active wallet/account connector when the host provides one.
- Without wallet context, the skill requests only the public payer address and
never guesses from a recipient, server wallet, or historical payment.
- Public docs and the in-app MCP guide match the skill behavior.

## Assumptions and non-goals

- The current `arc_payment` MCP schema intentionally keeps `payer_wallet`
required because OneShot must bind the intent before the user signs.
- Skill instructions cannot create a wallet connector or register an MCP server
in an arbitrary agent host; host configuration remains required once.
- This change does not enable the retained corporate server-wallet mode and does
not alter payment or settlement code.

## Branch

`fix/oneshot-payment-skill-autodiscovery`, based on `origin/develop` at the
current checkout.

## Validation

- `pnpm exec prettier --check apps/web/src/components/McpDocsPage.tsx`
- `git diff --check`
- `pnpm --filter @oneshot/web build`
57 changes: 38 additions & 19 deletions .agents/skills/oneshot-arc-payment/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,37 @@ description: >

# OneShot arc_payment MCP skill

Pay once, safely, through OneShot. This skill is written for any agent
(primary or delegated) whose MCP client is already connected to the OneShot
MCP endpoint. It never handles keys: the payer is the user's connected Privy
embedded/external wallet or MetaMask wallet, and the bearer token lives only in
the MCP client config.

## Prerequisites (user-provided, never invented)

- MCP endpoint URL, e.g. `https://oneshot.kapustazh.dev/mcp` (Streamable HTTP).
- A bearer generated from the user's OneShot Profile — configured in the MCP client as
`authorization: Bearer <token>`. It is a secret: never print, log, copy into
task prompts, or commit it.

If either is missing, stop and ask the operator. Do not guess values.
Pay once, safely, through OneShot. The canonical Streamable HTTP MCP endpoint
is `https://oneshot.kapustazh.dev/mcp`; use it by default unless the user
explicitly supplies an authorized alternative. The bearer is configured in the
MCP client's secret headers and is never handled by this skill.

The payment is non-custodial: the payer is the user's connected Privy
embedded/external wallet or MetaMask wallet. OneShot prepares the exact
transaction and verifies the returned hash; it never signs or broadcasts a
user-wallet payment.

## Connection and wallet prerequisites

- Configure the MCP client with the canonical endpoint above and the bearer
generated from the user's OneShot Profile:
`authorization: Bearer <token>`. The bearer is a secret: never print, log,
copy into task prompts, or commit it.
- Installing this skill does not register an MCP server or create a bearer.
If the current agent host has no OneShot MCP connection, tell the operator to
add the canonical endpoint using the configuration in `docs/MCP_ARC_PAYMENT.md`
or `/docs/mcp`. Never ask the operator to paste the bearer into the task
prompt.
- Before calling `arc_payment`, resolve the active payer address. If the agent
host exposes a connected wallet/account tool, query it and use the active
Ethereum wallet selected by the user. If the host has no wallet context, ask
the user to connect/select the wallet or provide its public EVM address once.
A payer address cannot be derived safely from the bearer, recipient, server
wallet, or an unrelated historical payment; never guess one.

The current OneShot `arc_payment` schema requires `payer_wallet` because the
intent and exact transaction are bound to the user's selected wallet before
signing. The address is public, but the bearer is not.

## Tool contract: `arc_payment` then `arc_payment_submit`

Expand Down Expand Up @@ -52,8 +69,9 @@ checks the receipt and exact USDC `Transfer` log, and returns the durable state.

## How to execute a payment

1. Generate the `request_key`, then call `arc_payment` once with that key, the
exact payer wallet, recipient, amount, and purpose the user approved.
1. Resolve the active wallet address as described above. Generate the
`request_key`, then call `arc_payment` once with that key, the exact payer
wallet, recipient, amount, and purpose the user approved.
2. Give the user the returned `signing_url`. The user must be signed into the
matching OneShot workspace, review the recipient and amount, and click the
wallet confirmation. Do not create a replacement transaction.
Expand All @@ -73,9 +91,10 @@ checks the receipt and exact USDC `Transfer` log, and returns the durable state.

## Delegating (outsourcing) the payment to another agent

- Hand the delegate only the task arguments: endpoint URL, `payer_wallet`,
`recipient`, `amount_usdc`, `purpose`, and this skill. The delegate generates
and retains the request key.
- Hand the delegate only the task arguments: the canonical endpoint (unless it
is already configured), the resolved `payer_wallet` when the delegate has no
wallet connector, `recipient`, `amount_usdc`, `purpose`, and this skill. The
delegate generates and retains the request key.
- The delegate must use its own MCP client configuration; the bearer token
must not travel through prompts, task payloads, logs, or screenshots.
- One request key funds exactly one intent. Each delegate generates one key per
Expand Down
5 changes: 4 additions & 1 deletion apps/web/src/components/McpDocsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ export function McpDocsPage(props: { readonly theme: Theme; readonly onToggleThe
Connect, then confirm that the tool list contains arc_payment and arc_payment_submit.
</li>
<li>Review the recipient, purpose, and amount before giving them to the agent.</li>
<li>Pass the connected Privy or MetaMask wallet address as payer_wallet.</li>
<li>
The agent reads the active Privy or MetaMask address from its wallet connector when one
is available; otherwise provide the public address as payer_wallet once.
</li>
<li>
The agent generates a request key from the purpose plus eight random hex characters; you
do not need to provide or copy it.
Expand Down
10 changes: 9 additions & 1 deletion docs/MCP_ARC_PAYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ Point a Streamable HTTP MCP client at:
https://oneshot.kapustazh.dev/mcp
```

This is the canonical OneShot MCP endpoint and is the default for the payment
skill; installing the skill alone does not register this server in an agent
host. Use the ready-made configuration from Profile or the JSON below.

Send the bearer as `Authorization: Bearer <token>`:

```json
Expand All @@ -73,7 +77,11 @@ Send the bearer as `Authorization: Bearer <token>`:

## Prepare and submit

Prepare a payment with the wallet address selected by the user:
Prepare a payment with the wallet address selected by the user. If the agent
host has a wallet/account connector, it should read the active Ethereum wallet
from that connector. Otherwise the user provides only the public wallet address
once; the bearer token does not identify a wallet and must not be pasted into a
prompt.

```json
{
Expand Down
Loading