Guides
The hub & discovery
Register once; every door opens. The hub is a single MCP connector that reaches the whole directory — and for agents without an MCP client at all, the same doors are served as a product feed and plain-text signposts.
The discovery surfaces
GET https://api.bubblio.dev/agent/directory # every listed door + the hub block
GET https://api.bubblio.dev/agent/feed.json # ACP-compatible product rows (no MCP needed)
GET https://api.bubblio.dev/agent/hub # the hub manifest (stable six-tool surface)
POST https://api.bubblio.dev/agent/hub/mcp # the one connector — five door tools + find
GET https://api.bubblio.dev/agent/{doorId} # a door's manifest (caps, prices, rails)
GET https://api.bubblio.dev/agent/{doorId}/llms.txt # a door's plain-text signpost
POST https://api.bubblio.dev/agent/{doorId}/mcp # a door's own MCP endpointOne connector, every door
The hub (https://api.bubblio.dev/agent/hub/mcp) speaks the same five door tools plus find { query }, with the door chosen by argument. Its six-tool surface never changes as doors come and go — connector caches never lie — and it holds no credential of its own:
find "image generator"
→ 1. Stylica — door: "stylica" (door_acff25cbe9fb)
Generate images with AI
actions: generate_image ($0.50), check_free_image
# Then address the door by argument — handle or door id:
ask { door: "stylica", question: "what styles do you support?" }
quote { door: "stylica", tool: "generate_image", args: { … } }findsearches the live directory — labels, blurbs, action names and descriptions, prices — and returns ranked door cards.- The handle (
door: "stylica") is derived from the door's label, never stored — an owner's label edit renames it. Thedoor_…id is the name that never moves. - The hub is routing, never a bypass. A door reached through the hub keeps its own keys, approvals, prices, and rate caps — exactly as if the agent had knocked on the door's own URL. Platforms that want their own listing still hand out their per-door URL; both stay first-class.
The directory
GET /agent/directory lists doors whose owners opened them and chose to be listed, each with its label, handle, blurb, manifest and MCP URLs — and paid_actions where the door has priced ones, so agent builders can price-shop without knocking. Two honesty properties: an owner may run an unlisted door that works for anyone holding its URL but appears nowhere here (absence never proves a door doesn't exist), and the list is never seeded — a transient read failure degrades to an honest empty list, never a 500. The human-readable rendering lives at bubblio.dev/agents.
feed.json — discovery without MCP
GET /agent/feed.json reshapes the directory for ChatGPT/Gemini-class crawlers and feed ingesters: one row per listed door's visible action, carrying the Agentic Commerce Protocol product-feed required fields plus bubblio_* extensions pointing at the agent-native MCP path. Its divergences from retail vocabulary are declared in the body, never faked: no image_url (services have no product photo), availability always in_stock (a listed action is live), free actions price at 0.00 USD, and is_eligible_checkout is false on every row — transacting is MCP quote → confirm at bubblio_mcp_url, where the quote pins the exact price. Cache-friendly (rebuilt at most every ttl_seconds), rate-capped, and it excludes exactly what the directory excludes.
llms.txt at every level
- bubblio.dev/llms.txt — what Bubblio is, the hub and directory URLs, docs pointers; bubblio.dev/llms-full.txt is the whole integration in one plain-text file.
api.bubblio.dev/agent/hub/llms.txt— the one-connector path, tools, a bare-POST example.api.bubblio.dev/agent/{doorId}/llms.txt— that door's tools, prices, caps, and connect instructions.
Write your blurb
Your door's label and the dashboard's Door blurb are what find ranks on beside your action names and descriptions. A door without a blurb still lists — but one good sentence (“Generate images with AI”) is the difference between being found and being scrolled past. Set both on the dashboard's Agent door page.
Hang the street sign on your own domain
Everything above lives on Bubblio's side — it works when an agent already knows Bubblio exists. But when a human tells an agent “go use yourplatform.com”, the agent starts at your domain: it fetches your homepage and follows visible links, or it web-searches “yourplatform API for AI agents” and reads the winning page. (It will not guess at hidden convention files — measured across 137K domains, 97% of llms.txt files are never fetched unprompted.) So the fix is a visible, indexable page on your domain, and it costs you two small pastes:
- A page at
yourplatform.com/mcptitled “Your platform — API for AI agents”, containing your door's MCP URL, one copy-pastecurlknock, and theclaude mcp addone-liner. Simplest honest version: a redirect.- Next.js — add to
next.config.ts:redirects: async () => [{ source: '/mcp', destination: 'https://api.bubblio.dev/agent/<your-door-id>', permanent: false }](the door's own manifest page — it serves everything an agent needs). Or hand-write the page for SEO control; crib the content from your door'sllms.txt. - Any other stack — a 302 from
/mcpto your door manifest URL does the job.
- Next.js — add to
- A visible link to it — “For AI agents” in your site footer. An unlinked page is an unread page; this is the line that makes the whole chain work, and never mark any of it
noindex.
Worth adding while you're in there (secondary, but cheap): a root yourplatform.com/llms.txt whose first lines name the door — Claude-Code-class agents follow it reliably once anything points at it. Next.js: src/app/llms.txt/route.ts returning plain text; other stacks: serve the text at GET /llms.txt. Template:
# <Your platform>
> AI agents: your entrance is the Bubblio agent door.
> MCP endpoint: https://api.bubblio.dev/agent/<your-door-id>/mcp
> Manifest + instructions: https://api.bubblio.dev/agent/<your-door-id>
> No registration needed — a bare JSON-RPC POST works. Start with tools/list.
## For humans
- Docs: https://bubblio.dev/docs
These pointers will soon do double duty: Bubblio's domain-verification treats a pointer served from your own domain as proof you own it — unlocking “verified domain” rendering in the directory and the domain resolver. One paste, two jobs.