Cloudup Plugin for Claude Code
Upload images to Cloudup directly from Claude Code, paying per upload with x402 micropayments. Agents can capture screenshots (e.g. via Playwright) and embed shareable URLs in PR comments, issues, and chat replies.
What's in the plugin
- MCP server (
cloudup) — wraps tellyworth/mpp-remote pointed at Cloudup staging
- Skill (
uploading-to-cloudup) — teaches the agent when to reach for the upload tool
- Slash commands —
/cloudup <path> for uploads, /cloudup-setup for one-time key provisioning
Setup
1. Install the plugin
In a Claude Code session:
/plugin marketplace add StevenDufresne/cloudup-plugin
/plugin install cloudup@cloudup-plugin
2. Provision a wallet
Three paths; /cloudup-setup walks you through A or B interactively. C is the build-agent escape hatch.
Path A — Privy agent wallet (recommended)
The plugin asks Privy's agent-wallet service to sign each x402 payment. The signing key lives in Privy; your machine only holds a per-user authorization keypair in the OS keychain (managed by the Privy CLI itself).
Install the CLI once:
npm i -g @privy-io/agent-wallet-cli
Then run /cloudup-setup in Claude Code, pick Privy agent wallet, and it walks you through paw login (browser-based) and prints the Ethereum address of your new wallet.
Path B — Locally generated key (macOS, laptop)
A fresh secp256k1 key generated on your machine and stored in the macOS Keychain. You hold the key — no third-party custody, but also no recovery if the laptop is lost. macOS only today.
Run /cloudup-setup in Claude Code and pick Locally generated key. It runs scripts/cloudup-key.sh generate, which generates the key, stores it under Keychain service cloudup / account wallet, and prints the derived address to fund. Manage the stored key with the same script:
scripts/cloudup-key.sh status # is a key stored?
scripts/cloudup-key.sh address # print the wallet address
scripts/cloudup-key.sh show # print the private key (use with care)
scripts/cloudup-key.sh remove # delete the key from Keychain
Path C — CLOUDUP_WALLET_KEY env var (CI, headless, TeamCity)
Paths A and B both require interactive setup that doesn't work on a build agent: paw login is browser-based, and macOS Keychain doesn't exist. For headless contexts, set:
export CLOUDUP_WALLET_KEY=0x... # a fresh secp256k1 key you generated
The wrapper skips Privy and Keychain entirely and signs locally with viem. Keep the funded balance thin (each upload ≤ CLOUDUP_MAX_USD); a leaked key drains exactly what you funded.
Signer precedence in the wrapper: if CLOUDUP_WALLET_KEY is set it wins (CI path). Otherwise a Keychain-stored key wins if present (Path B). Otherwise the wrapper falls back to paw (Path A). Switching between B and A on the same machine requires removing the previous one's state first — scripts/cloudup-key.sh remove to drop the Keychain key, or clear the paw session.
3. Fund the wallet with USDC
Send testnet USDC to your wallet address on Base Sepolia (chain ID 84532). A small amount is plenty — uploads cost $0.01–$0.25 depending on which tool the agent uses (image embeds are $0.05, small file uploads $0.01, and large multipart uploads up to $0.25). The Cloudup server submits the meta-transaction on your behalf, so you don't need ETH for gas.
For Path A, paw fund opens Privy's funding flow in a browser. For Paths B and C, use a Base Sepolia faucet:
4. Optional configuration
| Variable | Default | Purpose |
|---|
CLOUDUP_MAX_USD | 0.30 | Spending cap per upload — refuses to sign above this. Default covers the large SKU (begin_upload, $0.25) with a small margin; raise if pricing changes upstream. |
CLOUDUP_MCP_URL | https://api.stage-cloudup.com/mcp/public | Server endpoint (swap for prod when available) |
CLOUDUP_WALLET_KEY | (unset) | Path C selector. If set to a 0x… private key, skip both paw and Keychain and sign locally with viem. Use for CI / headless agents only. |
5. Remove any duplicate manual cloudup MCP
If you previously registered an mpp-remote-backed Cloudup MCP server manually (e.g. via claude mcp add), remove it. Claude Code silently suppresses plugin-declared MCP servers whose command + args match an existing manually-configured one, so the plugin's cloudup will appear to "do nothing" if a manual duplicate exists.
claude mcp list # find any manual cloudup-* entries
claude mcp remove <your-cloudup-server-name>
6. Restart Claude Code and verify
Start a fresh Claude Code session. Run /mcp and confirm cloudup shows as connected. Then test:
/cloudup /tmp/screenshot.png