Pink sits between an AI agent and a company's money. The agent asks "may I pay this?"; the company's rules answer in under a second: allow ask a person block. This sandbox is a full copy of that engine with test credentials, so any MCP-capable agent can try it in minutes.
Pick a company template. You get an admin key for the approvals console and one key per AI agent.
Every agent gets its own key. Put it in the URL, or send it as a Bearer token. Same server, either way.
MCP endpoint (Streamable HTTP)
https://agentic-sandbox.pinkwallet.com/mcp/<agent_key>
or: https://agentic-sandbox.pinkwallet.com/mcp
Authorization: Bearer <agent_key>
Tools the agent receives: pink.get_budget pink.list_payees pink.list_rules pink.check_policy pink.request_payment pink.get_credential pink.report_receipt
pink.request_payment({ payee_id, amount, purpose, reason, evidence }). It never sees a card or a bank login, only the answer.hold_id; a person approves in the console or on their phone and the agent polls pink.get_credential. blocked returns the reason and nothing else.pink.report_receipt closes the loop and raises the agent's trust score.claude mcp add --transport http pink \ https://agentic-sandbox.pinkwallet.com/mcp/<agent_key>
Then ask Claude: "Check my budget with Pink, then buy 20 kg of beans from Counter Culture Coffee for $420."
{ "mcpServers": { "pink": {
"url": "https://agentic-sandbox.pinkwallet.com/mcp",
"headers": { "Authorization": "Bearer <agent_key>" }
} } }Add a custom connector / remote MCP server and paste the key-in-URL form: https://agentic-sandbox.pinkwallet.com/mcp/<agent_key>. No OAuth is needed in the sandbox.
from agents.mcp import MCPServerStreamableHttp
pink = MCPServerStreamableHttp(params={
"url": "https://agentic-sandbox.pinkwallet.com/mcp",
"headers": {"Authorization": "Bearer <agent_key>"}})"mcp_servers": [{ "type": "url", "name": "pink",
"url": "https://agentic-sandbox.pinkwallet.com/mcp",
"authorization_token": "<agent_key>" }]curl -X POST https://agentic-sandbox.pinkwallet.com/v1/payments \
-H "Authorization: Bearer <agent_key>" \
-H "Content-Type: application/json" \
-d '{"payee_id":"p_cc","amount":420,"purpose":"20 kg beans"}'| Method | Path | Key | What it does |
|---|---|---|---|
| POST | /v1/sandbox/workspaces | none | Create a workspace: {company, email, template} → admin key + agent keys |
| GET | /v1/me · /v1/budget · /v1/payees · /v1/vaults · /v1/rules | agent | What this agent is, may spend, may pay, and the rules that apply to it |
| POST | /v1/payments/check | agent | Dry run: would_allow / would_ask / would_block with the full trace |
| POST | /v1/payments | agent | Request a payment. 201 allowed · 202 pending_human · 403 blocked. Send Idempotency-Key to make retries safe |
| GET | /v1/payments/{id} | agent | Poll a hold; returns the credential once approved |
| POST | /v1/payments/{id}/receipt | agent | File the receipt |
| GET | /v1/admin/state | admin | Everything: agents, vaults, payees, rules, pending requests, transactions |
| POST | /v1/admin/requests/{id}/approve · /decline | admin | Decide a pending request (the console uses this) |
| PUT | /v1/admin/rules | admin | Replace the policy: {rules:[…]}. Publishes a new version |
| PATCH | /v1/admin/agents/{id} | admin | {status:"paused"|"active", monthly, perPay} |
| POST | /v1/admin/reset-day · /v1/admin/reset | admin | Zero today's spend · reset the workspace to its template |
| payee_id | Id from the payee list. Omit and pass payee_name for a payee not on the list (the policy will usually stop and ask). |
| amount · currency | Positive number, USD by default. EUR, GBP, HKD, SGD, JPY are supported; rules can be currency-specific. |
| purpose · reason | What it is for, and why now. Both are shown to the person who approves. |
| evidence | Free-text references: PO number, invoice id, ticket, photos. |
| evidence_flags | Structured signals the rules react to: po sow ticket scan statement brief renewal dupInvoice payeeChanged repeatCustomer deposit. In production these come from connected systems (ERP, helpdesk, WMS); in the sandbox the agent states them. |
| local_hour | 0–23, for time-of-day rules. Defaults to the UTC hour. |
| idempotency_key | Any unique string per attempt. Repeating it returns the original decision instead of paying twice. |
Sandbox credentials are test values (4111… cards, PWS- transfer references). No money moves. Workspaces are kept for 30 days of inactivity. Questions and early access: agentic@pinkwallet.com