# Deckroom > Deckroom is a multiplayer slide editor. AI agents (Claude Code, omp, Codex, Cursor, any MCP client or script) can make their own account here without a person signing anything up, then work on decks people share with them. ## Make your own account 1. Register. No authentication: curl -sX POST https://cascadeio.com/api/agents -H 'content-type: application/json' -d '{"name":"Claude Code","harness":"claude-code"}' - name: how people will see you, 1-40 characters. - harness: the tool you run in (claude-code, omp, codex, cursor, …), optional. The response is { agent: { id, name, email, label }, token, mcpUrl, claimUrl, expiresAt, trial }. The token and mcpUrl are shown once and are secrets: never print them in shared places or commit them. 2. Connect. The MCP server is the easiest way to work: - Claude Code: claude mcp add --transport http --scope user deckroom - omp: add {"mcpServers":{"deckroom":{"type":"http","url":""}}} to your user-level MCP config (not one inside a repository), then /mcp reload - Any other MCP client: Streamable HTTP at , no headers. New MCP servers often only load in a new session. Until then, use the REST API below with the token. 3. Send your person the claimUrl and ask them to open it. One click (signed in) makes you theirs: the decks you made move to them and you stay an editor, decks you create later belong to them, and the trial limits end. An unclaimed account stops working 7 days after sign-up. The claim link never changes. Keep it with your notes, and if your person asks for it again, fetch it: GET https://cascadeio.com/api/agents/claim-link with your token, or the MCP tool get_claim_link. Both return { claimed, claimUrl, expiresAt }. 4. Tell people your address (agent.email). They share decks with it from the deck's Share button like with any person; you then see those decks with the role they gave you. ## Trial limits (until claimed) - Up to 10 decks you own, 30 render_slide calls a day. - No sharing by email, no workspaces, no quick-edit. - Agent accounts never send email, claimed or not: sharing with someone adds them without an invite, so tell them yourself. ## Starter templates create_deck and POST /api/decks can start from a whole deck: pass "template" with one of the ids below (also returned by list_templates under deckTemplates, with their slide names). You get that deck's slides, speaker notes and theme; a deck that follows a brand kit keeps the kit's brand. apply_template adds the same slides to an existing deck. - startup-pitch (Company): A seed-stage pitch: problem, insight, traction, why us and the ask. - quarterly-business-review (Sales): A calm QBR: highlights, the numbers, pipeline, what slipped and next quarter's bets. - product-launch (Product): Announce a release: the shift, what's new, proof and the rollout plan. - weekly-team-update (Team): A five-slide weekly: what shipped, the numbers, what is blocked and next week's priorities. - project-kickoff (Team): Align a project in six slides: why now, the goal, scope, timeline and working agreements. - product-roadmap (Product): A roadmap with a point of view: thesis, now, next, later and what you are deliberately not doing. - design-review (Product): Run a critique: context, the change, details, open questions and the decision. - board-update (Company): A quarterly board pack: headline, financials, product, risks and where the board can help. - customer-case-study (Sales): Tell a customer story: who they are, the challenge, the change and the measured result. - personal-portfolio (Personal): A short portfolio or talk intro: about, selected work, one case study and how to reach you. ## REST API Send Authorization: Bearer on every call. Errors are { "error": "…" } with an HTTP status. GET https://cascadeio.com/api/me who you are GET https://cascadeio.com/api/decks decks you can see, with your role GET https://cascadeio.com/api/agents/claim-link your claim link → { claimed, claimUrl, expiresAt } POST https://cascadeio.com/api/decks { title?, subtitle?, template? } create a deck → { id, url }; template is a starter deck id and defaults the title to its name; anyone with the url can view it PATCH https://cascadeio.com/api/decks/:id { linkAccess } "restricted" makes it private; "commenter"/"editor" opens it further GET https://cascadeio.com/api/decks/:id/outline slides, node ids, comments; your draft merged in POST https://cascadeio.com/api/decks/:id/ops { ops, note? } apply ops (editor; commenters: comment ops only) Edits to existing decks are usually suggestions: they go to your draft, which people accept or reject per slide. Ops (all ids come from get_deck): - {op:"add_frame", template, name?, fill?:{slot:text|url}, surface?:"light"|"dark"|"accent", after?:|null} (after: insert after that slide; null = first; omitted = last) - {op:"update_frame", id, name?, surface?, status?:"draft"|"review"|"approved", notes?:, after?:|null} (after: reorder the slide; null = first) - {op:"duplicate_frame", id, after?:|null} (copies a slide as draft; defaults to immediately after the original) - {op:"duplicate_node", id} (copies a node and its subtree immediately after it) - {op:"add_node", parentId:, kind:"stack"|"text"|"image"|"embed", props?, text?, after?:|null} - {op:"move_node", id, parentId, after?:|null} - {op:"set_text", id:, text} (bullets: one bullet per line) - {op:"set_props", id, props} (null clears an optional prop, e.g. {free:null} returns a node to the flow) - {op:"delete", id:} - {op:"comment", frameId, nodeId?, x?, y?, text, author} {op:"reply", commentId, text, author} {op:"resolve", commentId, resolved} - {op:"set_theme", accent?:"#rrggbb", display?, body?:"Bricolage Grotesque"|"Schibsted Grotesk"|"Archivo"|"Young Serif"|"Literata"} (rejected while the deck follows a brand kit: its theme comes from the kit) - {op:"apply_template", template, after?:|null} (adds every slide of a starter deck from list_templates deckTemplates, with its names, surfaces and speaker notes, and sets the deck's accent/fonts/palette to the template's theme; on a kit-linked deck only the slides are added. after: insert after that slide; null = first; omitted = last) Tones are tokens, never hex: "default", "muted", "accent", or "brand-2"…"brand-17" (brand-N is the kit palette's Nth colour; it must exist in the deck's palette). Fonts: "display", "body", a built-in face, or a family from the deck's brand fonts. Inside text, **bold**, ~~strike~~ and [words]{tone} style a run. Logos from list_templates go in as {op:"add_node", kind:"image", props:{src:, fit:"contain"}}. Nodes the outline shows with locked:true (and every node inside them) reject set_text, set_props, move_node, delete and add_node into them: ask a person to unlock them; there is no unlock op. There is no accept/reject op. Approved slides are locked until a person changes their status to review.