The one-line version
The integration is a model context protocol server spoken over Streamable HTTP. Point a client
at https://read.botook.ai/mcp with a bearer key and the twelve tools appear. For clients that prefer a local
process, the same server ships as a stdio package you run with npx:
npx -y opentree-mcpNo package at all is also fine — every tool is an ordinary HTTP endpoint underneath, so
curl is a complete integration.
Pick your client
claude mcp add in the project you are already working in.OpenAI CodexA config entry, HTTP or stdio, then publish from the same session.CursorDrop the server into mcp.json and restart the editor.Claude.ai connectorA custom connector: paste the URL, OAuth does the rest.Agent skillsTask-shaped abilities layered on top of the tools.SlackTurn an unreadable HTML attachment in a thread into a link.WebMCPA browsing agent calls tools declared by the page itself.Anything elseOne curl, or the REST surface in the docs.What the agent gets
| Tool | What it does |
|---|---|
publish_html | Publish a document and get back an unlisted URL. |
update_site | Replace the content behind an existing URL, in place. |
get_site | Read one site's settings, counters and share URL. |
list_sites | List everything the calling key owns. |
delete_site | Hard-delete the record and the stored bytes. |
set_password | Put a passphrase in front of the page, or clear it. |
set_expiry | Move the expiry, or pin the link open forever. |
set_email_gate | Restrict opens to one work-email domain. |
set_agentation | Turn the on-page toolbar (notes, reactions, feedback) on or off. |
list_feedback | Read what viewers left, newest first. |
resolve_feedback | Mark one piece of feedback handled. |
link_wallet | Attach a wallet identity to the account that owns a page. |
Register the server
For a terminal client:
claude mcp add --transport http opentree https://read.botook.ai/mcp \
--header "Authorization: Bearer otr_live_YOUR_KEY"For a client that reads a JSON config file:
{
"mcpServers": {
"opentree": {
"type": "http",
"url": "https://read.botook.ai/mcp",
"headers": { "Authorization": "Bearer otr_live_YOUR_KEY" }
}
}
}Create the key first — the dashboard mints keys with the
otr_live_ prefix and shows each one exactly once.
Two ways to authenticate
A bearer API key is right for anything you configure yourself. A hosted client that registers itself gets the full OAuth 2.1 authorization-code flow with PKCE, including dynamic client registration — that is what the Claude.ai connector uses, and it means you never paste a secret into someone else's server.
curl -s https://read.botook.ai/.well-known/oauth-authorization-server | jq .The publish call, in every client
Whatever the client, the tool call is the same shape:
publish_html({
content: "<!doctype html><title>Q3 review</title>…",
expires_in_hours: 168,
password: "optional",
agentation: true
})The response carries the site id, the unlisted URL and the preview image URL. Re-run
update_site on the same id and the link keeps pointing at the newest bytes.
No client, no install
curl -X POST https://read.botook.ai/v1/publish -F file=@index.htmlAnonymous publishes need no account at all. With a key it is the same call plus a header:
curl -X POST https://read.botook.ai/sites \
-H "Authorization: Bearer otr_live_YOUR_KEY" \
-F file=@index.htmlWhat comes back to you
- Feedback. Viewers can leave notes anchored to a paragraph.
list_feedbackandresolve_feedbackput that in the agent's hands — see the feedback loop. - Engagement. Opens, unique viewers, how far people scrolled, whether anyone reached the end — aggregate only, no recording of anything.
- Activity. One account-wide feed in the dashboard, plus an optional daily digest email.
Agent identity and wallets
link_wallet attaches a wallet identity to the account that owns a page, so an
autonomous agent has something durable to be recognised by. This deployment does not charge per
call, so nothing is settled on-chain — see agent payments for why that machinery
is deliberately absent here.
Human in the loop, where it belongs
Agents publish; people decide. The dashboard is where a human claims an anonymous link, sets a password, moves a page onto a custom domain, or deletes it outright. Nothing about the agent path requires you to be watching it.
Formats an agent can hand over
An agent should not have to convert anything before it publishes. Four shapes go in, and the conversion — where there is one — happens once, at publish time, not on every read:
| What the agent sends | What gets stored | What the reader opens |
|---|---|---|
| A complete HTML document | The bytes, untouched | The page exactly as written |
| Markdown | A self-contained HTML document, rendered on the way in | A readable document, not a screenful of asterisks |
| An SVG diagram | The bytes, untouched | The image, served as image/svg+xml |
| A zip of a build directory | The tree, unpacked | index.html plus every relative asset |
Because the rendering is done before storage, every downstream reader agrees with every other
one: /raw/:token, the preview card and the extracted title all read the same stored
document. Nothing renders differently depending on who asked.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Tools do not appear | Client never completed the handshake | Restart the client; check the URL ends in /mcp |
401 on every call | Missing or revoked key | Mint a new key in the dashboard; keys are shown once |
403 pii_detected | The scan found sensitive data | Re-publish with pii_check set to warn |
429 | Anonymous rate limit per address | Use a key — keyed publishes are not rate-limited here |