Skip to content

MCP server

Connect Claude, Cursor, or any MCP client. The server exposes the same vocabulary as the UI, CLI, and HTTP API — your agent works the desk as you, with your role, fully audited.

Connect

Pick your client. Need a key first? Create one in Settings → Developer — shown once.

Claude · browser

1. Copy the server URL.

bash
https://api.quietdesk.dev/mcp

2. In claude.ai or Claude Desktop → Settings → Connectors → Add custom connector, paste the URL.

3. Claude opens Quietdesk in your browser — click Approve. No key to copy; revoke any time from the API keys list.

✓ Check it worked

Ask Claude “list my Quietdesk boards”.

Claude Code

1. Create a key in API keys (shown once — copy it).

2. Add the server:

bash
claude mcp add --transport http quietdesk https://api.quietdesk.dev/mcp \
  --header "Authorization: Bearer ptl_u_YOUR_KEY"

✓ Check it worked

In Claude Code, /mcp lists quietdesk as connected.

Any client / CI

1. Point any MCP client at https://api.quietdesk.dev/mcp with header Authorization: Bearer <key>.

2. For CI / scripts, prefer an org key (a service identity — can’t touch org, billing, members, or keys):

bash
QD_TOKEN=ptl_o_… QD_ORG=finnoto

3. REST without MCP? The full OpenAPI is at https://api.quietdesk.dev/docs.

✓ Check it worked

curl -H "Authorization: Bearer $QD_TOKEN" https://api.quietdesk.dev/api/v1/me → 200.

Prefer the terminal, or scripting CI? See the qd CLI.

Tools

Tool names are snake_case within [a-zA-Z0-9_-] (MCP requires it) — clients namespace them as mcp__quietdesk__<tool>.

Query (read — safe by default):snippets_list · snippets_get · cards_list · cards_get · todos_list · milestones_status · boards_get · boards_context

Operate (write — a read-only key is rejected; clients should confirm):snippets_create · cards_create · cards_update · cards_move_status · todos_create · todos_complete

Board structure (write, admin+):boards_create · lists_create · lists_update · lists_reorder · lists_delete

Every card needs a list_id, so a board with no columns can't hold one. boards_create takes an optional lists — up to 20 names, seeded in order, in the same transaction — so the board is usable the moment it exists:

text
boards_create({ name: "Ops", card_id_prefix: "OPS", lists: ["To Do", "Doing", "Done"] })

Reshape the columns later with lists_create and lists_update (name, WIP limit, collapsed, mapped status). lists_reorder takes list_ids naming exactly the board's current lists. lists_delete is destructive: it requires confirm: true and is refused while the list still holds cards. List ids come from boards_get / boards_context, which return the board's lists.

The rules agents live by

  1. Attribution. Every write is audited as by <you> (via <client>). There is no anonymous agent action.
  2. Gates. cards_move_status into done on a gated board returns gated_move_requires_human. Your agent can prepare everything; a person approves.
  3. Scope. The token's organization and role bound everything — same as the UI.

Example session

text
You:    What's waiting on my review on the Q3 Roadmap board?
Agent:  → cards_list({ board:"q3-roadmap", status:"in_review", assignee:"me" })
        Two cards are at your gate: PS-117 (criteria 2/2 ✓) and PS-121 (1/2).

You:    Approve PS-117 and hand PS-121 back to Anika to re-check the retry case.
Agent:  → cards_move_status({ id:"PS-117", workflow_status:"done" })   ✓ allowed: human caller
        → cards_update({ id:"PS-121", assignees:["anika"] })
        Done. PS-117 shipped — you approved it, so it cleared the human gate.

Using Claude Code?

Install the Quietdesk skill with qd skill install. It carries the conventions these tools assume — where notes belong, what the pipeline actually enforces, and why a tool missing from a session usually means a stale binding rather than a server without it.

Reading these docs by machine? The whole corpus is at /docs/llms.txt and /docs/llms-full.txt.

One vocabulary, every door.