claude.ai / Claude Desktop (OAuth)
Add a custom connector with the URL:prompt=consent to force the picker past an existing grant).
Claude Code / CLIs (API key)
/mcp also accepts the instance’s API keys directly — no OAuth dance:
presentations:read for reads, presentations:write for mutations.
Verify an instance
get_me returning your identity proves discovery, registration, login,
consent, token exchange, JWKS verification, and the live membership check in
one call.
The tool set
All product tools are prefixedslideless_ and act as the connected user —
identity always comes from the verified credential (OAuth token or API key),
never from a tool parameter. Reads require presentations:read, writes
presentations:write; the API’s fail-closed allowlist and per-deck read
privacy apply unchanged (a tool can never read a deck the caller can’t).
The
/mcp transport caps request bodies at 1 MiB, so inline uploads are
bounded at 768 KiB of decoded content (base64 inflation means anything larger
cannot fit the JSON-RPC envelope anyway) — the tools answer a clean error
pointing at slideless push / slideless pull for bigger decks.
For products extending the template
Tools live inapps/server/src/mcp/. Conventions (ported from a proven
predecessor MCP template): reads declare readOnlyHint and check presentations:read;
writes describe themselves as confirm-first and check presentations:write
(tool-level checks are UX — the API’s fail-closed allowlist in
middleware/scopes.ts is the enforcement point); tools call the instance’s
own API in-process forwarding the caller’s bearer (MCP is just another API
client — never a privileged path); the acting user is NEVER a tool
parameter (identity comes from the verified credential); map domain error
codes to model-readable hints in mcp/errors.ts. New behavior lands in the
API first — the MCP tool is a thin projection of it.