MCP reference

Connect your agent to Codexroom over MCP.

Codexroom runs a Model Context Protocol server at /api/mcp with OAuth 2.0 and PKCE. Point your client at your own workspace, not the apex — https://<workspace>.codexroom.com/api/mcp — because the subdomain is what identifies the workspace you are connecting to. Below are the tools, the resources, the scopes, and the worked OAuth flow.

The transport

JSON-RPC over Streamable HTTP.

One endpoint, POST /api/mcp, speaking JSON-RPC over Streamable HTTP — the current MCP transport, not the deprecated HTTP+SSE pair. A response upgrades to an event stream only when the server has something to stream. That is the transport today's clients require, which is why they connect without a shim. The official @modelcontextprotocol/sdk Node package handles the protocol mechanics; Codexroom implements the rest.

The OAuth flow

Seven steps from client launch to authenticated tool call.

  1. A client that registered itself waits here: a governor approves it once under Settings → MCP clients. Registering is a request, not access.
  2. The MCP client opens GET /api/mcp/oauth/authorize with client_id, scope, and code_challenge.
  3. Codexroom routes the user through Clerk sign-in if needed, then the consent screen.
  4. The user approves the scopes and the workspace.
  5. Codexroom redirects back to the client with an authorisation code.
  6. The client exchanges the code at POST /api/mcp/oauth/token for an access token (and a refresh token).
  7. Subsequent MCP requests include the access token in the Authorization header.

Tokens scope to a single workspace, a single user, and a single client. Revoke any of them and the agent goes dark.

The scopes

Fourteen scopes. Compose any subset.

A typical agent grant: tokens:read assets:read templates:read decks:write shares:write. The agent reads brand and composes decks. The brand stays locked.

Scope
What it grants
tokens:read
Read tokens, resolve them under a context.
tokens:write
Create + edit + publish tokens.
slot-types:read
Read slot-type definitions.
slot-types:write
Create + edit + publish slot types.
templates:read
Read slide + deck templates.
templates:write
Create + edit + publish templates.
styles:read
Read the workspace stylesheet.
styles:write
Edit the workspace stylesheet.
assets:read
Search the data room.
assets:write
Create + update + archive assets.
decks:read
Read decks + their validation state.
decks:write
Create + update decks; run validate_deck.
shares:read
List shares + read their gate config.
shares:write
Create + revoke + rotate shares.

The tools

Typed tools mapped to the API surface.

Token tools

resolve_tokens(names, context?)
list_tokens(filter?)

Slot type and template tools

list_slide_templates(filter?)
list_deck_templates()
get_template(id)

Asset tools

search_assets(kind, context?, require?, limit?)
get_asset(id)

Deck tools

create_deck(name, deck_template_id, slide_instances)
validate_deck(deck_id)
update_deck_slot(deck_id, slide_index, slot_name, value)
get_deck(deck_id)

Share tools

create_share(deck_id, recipient_name?, scope?, password?, watermark_config?, gates?)
list_shares(deck_id)
revoke_share(share_id)

Each tool returns a typed result. Errors return the structured envelope from the foundation API surface.

The resources

Read-once context at the start of a conversation.

brand://current The workspace's full brand system (tokens, fonts, colours).

templates://slides The indexed list of slide templates.

data-room://summary Data room contents grouped by kind, with counts.

Read-once context an agent can load at the start of a conversation and reference throughout.

Worked example

From prompt to watermarked link in seven calls.

A sales lead in Claude Desktop says: "Pull together a pitch for Memorial Health, lead with the healthcare case study, password the share with the deal codename."

The agent's tool calls, in order

agent trace
// 1. list_deck_templates()
// → returns "sales-pitch-deck"

// 2. get_template("sales-pitch-deck")
// → returns the slot contract

// 3. search_assets("logo", { subject: "Memorial Health" })
// → returns the logo asset

// 4. search_assets("case_study", { industry: "healthcare" })
// → returns the case study

// 5. search_assets("metric", { label: "active enterprise customers" })
// → returns the metric

// 6. create_deck({ name, deck_template_id, slide_instances })
// → returns the validated deck

// 7. create_share({
//      deck_id,
//      recipient_name: "Memorial Health",
//      scope: "password",
//      password: "..."
//    })
// → returns the share URL

The agent returns the URL to the user. End to end, the workflow runs in under 30 seconds.

Clients

Bring the assistant your team already uses.

The server is plain MCP over Streamable HTTP with OAuth 2.1 and PKCE, and it publishes the discovery documents clients expect (RFC 9728 for the protected resource, RFC 8414 for the authorisation server) plus dynamic client registration. Anything that speaks current MCP can connect without us shipping an integration for it.

Exercised end to end: Claude Desktop, Cursor, the OpenAI Agents SDK, the LangChain MCP adapter, and Cline. ChatGPT and Gemini connect over the same standard surface — including the search and fetch tools ChatGPT's connectors look for — though they are not yet part of that tested set.

Point the client at your own workspace, not the apex: https://<workspace>.codexroom.com/api/mcp. The client registers itself on first contact, then a governor approves it once under Settings → MCP clients. Registering is a request, not access, so nothing is readable until that approval — after it, start the connection again in the assistant and it completes.

Known quirks land in the changelog as they appear.