From e5f3a88fc4c781fe005af8dec064bbc4aa1724ed Mon Sep 17 00:00:00 2001 From: apexethdev <156128799+apexethdev@users.noreply.github.com> Date: Wed, 3 Jun 2026 11:11:03 +0100 Subject: [PATCH 1/2] Add Veil Cash Base MCP plugin Add external-mcp stdio-only plugin for Veil Cash privacy pools on Base. Public register/deposit flows prepare calldata for send_calls; private withdraw, transfer, and x402 use the local Veil relay (none on Base MCP). Register plugin in SKILL.md, add privacy/shielded-payments tags, and extend plugin-spec conformance table. MCP package: @veil-cash/mcp@0.2.1. Co-authored-by: Cursor --- skills/base-mcp/SKILL.md | 3 +- skills/base-mcp/plugins/veil.md | 312 ++++++++++++++++++++++ skills/base-mcp/references/plugin-spec.md | 7 +- 3 files changed, 318 insertions(+), 4 deletions(-) create mode 100644 skills/base-mcp/plugins/veil.md diff --git a/skills/base-mcp/SKILL.md b/skills/base-mcp/SKILL.md index 005669e..1586892 100644 --- a/skills/base-mcp/SKILL.md +++ b/skills/base-mcp/SKILL.md @@ -65,12 +65,13 @@ Plugins currently maintained alongside this skill (the **native plugins**): | Virtuals | [plugins/virtuals.md](plugins/virtuals.md) | | Aerodrome (CLI-only) | [plugins/aerodrome.md](plugins/aerodrome.md) | | Bankr | [plugins/bankr.md](plugins/bankr.md) | +| Veil Cash (external-mcp, stdio) | [plugins/veil.md](plugins/veil.md) | Load a plugin reference only when the user's request matches it, following the same local-first, web-fallback rule as references (see [Loading referenced files](#loading-referenced-files) above). For a plugin's own external tools, defer to the plugin file first, then to any CLI help, API schema, or MCP tool descriptions it explicitly tells you to use. ### Native plugins vs. custom / user-supplied plugins -Native plugin HTTP hosts may be allowlisted in the Base MCP `web_request` tool. Aerodrome is CLI-only and requires a harness with shell access. Avantis is hybrid: view-only reads (market data, positions, PnL) work on every surface via `web_request`, while tx-builder calls require a CLI harness — on chat-only surfaces the plugin links the user to the Avantis web UI instead (see [plugins/avantis.md](plugins/avantis.md)). Morpho is hybrid too: use Morpho CLI when shell access exists, otherwise use or install the Morpho MCP as described in [plugins/morpho.md](plugins/morpho.md). Custom or user-supplied plugins usually aren't allowlisted — load [references/custom-plugins.md](references/custom-plugins.md) for the decision tree on which HTTP path to use (harness HTTP tool vs. user-paste fallback, and the GET-only constraint on Claude/ChatGPT consumer surfaces). +Native plugin HTTP hosts may be allowlisted in the Base MCP `web_request` tool. Aerodrome is CLI-only and requires a harness with shell access. Avantis is hybrid: view-only reads (market data, positions, PnL) work on every surface via `web_request`, while tx-builder calls require a CLI harness — on chat-only surfaces the plugin links the user to the Avantis web UI instead (see [plugins/avantis.md](plugins/avantis.md)). Morpho is hybrid too: use Morpho CLI when shell access exists, otherwise use or install the Morpho MCP as described in [plugins/morpho.md](plugins/morpho.md). Veil Cash is external-mcp and stdio-only: install the local `@veil-cash/mcp` npm package alongside Base MCP — there is no hosted HTTP URL because private keys and metadata must stay on the user's machine (see [plugins/veil.md](plugins/veil.md)). Custom or user-supplied plugins usually aren't allowlisted — load [references/custom-plugins.md](references/custom-plugins.md) for the decision tree on which HTTP path to use (harness HTTP tool vs. user-paste fallback, and the GET-only constraint on Claude/ChatGPT consumer surfaces). ## Installation diff --git a/skills/base-mcp/plugins/veil.md b/skills/base-mcp/plugins/veil.md new file mode 100644 index 0000000..f4db51d --- /dev/null +++ b/skills/base-mcp/plugins/veil.md @@ -0,0 +1,312 @@ +--- +title: "Veil Cash Plugin" +description: "Privacy pool on Base via Veil MCP — prepare register/deposit calldata for send_calls; private withdraw, transfer, and x402 via Veil relay." +tags: [privacy, shielded-payments, agent-commerce] +name: veil +version: 0.2.1 +integration: external-mcp +chains: [base] +requires: + shell: none + allowlist: [] + externalMcp: + name: veil + url: null + cliPackage: null +auth: none +risk: [irreversible] +--- + +# Veil Cash Plugin + +> [!IMPORTANT] +> Complete the short Base MCP onboarding flow defined in `SKILL.md` before calling any Veil tool. Use `baseAccount.address` from Base MCP `get_wallets` as `owner` on Veil MCP calls that require it. + +## Overview + +Veil Cash is a privacy pool for ETH and USDC on Base mainnet (`8453`, Base MCP chain string `base`). This is an **external-mcp** plugin: all Veil operations go through a local Veil MCP server (`@veil-cash/mcp` on npm). Public register/deposit flows return **unsigned calldata** for Base MCP `send_calls`; private withdraw, transfer, x402 payment, and UTXO consolidation submit through the Veil relay inside Veil MCP (`none` on Base MCP — see [Submission](#submission)). + +Veil MCP v1 is **stdio-only**. There is no hosted HTTP MCP URL: `VEIL_KEY`, proof building, and balance decryption must stay on the user's machine. A hosted MCP would require custodial keys and would centralize activity metadata, which defeats the purpose of a privacy pool. + +The exact list of Veil tools, their parameters, and descriptions are advertised by Veil MCP itself — read the tool catalog at runtime rather than relying on a fixed list in this file. + +If another Veil skill from `@veil-cash/sdk` is available, treat it as CLI-specific reference only. This plugin is the authority for Base MCP use: do not switch to CLI signing modes, Bankr flows, or direct SDK transaction submission. + +Veil keys are local. Base Account smart wallets do not reliably provide the plain `personal_sign` signature needed for Veil's deterministic key derivation, so v1 uses a random local Veil key (`veil_init_keypair`). Configure `VEIL_KEY` in the MCP server env or `.env.veil` to enable private balances and relay-backed writes. + +## Detection + +If no Veil tools (e.g. `veil_status`, `veil_prepare_deposit`, `veil_get_balances`) are exposed to the harness, Veil MCP is not installed. Do not improvise Veil flows with the SDK CLI or direct contract calls — install Veil MCP alongside Base MCP (see [Installation](#installation)), reconnect or restart the session so tools register, then retry. + +## Installation + +Veil MCP is a **local stdio** server, not a hosted HTTP connector. Install it beside Base MCP in the harness MCP config (`command` + `args`, or global `veil-mcp` binary). `requires.externalMcp.url` is `null` by design — do not substitute a remote URL or SDK CLI in place of the local MCP. + +Pin a version for reproducibility, e.g. `@veil-cash/mcp@0.2.1`. + +**Recommended (avoids per-launch npm resolution):** + +```bash +npm install -g @veil-cash/mcp +``` + +Detect the harness and apply the matching step: + +- **Claude Code:** add Veil MCP to the harness MCP config (see JSON below) and restart. +- **Codex:** add `[mcp_servers.veil]` with `command = "veil-mcp"` to `codex.toml`, or use the JSON snippet below. +- **Cursor / JSON-config harnesses:** add the snippet below to `~/.cursor/mcp.json` or the project's `.cursor/mcp.json` and restart. +- **Claude.ai web / ChatGPT connectors:** unsupported on v1. These surfaces require a hosted HTTP MCP URL; Veil deliberately does not offer one because private keys and metadata must stay local. Tell the user Veil requires a harness that can launch a local MCP process (Cursor, Codex, Claude Code). Do not improvise a workaround or suggest a hosted alternative. +- **Other / unknown harness:** show the JSON snippet below and ask the user where their MCP config lives. + +```json +{ + "mcpServers": { + "base-mcp": { "url": "https://mcp.base.org" }, + "veil": { + "command": "npx", + "args": ["-y", "@veil-cash/mcp@0.2.1"] + } + } +} +``` + +Or, when `veil-mcp` is installed globally: + +```json +{ + "mcpServers": { + "base-mcp": { "url": "https://mcp.base.org" }, + "veil": { "command": "veil-mcp" } + } +} +``` + +**Enabling private writes** — set `VEIL_KEY` (and optionally `RPC_URL`) in the Veil MCP server env: + +```json +{ + "mcpServers": { + "veil": { + "command": "npx", + "args": ["-y", "@veil-cash/mcp@0.2.1"], + "env": { + "VEIL_KEY": "0x...", + "RPC_URL": "https://your-base-rpc" + } + } + } +} +``` + +Use `npx -y github:veildotcash/veil-mcp` only for development; GitHub resolution slows MCP startup. + +After install, ask the user to reconnect or restart the session so Veil tools register. + +## Surface Routing + +| Capability | Harness surface | Execution path | Base MCP submission | +|---|---|---|---| +| All Veil operations | Harness with local Veil MCP (stdio) | Veil MCP tools | varies by operation — see [Submission](#submission) | +| Read (status, balances, deposit status, x402 quote/receipts) | Cursor, Codex, Claude Code, etc. | Veil MCP read tools | `none` | +| Register / deposit (public on-chain) | Same | Veil MCP prepare tools → Base MCP | `send_calls` | +| Private withdraw / transfer / x402 / consolidate | Same | Veil MCP relay tools (`confirm: true`) | `none` | +| Chat-only connectors (Claude.ai web, ChatGPT) | No local stdio MCP | **Stop** — no hosted URL on v1 (privacy) | — | + +Veil MCP performs its own RPC and relay HTTP calls internally. Base MCP `web_request` is not used for Veil protocol access. A dedicated `RPC_URL` on the Veil MCP server is recommended because Merkle tree, event, queue, and balance reads can hit public RPC rate limits; it does not replace Base MCP for public transaction submission. + +## Orchestration + +### Registration + +```text +1. Base MCP get_wallets → owner (baseAccount.address) +2. Veil MCP veil_status({ owner }) +3. If no local Veil key, veil_init_keypair({}) — returns deposit key only, never VEIL_KEY +4. Veil MCP veil_status({ owner }) to confirm key and registration state +5. Veil MCP veil_prepare_register({ owner }) +6. If action is alreadyRegistered and calls is empty, skip send_calls +7. Base MCP send_calls({ chain: "base", calls }) → approvalUrl + requestId +8. User approves → Base MCP get_request_status(requestId) +``` + +If the owner is registered with a different deposit key, ask the user before retrying `veil_prepare_register` with `force: true` (key rotation). + +### Deposit + +```text +1. Base MCP get_wallets → owner +2. Veil MCP veil_status({ owner }) — ensure key exists and owner is registered +3. Veil MCP veil_prepare_deposit({ owner, asset, amount }) +4. Base MCP send_calls({ chain: "base", calls }) +5. User approves → get_request_status(requestId) +6. Veil MCP veil_get_balances({ owner, pool }) to find pending nonce +7. Veil MCP veil_deposit_status({ owner, pool, nonce }) until status is not pending +``` + +After Base MCP confirms the transaction, funds enter the Veil queue before becoming private balance. Typical processing is **8–12 minutes**. Report the lifecycle clearly: submitted on Base → pending in queue → accepted into private balance. `veil_deposit_status` reports `queuePosition`, `queueLength`, and `typicalProcessingMinutes`. + +Deposit `amount` is the **net** amount that lands in Veil; the 0.3% protocol fee is included in prepared calldata. Minimums: `0.01 ETH`, `10 USDC`. + +### Private withdraw, transfer, x402, or consolidation + +```text +1. Ask the user to explicitly confirm the relay-backed private action. +2. For private transfers, verify the recipient is registered with Veil. +3. For x402: optionally veil_x402_quote first; confirm URL, maxPayment cap, and that private USDC moves to a payer EOA. +4. Veil MCP veil_withdraw / veil_transfer / veil_pay_x402 / veil_consolidate_utxos with confirm: true +5. Report public metadata only: tx hashes, amounts, payer address, response status/body, success +``` + +Do **not** route private relay actions through Base MCP `send_calls`. + +### x402 payment (private USDC) + +Supports Coinbase-compatible x402 v2 `exact` Base USDC resources (GET and POST). Always set a tight `maxPayment` cap (decimal USDC string, e.g. `"0.10"`); default and hard cap is `10 USDC`. `veil_pay_x402` pre-flights the endpoint — if the probe is not HTTP 402, it returns `action: "endpoint_error"` and withdraws nothing. + +If a funded payer already holds enough USDC, `veil_pay_x402` may return `action: "reuse_available"`. Ask the user to reuse via `payerIndex` or withdraw anew with `forceFresh: true`. Each payment writes a local receipt (`.veil-x402-receipts.json`). + +### UTXO consolidation + +A single transaction consumes at most **16 input UTXOs**. When `veil_get_balances` reports `fragmentation.needsConsolidation: true`, call `veil_consolidate_utxos({ asset, confirm: true })`. Repeat while `needsAnotherRound: true`. + +### Subaccounts + +Valid slots are 0–2. v1 of this plugin exposes status only via `veil_subaccount_status`. If the user asks to deploy, sweep, merge, or recover subaccounts, explain that those flows are not exposed in v1. + +## Submission + +This plugin uses **two** Base MCP submission targets depending on the operation. + +### Public flows → `send_calls` + +Veil MCP prepare tools return: + +```json +{ + "chain": "base", + "calls": [ + { "to": "0x...", "value": "0x0", "data": "0x..." } + ] +} +``` + +Map directly into Base MCP: + +```json +{ + "chain": "base", + "calls": [ + { "to": "", "value": "", "data": "" } + ] +} +``` + +- Pass `chain` and `calls` unchanged from the Veil MCP response. +- USDC deposits return an ordered **approve + deposit** batch — submit the full array in one `send_calls` request. +- ETH deposits may include nonzero `value` on the deposit call; keep hex-encoded wei strings as returned. +- If `veil_prepare_register` returns `action: "alreadyRegistered"` with `calls: []`, do **not** call `send_calls`. +- After submission, present the approval URL and poll `get_request_status(requestId)` until completed, failed, or rejected. + +### Private flows → `none` + +Withdraw, transfer, x402 payment, and UTXO consolidation submit through the **Veil relay** inside Veil MCP. Base MCP is not involved after onboarding (`get_wallets` for `owner`). State explicitly: submission tool is `none`. + +Private relay tools require `confirm: true` after explicit user approval — they are not Base MCP approval-link flows. + +## Example Prompts + +``` +Deposit 0.1 ETH into Veil privately +``` + +1. Base MCP `get_wallets` → `owner`. +2. Veil MCP `veil_status({ owner })`; call `veil_init_keypair` if no local key. +3. Veil MCP `veil_prepare_register({ owner })`; if calls non-empty, Base MCP `send_calls`. +4. Veil MCP `veil_prepare_deposit({ owner, asset: "ETH", amount: "0.1" })`. +5. Base MCP `send_calls({ chain: "base", calls })` → user approves → `get_request_status`. +6. Veil MCP `veil_deposit_status({ owner, pool: "eth", nonce })` until accepted; explain 8–12 minute queue if pending. + +``` +What's my Veil balance? +``` + +1. Base MCP `get_wallets` → `owner`. +2. Veil MCP `veil_get_balances({ owner, pool: "all" })`. +3. Summarize wallet, queue, and private balances per pool. No Base MCP write. + +``` +Withdraw 50 USDC from Veil to my wallet +``` + +1. Confirm recipient address and amount with the user. +2. Veil MCP `veil_withdraw({ asset: "USDC", amount: "50", recipient: "
", confirm: true })`. +3. Report transaction hash and success. Submission: `none`. + +``` +Pay this x402 API from my private USDC +``` + +1. Veil MCP `veil_x402_quote({ url, maxPayment: "0.10" })` — validate price and support. +2. Confirm URL and cap with the user. +3. Veil MCP `veil_pay_x402({ url, maxPayment: "0.10", confirm: true })`. +4. If `reuse_available`, ask user to pick `payerIndex` or `forceFresh: true` before retrying. +5. Report payment status and response summary. Submission: `none`. + +``` +Use Veil on Claude.ai +``` + +1. Detect chat-only connector surface with no local MCP config. +2. Explain: Veil v1 requires a local stdio MCP because `VEIL_KEY` and private metadata must stay on the user's machine; there is no hosted HTTP URL by design. +3. Direct the user to Cursor, Codex, or Claude Code with Base MCP + Veil MCP installed. Do not substitute SDK CLI or direct contract calls. + +## Risks & Warnings + +### irreversible + +Onchain register/deposit transactions and relay-backed private actions cannot be undone once submitted. Confirm asset, amount, recipient, and whether the action uses Base MCP approval or the Veil relay before any write. Deposits enter a screening queue; rejected deposits may be refunded to the fallback receiver per queue rules. Do not resubmit private relay actions without explicit user confirmation after a failure. + +Guardrails: + +- Never ask Veil MCP to reveal `VEIL_KEY` or request raw private key material from the user. +- Never echo proof internals, nullifiers, encrypted outputs, payer private keys, or x402 signatures. +- Do not show raw calldata as the final user-facing answer — summarize asset, amount, fee, status, request id, transaction hash, and nonce. +- Set a tight `maxPayment` on every x402 call; never raise the cap silently. +- For private transfers, verify the recipient is registered with Veil before submitting. + +## Notes + +### Environment (Veil MCP server) + +Veil MCP loads `.env.veil` first, then `.env`. + +| Variable | Purpose | +| --- | --- | +| `VEIL_KEY` | Local Veil private key for private balances and relay writes | +| `DEPOSIT_KEY` | Public deposit key for register/deposit calldata | +| `RPC_URL` | Base RPC URL; defaults to `https://mainnet.base.org` | +| `RELAY_URL` | Veil relay URL override | +| `X402_RELAY_URL` | x402 relay base; defaults to `RELAY_URL + /x402` or hosted relay `/x402` | +| `X402_PAYER_INDEX` | Deterministic payer index counter; managed by `veil_pay_x402` | + +### Error guidance + +- Missing local Veil key: `veil_init_keypair` or provide `VEIL_KEY` in server env. +- Different registered deposit key: ask before `veil_prepare_register({ force: true })`. +- Invalid amount: minimum `0.01 ETH`, `10 USDC`. +- x402 unsupported: only Base USDC `exact` v2 is supported. +- RPC/network failure: suggest dedicated `RPC_URL`; check `veil_status` relay health. +- Relay failure: do not resubmit private actions without user confirmation. + +### Fragmentation + +`veil_get_balances` returns per-pool `fragmentation` (`unspentCount`, `largestUtxo`, `smallestUtxo`, `needsConsolidation`). When `needsConsolidation` is true, the full balance cannot be spent in one transaction until consolidated. + +### x402 payer recovery + +`veil_x402_payer_balances({ discover: true })` finds USDC left on payer EOAs after failed payments. Funds remain recoverable from `VEIL_KEY + payerIndex`. `veil_x402_receipts({ limit })` reconstructs local spend history. + +### Package + +- npm: [@veil-cash/mcp@0.2.1](https://www.npmjs.com/package/@veil-cash/mcp) +- source: [veildotcash/veil-mcp](https://github.com/veildotcash/veil-mcp) diff --git a/skills/base-mcp/references/plugin-spec.md b/skills/base-mcp/references/plugin-spec.md index 8952320..1153772 100644 --- a/skills/base-mcp/references/plugin-spec.md +++ b/skills/base-mcp/references/plugin-spec.md @@ -57,7 +57,7 @@ Derive every value from the protocol's actual behavior — don't copy another pl `arbitrum`, `avalanche`, `base`, `base-sepolia`, `bsc`, `ethereum`, `optimism`, `polygon` (`base-sepolia` is the only testnet; `swap` is mainnet-only.) Read the `chain` parameter on the Base MCP tools to confirm the current set — it may change over time. If the plugin never routes an onchain transaction through Base MCP (e.g. an external MCP that only uses a Base MCP signature to log in), use `[]`. -- **`tags`** — 3–5 lowercase, hyphenated keywords describing *what the user can do* — capability and category, not the protocol name (the `name` already covers that). These drive routing: the agent reads the SKILL.md tags column to decide which plugin matches a request. Reuse existing tags where they fit so similar plugins cluster, but add new tags as you see fit. Current vocabulary: `lending`, `borrowing`, `yield`, `vaults`, `dex`, `swap`, `liquidity`, `perps`, `leverage`, `derivatives`, `trading`, `token-launches`, `memecoins`, `discovery`, `ai-agents`, `agent-commerce`, `payment-cards`, `email` — when you introduce a new tag, add it to this list so the vocabulary stays shared. +- **`tags`** — 3–5 lowercase, hyphenated keywords describing *what the user can do* — capability and category, not the protocol name (the `name` already covers that). These drive routing: the agent reads the SKILL.md tags column to decide which plugin matches a request. Reuse existing tags where they fit so similar plugins cluster, but add new tags as you see fit. Current vocabulary: `lending`, `borrowing`, `yield`, `vaults`, `dex`, `swap`, `liquidity`, `perps`, `leverage`, `derivatives`, `trading`, `token-launches`, `memecoins`, `discovery`, `ai-agents`, `agent-commerce`, `payment-cards`, `email`, `privacy`, `shielded-payments` — when you introduce a new tag, add it to this list so the vocabulary stays shared. - **`requires.shell`**: - `required` — the plugin cannot function without a shell/terminal (its only path is a CLI). On shell-less surfaces the agent must stop. - `optional` — a shell unlocks a richer path (a CLI, or a tx-builder), but the plugin still works without one via an HTTP/MCP/UI fallback. @@ -296,7 +296,7 @@ Before opening a PR, confirm: ## Existing Plugin Conformance -Current integration classification for the 7 native plugins: +Current integration classification for the native plugins: | Plugin | `integration` | `chains` | `tags` | `shell` | `auth` | `risk` | |---|---|---|---|---|---|---| @@ -306,6 +306,7 @@ Current integration classification for the 7 native plugins: | Moonwell | `http-api` | `[base, optimism]` | `[lending, borrowing, yield]` | `none` | `none` | `[liquidation]` | | Morpho | `hybrid` | `[base]` | `[lending, borrowing, vaults, yield]` | `optional` | `none` | `[liquidation]` | | Uniswap | `http-api` | `[base]` | `[dex, swap, liquidity]` | `none` | `api-key` | `[slippage]` | +| Veil Cash | `external-mcp` | `[base]` | `[privacy, shielded-payments, agent-commerce]` | `none` | `none` | `[irreversible]` | | Virtuals | `external-mcp` | `[]` | `[ai-agents, agent-commerce, payment-cards, email]` | `none` | `siwe-jwt` | `[pii]` | -All seven are at `version: 0.2.0` as of the spec-conformance restructure. +Existing native plugins are at `version: 0.2.0` as of the spec-conformance restructure; Veil Cash ships at `0.2.1`. From 7e83342c4665ac6223759b2d2a17d7e9d5a46b51 Mon Sep 17 00:00:00 2001 From: apexethdev <156128799+apexethdev@users.noreply.github.com> Date: Fri, 5 Jun 2026 06:00:34 +0100 Subject: [PATCH 2/2] Address review: narrow PR to plugin file + adopt #78 stdio schema - Revert maintainer-owned registry/inventory edits per review: fully revert SKILL.md; in plugin-spec.md restore the "7 native plugins" conformance table (drop Veil row) and the version line. Keep only the privacy/shielded-payments tag-vocabulary additions. - Rewrite veil.md frontmatter to the #78 transport: stdio schema (command/args/env, shell: required, risk += local-exec); add a ### local-exec Risks subsection. - Make register-before-deposit an explicit hard prerequisite in ## Orchestration > Deposit (a deposit before register reverts). - Pin the global-install command to @0.2.1. Co-Authored-By: Claude Opus 4.8 --- skills/base-mcp/SKILL.md | 3 +-- skills/base-mcp/plugins/veil.md | 22 ++++++++++++++++------ skills/base-mcp/references/plugin-spec.md | 5 ++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/skills/base-mcp/SKILL.md b/skills/base-mcp/SKILL.md index 1586892..005669e 100644 --- a/skills/base-mcp/SKILL.md +++ b/skills/base-mcp/SKILL.md @@ -65,13 +65,12 @@ Plugins currently maintained alongside this skill (the **native plugins**): | Virtuals | [plugins/virtuals.md](plugins/virtuals.md) | | Aerodrome (CLI-only) | [plugins/aerodrome.md](plugins/aerodrome.md) | | Bankr | [plugins/bankr.md](plugins/bankr.md) | -| Veil Cash (external-mcp, stdio) | [plugins/veil.md](plugins/veil.md) | Load a plugin reference only when the user's request matches it, following the same local-first, web-fallback rule as references (see [Loading referenced files](#loading-referenced-files) above). For a plugin's own external tools, defer to the plugin file first, then to any CLI help, API schema, or MCP tool descriptions it explicitly tells you to use. ### Native plugins vs. custom / user-supplied plugins -Native plugin HTTP hosts may be allowlisted in the Base MCP `web_request` tool. Aerodrome is CLI-only and requires a harness with shell access. Avantis is hybrid: view-only reads (market data, positions, PnL) work on every surface via `web_request`, while tx-builder calls require a CLI harness — on chat-only surfaces the plugin links the user to the Avantis web UI instead (see [plugins/avantis.md](plugins/avantis.md)). Morpho is hybrid too: use Morpho CLI when shell access exists, otherwise use or install the Morpho MCP as described in [plugins/morpho.md](plugins/morpho.md). Veil Cash is external-mcp and stdio-only: install the local `@veil-cash/mcp` npm package alongside Base MCP — there is no hosted HTTP URL because private keys and metadata must stay on the user's machine (see [plugins/veil.md](plugins/veil.md)). Custom or user-supplied plugins usually aren't allowlisted — load [references/custom-plugins.md](references/custom-plugins.md) for the decision tree on which HTTP path to use (harness HTTP tool vs. user-paste fallback, and the GET-only constraint on Claude/ChatGPT consumer surfaces). +Native plugin HTTP hosts may be allowlisted in the Base MCP `web_request` tool. Aerodrome is CLI-only and requires a harness with shell access. Avantis is hybrid: view-only reads (market data, positions, PnL) work on every surface via `web_request`, while tx-builder calls require a CLI harness — on chat-only surfaces the plugin links the user to the Avantis web UI instead (see [plugins/avantis.md](plugins/avantis.md)). Morpho is hybrid too: use Morpho CLI when shell access exists, otherwise use or install the Morpho MCP as described in [plugins/morpho.md](plugins/morpho.md). Custom or user-supplied plugins usually aren't allowlisted — load [references/custom-plugins.md](references/custom-plugins.md) for the decision tree on which HTTP path to use (harness HTTP tool vs. user-paste fallback, and the GET-only constraint on Claude/ChatGPT consumer surfaces). ## Installation diff --git a/skills/base-mcp/plugins/veil.md b/skills/base-mcp/plugins/veil.md index f4db51d..b3dfc42 100644 --- a/skills/base-mcp/plugins/veil.md +++ b/skills/base-mcp/plugins/veil.md @@ -7,14 +7,17 @@ version: 0.2.1 integration: external-mcp chains: [base] requires: - shell: none + shell: required allowlist: [] externalMcp: name: veil - url: null + transport: stdio + command: npx + args: ["-y", "@veil-cash/mcp@0.2.1"] + env: [VEIL_KEY, RPC_URL] cliPackage: null auth: none -risk: [irreversible] +risk: [irreversible, local-exec] --- # Veil Cash Plugin @@ -40,14 +43,14 @@ If no Veil tools (e.g. `veil_status`, `veil_prepare_deposit`, `veil_get_balances ## Installation -Veil MCP is a **local stdio** server, not a hosted HTTP connector. Install it beside Base MCP in the harness MCP config (`command` + `args`, or global `veil-mcp` binary). `requires.externalMcp.url` is `null` by design — do not substitute a remote URL or SDK CLI in place of the local MCP. +Veil MCP is a **local stdio** server, not a hosted HTTP connector. Install it beside Base MCP in the harness MCP config (`command` + `args`, or global `veil-mcp` binary). `requires.externalMcp.transport` is `stdio` with no `url` by design — do not substitute a remote URL or SDK CLI in place of the local MCP. Pin a version for reproducibility, e.g. `@veil-cash/mcp@0.2.1`. **Recommended (avoids per-launch npm resolution):** ```bash -npm install -g @veil-cash/mcp +npm install -g @veil-cash/mcp@0.2.1 ``` Detect the harness and apply the matching step: @@ -133,9 +136,12 @@ If the owner is registered with a different deposit key, ask the user before ret ### Deposit +> [!IMPORTANT] +> **Registration is a hard prerequisite.** A deposit submitted before the owner's deposit key is registered on-chain will **revert**. Run the [Registration](#registration) flow to completion first and confirm via `veil_status` that the owner is registered (and that the registered deposit key matches the local key) before preparing or submitting a deposit. + ```text 1. Base MCP get_wallets → owner -2. Veil MCP veil_status({ owner }) — ensure key exists and owner is registered +2. Veil MCP veil_status({ owner }) — MUST confirm a local key exists AND owner is already registered; if not, complete Registration first (a deposit before register reverts) 3. Veil MCP veil_prepare_deposit({ owner, asset, amount }) 4. Base MCP send_calls({ chain: "base", calls }) 5. User approves → get_request_status(requestId) @@ -266,6 +272,10 @@ Use Veil on Claude.ai Onchain register/deposit transactions and relay-backed private actions cannot be undone once submitted. Confirm asset, amount, recipient, and whether the action uses Base MCP approval or the Veil relay before any write. Deposits enter a screening queue; rejected deposits may be refunded to the fallback receiver per queue rules. Do not resubmit private relay actions without explicit user confirmation after a failure. +### local-exec + +Veil MCP runs as a **local process on the user's machine** (`npx @veil-cash/mcp` over stdio). Installing and launching it is running third-party partner code locally — a categorically larger trust surface than a hosted MCP or an HTTP API. Install only the **pinned** version from the official package (`@veil-cash/mcp@0.2.1`), never `@latest`, and only from the sources in [Installation](#installation). Never paste `VEIL_KEY` or other secrets into the plugin file or chat — the user provisions them in their own MCP server env (`.env.veil`/`.env` or the `env` block). + Guardrails: - Never ask Veil MCP to reveal `VEIL_KEY` or request raw private key material from the user. diff --git a/skills/base-mcp/references/plugin-spec.md b/skills/base-mcp/references/plugin-spec.md index 1153772..4a5dae7 100644 --- a/skills/base-mcp/references/plugin-spec.md +++ b/skills/base-mcp/references/plugin-spec.md @@ -296,7 +296,7 @@ Before opening a PR, confirm: ## Existing Plugin Conformance -Current integration classification for the native plugins: +Current integration classification for the 7 native plugins: | Plugin | `integration` | `chains` | `tags` | `shell` | `auth` | `risk` | |---|---|---|---|---|---|---| @@ -306,7 +306,6 @@ Current integration classification for the native plugins: | Moonwell | `http-api` | `[base, optimism]` | `[lending, borrowing, yield]` | `none` | `none` | `[liquidation]` | | Morpho | `hybrid` | `[base]` | `[lending, borrowing, vaults, yield]` | `optional` | `none` | `[liquidation]` | | Uniswap | `http-api` | `[base]` | `[dex, swap, liquidity]` | `none` | `api-key` | `[slippage]` | -| Veil Cash | `external-mcp` | `[base]` | `[privacy, shielded-payments, agent-commerce]` | `none` | `none` | `[irreversible]` | | Virtuals | `external-mcp` | `[]` | `[ai-agents, agent-commerce, payment-cards, email]` | `none` | `siwe-jwt` | `[pii]` | -Existing native plugins are at `version: 0.2.0` as of the spec-conformance restructure; Veil Cash ships at `0.2.1`. +All seven are at `version: 0.2.0` as of the spec-conformance restructure.