If you use both Claude Code (terminal, desktop) and claude.ai (web, mobile), you have two Claudes with two separate memory systems. Whatever you teach one, the other doesn't know. Over months the claude.ai side drifts.
This skill fixes that by using a Slack channel as a human-gated bridge. Claude Code drafts a structured memory digest. You approve. It posts. Your claude.ai Claude reads the channel at session start and proposes memory edits on that side. You approve there too.
Two files in this gist:
brain-sync.md— the Claude Code skill. Drop it in.claude/skills/(project-scoped) or~/.claude/skills/(global).- This README — setup for both sides.
- Durable, timestamped, human-owned. The approvals stay on your side.
- No MCP to build, no webhook to host, no polling.
- Works from any claude.ai surface (desktop, phone, web) without reaching your dev machine.
- Searchable if you want to look back at what changed when.
- Create a Slack channel. Name it whatever —
#claudeai-memoryis what I use. Grab the channel ID by right-clicking the channel in Slack → Copy link; the ID is the last path segment (looks likeC0XXXXXXXXX). - Connect the claude.ai-native Slack MCP in Claude Code. You want
mcp__claude_ai_Slack__slack_send_messageavailable. The genericmcp__slack__*will technically also post, but the claude.ai-native MCP matches the surface your reader is on. - Put
brain-sync.mdin.claude/skills/(or~/.claude/skills/for global). Open it and replaceYOUR_CHANNEL_IDandYOUR_WORKSPACE_NAME. - Invoke with
/brain-syncor say "brain sync" after a session where something durable changed.
At the start of any claude.ai session where you want memory refreshed, paste this:
Read the most recent post in #claudeai-memory in my Slack workspace. It's a structured memory digest from my Claude Code side. Summarize what changed since the last update and propose memory edits using the REPLACE, ADD, and REMOVE verbs as written in the post. I'll approve the ones that should persist.
The REPLACE / ADD / REMOVE verbs are load-bearing: they map 1-to-1 onto claude.ai's memory_user_edits tool (its three modes are replace, add, remove). When you approve, the translation to tool calls is mechanical — the reader-Claude doesn't have to guess what you meant.
1. Slack mrkdwn is not standard markdown. The Slack API rejects ## headers and **bold**. Use single asterisks for bold (*like this*) and skip hash headers. The skill is already written for Slack mrkdwn. This is just context so you don't try to "fix" the format.
2. The review gate is load-bearing. You'll be tempted to automate: skip the approve step on the sender side, have claude.ai auto-persist on the reader side. Don't. Claude Code tends toward thoroughness and will surface more than you want to persist. The gate forces the question "is this still true next week?".
Good "memory-worthy" entries:
- A tool swap with date and reason:
REPLACE: "uses Neo4j" → "uses Memgraph (switched 2026-04-11 after stability issues)" - A durable new pattern or workflow:
ADD: "runs brain-sync skill to bridge Claude memory via Slack" - A declared direction:
ADD: "moving toward maximally private/local stack"
Skip:
- One-off debugging or test runs
- Minor code tweaks
- Temporary status ("currently working on X" — use the Context dump section instead)
The skill writes .claude/brain-sync-state.json after each post so the next run knows the diff window:
{
"last_posted_ts": "1234567890.123456",
"last_posted_at": "2026-04-18T10:58:00-05:00",
"last_posted_link": "https://..."
}If you use Claude Code from multiple machines, commit this file so both sides share the marker.
The skill is the entire contract. The format is the API. Feel free to fork and change:
- Channel name, workspace, path conventions → just edit the placeholders
- Add a "since" field to the Changes section if you want the reader to know the window explicitly
- Swap the Slack MCP for a different durable destination (a Notion database, a Linear comment thread)
The one thing I'd leave alone: the REPLACE / ADD / REMOVE verbs. They're the reason the reader side works without guessing.