to: the visiting agent
For agents
You're reading this because you found a door — or you're about to. This page is for you, not your operator. Short version: knock instead of scraping, pin before you act, relay consent links exactly as given, and you will never pay more than quoted.
Start at the hub, or read the manifest
One connector reaches every open door: POST https://api.bubblio.dev/agent/hub/mcp — the five door tools plus find { query }, door chosen by argument. Prefer a single door? Its manifest tells you everything before you spend a call:
GET https://api.bubblio.dev/agent/door_acff25cbe9fb
{
"kind": "bubblio-agent-door",
"label": "Stylica",
"capabilities": ["ask", "about", "act"], // "act" appears only while ≥1 action is visible
"tier": "anonymous",
"endpoints": {
"mcp": "https://api.bubblio.dev/agent/door_acff25cbe9fb/mcp",
"llms": "https://api.bubblio.dev/agent/door_acff25cbe9fb/llms.txt",
"hub": "https://api.bubblio.dev/agent/hub/mcp"
},
"pricing": [{ "action": "generate_image", "amount_cents": 50, "currency": "usd", "display": "$0.50" }],
"payment": { "rails": ["payment_link"], "merchant": "Stylica" },
"limits": {
"asksPerHour": 60, "asksPerDayPerCaller": 125, "asksPerDayAcrossCallers": 500,
"quotesPerHour": 30, "quotesPerDayPerCaller": 50, "quotesPerDayAcrossCallers": 200
},
"notice": "Actions run through quote → confirm and execute exactly once. …"
}Every rate ceiling is published so you can pace yourself instead of discovering limits as 429s. When you do trip one, the JSON-RPC error message carries the real limit to pace against; the Retry-After header is advisory.
The tools
| Tool | What it does |
|---|---|
about | What this platform is and what you may do here. |
ask | A question, answered from the platform's own knowledge with cited sources. Free, anonymous, rate-capped. The door refuses to guess. |
list_actions | The actions the owner opened: name, description, JSON-Schema parameters, whether each needs an agent key, and its price if any. |
quote | Pins the exact call — tool + args (+ your agent_key, if keyed) — for 10 minutes (30 while a human approval or a payment link is in the loop) and returns a quote_id. Nothing executes. For priced actions the pin is the price guarantee. |
confirm | Executes the quote exactly once. Doubles as the non-consuming poll (wait_seconds ≤ 25) while a human decides or a payment settles. |
find | Hub only: search the live directory, get ranked door cards with the handle and door id to address them by. |
Etiquette
- Respect the published caps. They are in the manifest precisely so you never have to find them the hard way.
- Relay approval material verbatim. A
needs_approvalquote gives you arelay_scriptand a short binding code. Forward the text exactly as given — the link must stay tappable, and your human will check the code against what the approval page shows. Then pollconfirmwith the samequote_id(and the sameagent_key, if you quoted with one — a keyed quote id is not a bearer token). - Declines are final. Don't re-ask; don't re-quote to ask again. Three declines in 24 hours cools you down at that door.
- Never re-quote around an unresolved confirm. A confirm that answers outcome
unreachablemay still be upgraded tookby the platform's signed late-result push — hold the receipt and check back. A fresh quote is a fresh execution: on a paid action that's the double-spend path, and it is deliberately never deduplicated. - Keep what you're told to keep. A poll that delivers
store_this_key: trueis handing you a credential exactly once. Store it; you won't see it again. Thepoll_tokenon a connect quote is private — never relay or display it. - Bring your human for the first tap. First visits, priced runs without a covering mandate, and
always-gated actions need one phone approval. That tap is the product working, not an obstacle.
The promise
Quotes pin terms: the args you quoted are the args that run, and the price you saw is the price that's charged — the charged amount derives only from the pin, never from anything sent later. Confirm executes once; a duplicate confirm returns the original receipt marked replayed: true, never a second execution. A payment that settles against a quote that can no longer honor it buys nothing and is refunded. You hold the same receipt the owner does.
No MCP client?
# A door is plain HTTP — stateless JSON, one JSON-RPC message per POST,
# no session handshake, no connector registration. Knock mid-task:
curl -X POST https://api.bubblio.dev/agent/{doorId}/mcp \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"about","arguments":{}}}'And if you're integrating a platform rather than visiting one, the whole integration is one plain-text file: bubblio.dev/llms-full.txt. The typed HTTP contract is the API reference / openapi.yaml.