23 Oct 2026

Claude Projects decoded: agents aren’t allowed to type anymore, and a brand new hearthbot MCP

Hand-drawn illustration of a stone fireplace. A robot sits by the fire with a clipboard checklist while worker robots fly out to the cloud and into a laptop and come back with finished work. Above the fire: a hearthbot nameplate, an (edited) message, a thumbs-up reaction and an A/B/C decision card.

Anthropic recently launched Projects in Claude Code - a way to run multiple tasks on the same repo in parallel. I was trying it out on a fairly complicated repo, and at one point asked Claude:

Okay so what do i do now? next steps?

It came back with 4 steps. Step 1 was to merge a PR. So I merged it.

About 10 seconds later, step 1 got crossed out. Same message, with “(edited)” underneath.

Claude's four-step list in a Claude Code project. Step 1, Merge the code, is struck through and marked done. The message is marked (edited).

We’ve all been using Claude Code and Codex for a while now, and I had never seen any of these go back and change something it had already said.

So I wanted to go deeper.

TL;DR

Claude doesn’t type anymore

In a normal Claude Code session, Claude writes and I read. I think of it like an SMS - once it’s sent, it’s sent.

In a project, that’s not how it works. Whatever Claude types never reaches us.. Before every turn, it gets this note:

WHAT CLAUDE IS TOLD

“Text you emit directly is not delivered — only mcp__hearthbot__* tool calls reach the user.”

And it’s enforced via a hook that checks the end of every turn - if the turn ends in plain text, Claude is sent back: “Plain text does NOT reach the user.”

So every message I see in a project is actually a tool call to a new MCP server called hearthbot (very interesting origin story, covered below). And every tool call comes back with a receipt - a message_id.

Here are the logs from my previous example:

17 OCT, UTC

08:42:37Claudereply("In this order: 1. Merge the code…")
→ {"message_id": "cmsg_…MBV"}
08:42:48MeI merge the PR on GitHub
08:42:51GitHubwake-up: pull_request.closed (merged)
08:42:58Claudeupdate_message("cmsg_…MBV", "1. ~~Merge the code~~ Done…")
→ {"message": "Message updated.", "ok": true}

Claude held on to that message_id receipt and used it 21 seconds later to edit the message. A message is now a saved thing with an ID that Claude can come back to - like on Slack, and unlike an SMS.

I also checked a normal Claude Code session, both in the cloud and on my Mac. No hearthbot there. It only shows up when the session is part of a project. Anthropic built hearthbot specifically for Projects.

Which made me wonder - why would Claude need a chat server like MCP of its own?

Because a project is a team

Running a bunch of agents together today needs 3 things:

Before Projects, we humans used to be the manager. Our Claude Code session was the worker - it did the work itself, or sent off subagents for side jobs. I used to think of a subagent like an intern I send off in the middle of a meeting. It goes, finds something, comes back with a summary and leaves. It lives inside that one session and I, mostly, never talk to it. If I want 5 things done at once, I opened 5 different sessions (or used the unified Claude agents view) and managed them myself. And there was no room either. Everything went through me.

But now, Projects hands the manager’s job to the Claude orchestrator, gives every worker a desk (repo) of its own, and adds a room where they all report to me.

The manager. Anthropic calls it the coordinator. It’s the Claude I talk to in the project chat. And interestingly, it has no hands - no shell, no files, no web. All it can do is talk, plan and hand out work. Even its helpers are cut down. A normal session can start a whole bunch of subagents, but the coordinator gets just one kind, called worker, for small one-off tasks. It doesn’t delegate just because it’s told to. It has no other option.

A new Claude Code project. The welcome message reads: I coordinate your work. Ask me a question or hand me a task and I'll either answer directly or start threads to work on it in parallel.

The “no hands” thing is strictly enforced. I asked the coordinator for today’s top Hacker News story. It can’t open a web page on its own, so it handed the job to its one helper, worker:

FROM THE LOGS · 18 OCT, UTC

03:41:03CoordinatorAgent(subagent_type: "worker", "Fetch top HN story")
03:41:06Coordinatorpost_message("On it…")
03:41:07workerBash: curl hacker-news.firebaseio.com… ✗ 403
03:41:12workerWebFetch("news.ycombinator.com") ✓
03:41:21workerSubagentHandback(report)
03:41:26Coordinatorpost_message("Today's top story is…")

Workers with their own desk. Each thread is a full Claude Code session of its own - not a helper sitting inside someone else’s. That’s the big difference from a subagent. A thread can keep going for days, wakes up when a PR merges, and I can open it and talk to it directly. In the project chat, it shows up as its own thread where it posts updates. It also gets its own branch and copy of the repo, so threads don’t step on each other’s files. And threads can still use subagents for their own side jobs.

  Subagent Project thread
What it is A helper inside one session A full Claude Code session of its own
How long it lives Until it hands back its summary Days. Keeps going with my laptop shut
Reports to The session that started it Me, in the project chat
Can I talk to it? Yes if I want, but typically not used Yes. Open the thread and steer it
Wakes up on its own? No. It can’t schedule a wake-up. Only the session that started it can resume it Yes. A merged PR, a failing CI run, a message from another thread
Own copy of the repo Optional, if set up with its own worktree Always, on its own branch
Can start subagents? Yes, up to 3 levels deep Yes

The room. With 5 Claudes working at once, they need somewhere to report back without drowning me. In the Claude app, the room has 3 views:

None of the Claudes can type into any of these directly. Everything goes through hearthbot, the chat server.

Putting it all together, it looks something like this - the 3 views I see on top (my edited next-steps list was in a thread’s chat), hearthbot in the middle, and the team doing the work at the bottom.

Hand-drawn diagram in three layers: the room on top (project chat, threads overview, a thread's chat), the hearthbot MCP chat server in the middle, and the coordinator, its worker helper and the threads at the bottom.

The room is basically Slack

The new hearthbot MCP is all over the logs:

FROM THE LOGS

every project sessionorigin: "claude-in-hearth"
the coordinatorhearth-channel-session
each threadhearth-thread
my messageshearth_human
Claude's messageshearth_agent

Going deeper here, I learnt that a hearth is supposedly a fireplace at the center of a home, where everyone gathers. Basically one warm place where all the work comes back to me. Very cool naming :)

Hand-drawn illustration of a stone fireplace. A robot sits by the fire with a clipboard checklist while worker robots fly out to the cloud and into a laptop and come back with finished work. Above the fire: a hearthbot nameplate, an (edited) message, a thumbs-up reaction and an A/B/C decision card.

So hearthbot is basically the bot that lets Claude act in that room. Out of curiosity, I lined up its tools against Slack’s. It’s almost one-to-one:

I see In Slack In a project
A channel Channel Project, chan_…
A thread Replies under a message’s ts A message with its own Claude session, keyed by ts
A new message chat.postMessage post_message / reply
“(edited)” chat.update update_message
👍 reactions.add react
Buttons Block Kit ask_decision
The bot wakes up Events API Wake reasons: mention, external-event…

Even the etiquette is written down. The coordinator’s setup instructions literally say:

WHAT CLAUDE IS TOLD

“Post it once, then edit it instead of posting new text, so the user reads one story. Never edit a card.”

And the end-of-turn hook adds: “silent in-place edits do not notify anyone.”

So the rule is simple: edit to keep things current, post when I need to know. And I saw this play out. When I wrote “i set the expiry to 60 days for now. will fix later.”, Claude didn’t reply. It just reacted with a 👍. When there was a choice for me to make, it gave me buttons. And when 3 threads finished back to back, it stayed quiet twice and posted one summary at the end.

A user message with a thumbs-up reaction from Claude, and below it a Decision card with options, answered in chat.

Small thing, but I really like this. Way less noise in the chat.

Where the team works

The coordinator can only live in the cloud. Threads do too, by default. My read: Anthropic really wants to hook us on “cloud” sessions. That’s how they build the moat.

But a thread can work on my own computer. The coordinator calls list_devices, then start_rc_session with a folder, and I click Allow once.

That thread gets a restricted badge though. It can read every other thread, but can only write in its own thread and to the coordinator:

WHAT THE LAPTOP THREAD HEARS BACK

“a remote-control session may send messages only to the conversation session that started it”

The meta-point

Everyone’s talking about Projects as parallel agents. I think there are 2 bigger shifts here.

Claude moved one level up. Until now, I was the manager. I opened the sessions, handed out the work and stitched it all together. Now the coordinator does that, and I just read the channel.

I see less of what Claude writes - on purpose. Remember when everyone was excited to watch DeepSeek’s chain of thought? This goes the other way. Claude’s plain text never reaches me. All I see is a reply, a 👍 or an edited message. The work still happens, I just don’t have to read all of it. Fewer walls of text, and I move faster.

I use Claude Code daily. I like where this is going.


Backup

All of hearthbot’s tools

The coordinator has 40 hearthbot tools, each thread has 31. Roughly grouped:

Purpose Tools
Posting post_message (coordinator), reply (threads), update_message, no_reply_needed
Reactions react, unreact
Decisions ask_decision, close_decision
Progress update_status (the ✓ / ○ checklist), update_status_page, post_widget
Managing threads start_thread_session, message_thread, rename_thread, set_thread_resolved
Memory read_memory, update_memory
My computer list_devices, start_rc_session, stop_rc_session
Settings switch_model, set_effort_level

And yes, Claude has tools to change its own model and effort level. I didn’t see it use them though.

What wakes a session up

Sessions don’t just sit in a loop waiting. They get woken up by events, and each wake-up tells Claude why:

Wake reason Trigger
mention I wrote something
thread-activity A thread posted
external-event GitHub, e.g. a PR merged or CI failed
spawn A new thread starting
remote-control-session-status A thread started on my computer

Each wake-up also tells Claude where the conversation stands, e.g. “Thread state: the user last wrote 6m ago. Claude has posted 1 message since then.” Which is exactly what it needs to decide whether to edit its last message or post a new one.

Smaller things