The Problem You Learn to Live With
I use Claude Code for hours every day. Over time, I noticed a pattern I kept ignoring: context evaporation.
You are 45 minutes into a session. Claude has warned you about a breaking change, made architectural decisions you agreed with, created TODOs for edge cases, flagged a security issue to revisit later. Where is all of that now? Buried in terminal scroll. You half-remember the warning. The TODOs are gone.
I tried to solve this with small workarounds. I created a shell alias (here='pbpaste | bat -l md -p') to quickly paste and read Claude's output as formatted markdown. Copy something important, switch pane, run here, keep working. I tried keeping a text file open alongside my terminal. Every workaround lasted a few days before the friction won. The moment I got deep into a problem, I stopped doing it.
You can also ask Claude directly: "what were the TODOs from earlier?" But that means scrolling back, re-reading context, spending tokens on retrieval instead of work. In long sessions, this adds up.
What made me actually build it was seeing similar frustrations on X. People describing the same thing: important context from Claude Code sessions disappearing into scroll. It was not just my problem. The idea of a blackboard, something like a floating post-it board for coding sessions, kept coming back. After the third time I caught myself re-asking Claude about something it had already told me, I decided to stop patching the problem and build the thing.
How Else Could You Solve This?
Before building anything, I looked at what already exists.
1. CLAUDE.md and Memory Files
Claude Code has built-in persistence: CLAUDE.md for project instructions, memory files for cross-session recall. These are great for long-term context (project conventions, user preferences). But they are not designed for scratch notes within a single session. Writing "remember to check the auth middleware" to a memory file is overkill. It pollutes long-term storage with ephemeral context.
2. TodoWrite (Built-in Task Tool)
Claude Code's TodoWrite tool tracks tasks within a session. It works, but:
- It is invisible. You can not glance at it. You have to ask Claude "what are my todos?" to see them.
- It is one-directional. Claude writes, you read (by asking). You can not add your own items.
- It disappears completely when the session ends, with no option to review.
3. Productivity Apps with MCP (Obsidian, Notion, Todoist, Apple Notes)
This is the closest alternative. Obsidian has basic-memory MCP, Notion and Todoist have their own MCP servers. Claude can read and write to all of them. I actually use Obsidian + MCP daily for long-term project context.
Apple Notes has several well-built MCP servers too (sweetrb/apple-notes-mcp is the most complete, with 18+ tools including sync awareness and batch operations; RafalWilinski/mcp-apple-notes adds on-device semantic search with vector embeddings).
So Claude can write to these apps. The problem is not access, it is purpose mismatch:
- Permanent storage for ephemeral context: These are knowledge bases. Writing "check auth middleware before merging" to your Obsidian vault or Apple Notes creates noise you will have to clean up later. Session scratch does not belong in a permanent knowledge graph.
- Not glanceable: These are full apps you switch to with Cmd+Tab. Not a floating panel you glance at while typing in your terminal. That context switch, even a quick one, breaks flow.
- No session lifecycle: MCP lets Claude write to these apps, but there is no concept of "this note belongs to this coding session and should disappear when the session ends." You would need to manually organize and delete session notes.
4. Terminal Multiplexer (tmux pane)
Split your terminal. Dedicate a pane to a scratch file. There are even tmux MCP servers that let Claude send commands to other panes. But:
- Text, not UI: Claude can push text to a pane, but it is still a flat stream. No typed notes (note vs todo vs warning), no completion toggles, no visual hierarchy. You are reading raw text in a monospace grid.
- Same cognitive channel: Terminal output and scratch notes are both text in the same visual context. Your eyes have to distinguish "this is code output" from "this is a note I should remember." A floating panel in a different visual layer separates these naturally.
- No session lifecycle: The pane does not know when a Claude Code session starts or ends. Notes accumulate across sessions unless you manually clear them.
Full disclosure: I use Ghostty, not tmux. If tmux has capabilities that address these points better than I realize, I would love to hear about it in the comments.
5. Clipboard Managers
Tools like Maccy or Paste capture everything you copy. But they are reactive (you have to copy first) and have no concept of "this is important context from an AI session" vs "I copied a URL 20 minutes ago."
The Gap
The MCP ecosystem has solved the "Claude can not write to external apps" problem. Claude can write to Obsidian, Apple Notes, Notion, Todoist, tmux panes. Access is not the issue.
What is missing is a combination of three things no existing tool provides together:
- Session lifecycle: Notes that belong to a coding session and disappear when it ends. No cleanup, no permanent noise.
- Glanceability: A floating panel visible alongside your terminal at all times. Not behind a Cmd+Tab, not buried in a pane.
- Structure: Typed notes (note, todo, warning) with visual distinction, not a flat text stream.
Prior Art
mattt/iMCP is the closest architectural sibling to what I ended up building: a native macOS SwiftUI app paired with an MCP CLI server, built with the official MCP Swift SDK (which mattt co-created). iMCP bridges Calendar, Contacts, Messages, Reminders, and Weather to Claude. It uses Bonjour for discovery between the app and CLI processes.
Clause borrows from this pattern (native app + CLI MCP server, two-process model) but differs in scope and intent. iMCP is a general-purpose bridge to Apple's built-in apps. Clause is a single-purpose ephemeral scratchpad. iMCP stores nothing new; it reads and writes to existing Apple services. Clause creates its own transient state that lives and dies with a coding session.
Who Needs This?
Not everyone. If your Claude Code sessions are short (under 15 minutes) or focused on single-file edits, you probably do not need Clause.
But if you:
- Run long sessions (30+ minutes) where Claude makes multiple decisions and flags issues
- Work on complex refactors that span many files and accumulate warnings
- Use Claude Code as a pair programmer, not just a code generator
- Have found yourself scrolling back through terminal history looking for "that thing Claude said earlier"
- Want a shared workspace where both you and Claude can track session context
Then Clause solves a real problem.
In my workflow, the biggest win is warnings. Claude notices things: a dependency that is about to hit EOL, a pattern that does not match the rest of the codebase, a test that covers the happy path but not the error path. These observations used to vanish. Now they sit in a floating panel until I deal with them or the session ends.
What I Built
Clause is a minimal floating panel that sits alongside your terminal. Claude Code pushes notes, TODOs, and warnings to it in real time via MCP tools. You can add your own notes too. Everything disappears when the session ends.
It is not a full note-taking app. It is a scratchpad with a 1-session lifespan.
How It Works
Clause uses a two-process architecture:
- clause-mcp: A CLI binary that Claude Code spawns as an MCP server (stdio transport)
- Clause.app: A native macOS SwiftUI floating window
Both communicate over a Unix domain socket at ~/.clause/clause.sock. When Claude calls an MCP tool like add_note, the request flows through the socket to the app, and the note appears instantly in the floating panel.
Claude Code <--stdio--> clause-mcp <--unix socket--> Clause.app
Why Two Processes?
MCP servers communicate with Claude Code over stdio. A GUI app can not be a stdio server. So the MCP server is a headless CLI binary, and the GUI is a separate app. The Unix socket bridges them.
I considered alternatives:
- Named pipes: Unidirectional. I needed bidirectional communication for request/response patterns.
- XPC: Apple's IPC mechanism. Requires code signing and entitlements, which I wanted to avoid for an open-source tool.
- Network sockets (TCP/localhost): Works, but Unix domain sockets are faster for local IPC and do not expose a port.
The MCP Tools
Claude gets 6 tools to work with:
| Tool | What it does |
|---|---|
set_session |
Initialize session context (name, working directory) |
add_note |
Push a note, todo, or warning to the panel |
list_notes |
Read back current notes (useful for context) |
edit_note |
Update an existing note |
delete_note |
Remove a note |
clear_notes |
Wipe the session clean |
In practice, Claude uses add_note most. It naturally drops warnings and TODOs as it works. The list_notes tool is useful when Claude needs to recall what it flagged earlier in a long session.
Technical Decisions Worth Sharing
Swift 6 Strict Concurrency
The entire codebase uses Swift 6 strict concurrency. The socket server runs on a background thread, the UI updates on @MainActor, and all shared state goes through Sendable types. No data races, enforced at compile time.
POSIX Sockets for the Server Side
Here is something I did not expect: Apple's Network.framework (NWListener) does not support binding to Unix domain sockets as a server, or at least I could not find a way to make it work. I explored several approaches before landing on raw POSIX sockets (socket(), bind(), listen(), accept()) for the server side. The client side uses NWConnection, which does support Unix domain socket connections just fine.
If you have solved NWListener + Unix domain sockets on macOS, I would genuinely like to know how. If you are building IPC on macOS and hit this wall, POSIX sockets work reliably.
Debounced Persistence
Notes are kept in memory for speed. A debounced write serializes them to JSON every few seconds as a crash-safety measure. On restart, the app picks up where it left off.
Try It
Download
Grab the pre-built binaries from the GitHub Release:
-
Clause-app-macos-arm64.zip(the floating window app) -
clause-mcp-macos-arm64.zip(the MCP server binary)
Install
- Unzip both files
- Move
Clause.appto/Applications - Run
Clause.app(right-click > Open on first run, since the build is unsigned) - Add to your Claude Code config (
~/.claude.json):
{
"mcpServers": {
"clause": {
"command": "/Applications/Clause.app/Contents/MacOS/clause-mcp"
}
}
}
Or build from source:
git clone https://github.com/ceaksan/clause.git
cd clause
brew install xcodegen && xcodegen generate
open Clause.xcodeproj
What Is Next
- Global hotkey (Cmd+Shift+N) to capture clipboard as a note
- Multi-session tabs (each Claude Code session gets its own tab)
- Note search and filtering
- DMG and Homebrew cask distribution
Links
- GitHub: github.com/ceaksan/clause
- Landing page: clause.ceaksan.com
Clause is MIT licensed. If you use Claude Code daily, give it a try and let me know what you think.

Top comments (0)