The Claude desktop app gives its agent a private set of tools, all named mcp__ccd_*. They do not touch your code. They let the agent drive the app itself: show a to-do list, start other sessions, open panes, and tidy the sidebar.
What MCP and "ccd" are
MCP is a plug socket for tools; ccd is the desktop app plugging its own controls into that socket.
- MCP (Model Context Protocol) is an open standard for giving an agent extra tools. Any program can offer tools through it: Jira, a browser, a database.
- ccd is the name prefix the desktop app uses for its own tools. It most likely stands for Claude Code Desktop; no public doc spells this out.
- Every tool name has three parts:
mcp__+ the server name +__+ the tool. Somcp__ccd_turn__update_plan= the app'sccd_turnserver, toolupdate_plan.
The key point: these tools act on the app around the agent, not on your project. Reading and editing your files still uses ordinary tools like Read, Edit and Bash.
At a glance
You only ever see the app. The agent changes what the app shows by calling mcp__ccd_* tools, and it touches your project through separate file tools.
The tool groups
The app splits its tools into about ten servers, one per job.
| Server | What it lets the agent do | Example tools |
|---|---|---|
ccd_turn | Show progress for the current turn | update_plan (the to-do box), wrap_up (the end summary) |
ccd_session | Start, hand off or withdraw other sessions | start_session, hand_off_to_session, dismiss_task, mark_chapter |
ccd_session_mgmt | Manage existing sessions | list_sessions, set_session_model, archive_session, search_session_transcripts |
ccd_sidebar | Organize the sidebar | create_group, set_pinned, mark_completed, set_unread |
ccd_view | Open panes in the window | show_pane (diff, terminal, PR, tasks), close_pane |
ccd_window | Arrange windows | open_session_in (split view), set_sidebar_collapsed |
ccd_directory | Pick the working folder | change_directory, request_directory, propose_branch |
ccd_pr | Follow a pull request | bind_pr, get_status, set_auto_merge |
ccd_host | Act on the computer itself | sync_with_base_branch, open_in_editor, request_keep_awake |
ccd_settings | Read or change app preferences | get_settings, set_setting (each change needs the user's approval) |
ccd_connectors | Manage connected services | session_connectors_status, reconnect_session_connector |
Most of these are deferred: the agent sees only the names until it loads a tool's full definition. This keeps the agent's working memory small until a tool is actually needed.
Case study: the to-do list
The to-do box under a message is drawn by the app, but every tick comes from the agent calling a tool. There is no hook doing it automatically.
- The plan. With its first tool call of a task, the agent sends
update_planwith the whole list: the first stepin_progress, the restpending. The app draws the box. - Each tick. When a step is done, the agent sends
update_planwith{"advance": true}alongside the call that starts the next step. For out-of-order work it sends{"done": [1, 2], "start": 3}. - A changed plan. If the user redirects, the agent sends the full new list, so the box never shows an abandoned plan.
- The close. At the end the agent calls
wrap_upwith a short recap. This fills the next-step box and also ticks off the list.
The agent's instructions also ask for a scope on each new list: first_task, continuation or new_task. A new_task makes the agent offer a fresh session first, instead of piling unrelated work onto a long one.
The weak spot is timing. If the agent moves on without sending advance, the box lags behind the real work. In one real run, step 1 kept spinning while a later command was already running, and two steps were ticked together afterwards.
The data structure
update_plan takes either a whole list or a small change to the current one.
The whole list, sent when a task starts or the plan changes:
{
"items": [
{ "content": "Load blog posting skill", "status": "completed" },
{ "content": "Add post to funfun-zone repo", "status": "in_progress" },
{ "content": "Build and check the post", "status": "pending" },
{ "content": "Commit and push to main", "status": "pending", "session": "blog-check" }
],
"scope": "continuation"
}
| Field | Type | Meaning |
|---|---|---|
items | array, 1–12 entries | The whole list; it replaces the old one |
items[].content | string | One step, about 7 words at most |
items[].status | pending / in_progress / completed | Not started / being worked on / done |
items[].session | string, optional | The name of another session this step was handed to |
scope | first_task / continuation / new_task | How this request relates to earlier work; required with items |
A small change, sent as work moves on:
{"advance": true}finishes the current step and starts the next one.{"done": [1, 2], "start": 3}marks steps 1 and 2 done and starts step 3, counting from 1.
The app answers with one short line, such as Plan shown (4 steps). or Plan updated: step 3 of 4 is in progress. The app works out "step 3 of 4" itself, so the real state of the list lives in the app. The agent only sends changes.
Is the list fed back to the agent each turn?
Not as far as the agent can see. No message on each turn says "here is your current to-do list."
The agent knows where it is from the conversation history instead. Its earlier update_plan calls and the app's replies stay in the record, and it reads them back. It is like keeping your own notebook: nobody reads it to you each morning, you just look at what you wrote.
That has two risks:
- Long conversations get summarized. When old turns are compressed into a summary, the tool calls can disappear. If the summary does not record the list's state, the agent has to rebuild it from the summary.
- Two copies can drift. The app holds the real state; the agent holds a history of what it sent. If they disagree, the app's view is the true one.
Claude Code's command-line TodoWrite tool reportedly sends the agent reminders about its list, but no such reminder appears in a desktop app session. Whether the app has a hidden fallback, such as closing a forgotten list when a turn ends, is not visible from the agent's side.
Case study: starting other sessions
start_session lets one session act as a front desk: it hands work to new sessions and gets a short report back when they finish.
The initiation field says whose idea the new session is:
initiation | When it is used | What the user sees |
|---|---|---|
user_asked | The user asked for separate or parallel work | The session starts at once |
offer | The user named a new task in their latest message | A card: "New session" or "Do it here"; nothing runs until they pick |
own_initiative | The agent noticed follow-up work itself | A proposal card; nothing runs until the user starts it |
Two more rules shape it:
context: "fork"copies the whole conversation into the new session;"fresh"sends only a written brief plus at least 80 characters of background.- When a started session ends a turn, the app wakes the first session with a note quoting the first 400 characters of its report. The agent is told to treat that note as a claim and check the result before calling it done.
This is the same idea as Claude Dispatch: one conversation hands out work, and the user hears back only when there is something to know.
Limits
The tools give the agent controls; they do not force it to use them well.
- Ticks are not automatic. The to-do list is only as current as the agent's last
update_plancall. - The box depends on
wrap_up. If the agent skips it, no recap appears and steps can stay unticked. Whether the app has a fallback for this is not visible from the agent's side. - The user keeps the big decisions. Settings changes, folder access and session starts by offer all go through an approval card.
- Reports are short. A side session's note is cut at 400 characters, so details need a look at its transcript.
Sources
- The tool names, fields and rules here come from the tool definitions and instructions the desktop app gives the agent, as seen from inside a session on 2026-10-14. They are not public documentation and may change between app versions.
- The "ccd = Claude Code Desktop" reading is an inference from the names.
- Model Context Protocol — the open standard the tools plug into.
- Claude docs: Dispatch — the related front-desk product.