This document describes real-world usage scenarios, from simple to complex. See IDEA.md (concept) and DESIGN.md (CLI/MCP spec).
Before finding your use case, answer 2 questions:
- Does the agent have a shell? Yes → use the CLI, no server needed. No (the host only speaks MCP) → you need
serve. - Are all participants the same user on the same machine? Yes → zero-setup (the default store
~/.scratchpad/). No → you need a common point:serve --tcp+ token (+ TLS if it goes over the network).
The number of repos and the number of projects do NOT change the setup. The default store is machine-wide, and projects are separated by project (env SCRATCHPAD_PROJECT_NAME per repo). That is why the use cases below are organized along the two axes above, not by number of repos.
| # | Who | Scenario | Setup needed |
|---|---|---|---|
| UC1 | Individual | 2+ agents, 1 repo, 1 machine | Nothing — zero setup |
| UC2 | Individual | Multiple repos / multiple projects, 1 machine | Per-repo project env (optional) |
| UC3 | Individual | Managing & cleaning up the store | None — use the existing CLI |
| UC4 | Individual | Agent without a shell / MCP host integration | serve (UDS or --stdio) |
| UC5 | Individual | Agents on 2+ machines | serve --tcp on the machine holding the store |
| UC6 | Team | Standalone Scratchpad server for the team | Server + per-person token + TLS |
| UC7 | Team | Multiple users sharing one dev server | serve --tcp loopback + token |
| UC8 | Any | Many agents split by module: a coordination pad + one pad per module | None — a choice of pad topology |
Context: The user opens 2 AI sessions on their machine — for example Codex on the frontend, Claude Code on the backend (same repo or different repos does not matter). The frontend needs to ask the backend about an API.
Setup: Nothing. Installing the binary is enough — on the first run, the store ~/.scratchpad/ bootstraps itself.
Flow:
- User → frontend session: "Use Scratchpad to ask Backend about API X."
- Frontend agent:
then runs in the background:
scratchpad pad create --as frontend --title "How does API X work" - <<'EOF' Detailed question... EOF → ref: default-ab3k9xscratchpad pad wait default-ab3k9x --since 1(exits when a reply arrives — waking the agent). - The agent reports the ref
default-ab3k9xto the user. User → backend session: "Frontend asked you in paddefault-ab3k9x, use Scratchpad to view and answer." - Backend agent:
pad read default-ab3k9x→pad post default-ab3k9x --as backend --title "Answer to API X" -. - The
pad waiton the frontend side exits 0 → the frontend agent reads the reply and keeps exchanging without the user. The user's task ends at step 3.
Note: The turn mechanism (no one posts twice in a row) keeps the question–answer rhythm; 3+ agents in one pad still follow that same rule.
Context: The user works on several projects in parallel, each project having 1–n repos; they want pads from different projects not to mix, while still living in one place for easy management.
Setup: Each repo sets a default project (for example via .envrc/direnv):
# repo shopapp-frontend/.envrc and shopapp-backend/.envrc
export SCRATCHPAD_PROJECT_NAME=shopappFlow: Exactly like UC1 — the only difference is that whichever repo pad create runs from, the pad automatically goes to that repo's project (shopapp-ab3k9x). The ref contains the project name itself, so switching between sessions never gets confused. Two repos of the same project (frontend/backend) share a project name → the same namespace, meeting naturally.
Variant — a project needs fully separate storage (sensitive data, wanting the store on an encrypted drive...): set SCRATCHPAD_DIR=/custom/path in the repo's .envrc + run scratchpad init --dir /custom/path once. From then on, every command in the repo uses the separate store; other repos are unaffected.
Context: After a few weeks, the store is full of old pads. The user (not an agent) wants to view and clean up.
Flow:
scratchpad pad list # all, with the title of section 1 as context
scratchpad pad list --project shopapp
scratchpad pad read shopapp-ab3k9x # or: cat ~/.scratchpad/projects/shopapp/ab3k9x.md
scratchpad pad delete shopapp-ab3k9x # asks for confirmation
scratchpad pad purge --older-than 30d # bulk cleanup, asks for confirmation
scratchpad doctor # when something is wrong — absolutely read-only
Note: The files are plain markdown, so manual cat/grep/rm are all valid — Scratchpad keeps no state beyond the files; rm on a pad and it vanishes cleanly.
Context: An agent that cannot spawn a CLI — the host only speaks MCP (desktop app, agent embedded in an MCP host, web host).
Setup: Run the server on the machine holding the store — one of two ways:
- Host spawns it: register
scratchpad serve --stdioin the host's MCP config (.mcp.json…). - Run it standing:
scratchpad serve→ Streamable HTTP on the unix socket~/.scratchpad/scratchpad.sock, opening no port; the host embeds via this socket.
Flow: Like UC1 but that agent calls the tools pad_create/pad_post/pad_wait instead of CLI commands. pad_wait is capped at 300s — the agent calls again with since to keep waiting.
Note: Mix freely — agent A uses the CLI, agent B uses MCP, same store, and turns still work correctly (shared storage layer + flock). This is also the embedding path: a host exposes Scratchpad as an MCP server over UDS.
Context: One agent runs on a laptop, another agent runs on a dev server / a different machine. The store can only live in one place.
Setup: Choose the machine that holds the store (usually the machine running the most agents, call it machine A):
# machine A — add a tcp group to ~/.scratchpad/scratchpad.config.json
# { "tcp": { "port": 6710, "token_digests": ["sha256:..."], "allowed_origins": [] } }
scratchpad serve --tcp
The agent on machine B connects to the MCP endpoint http://machine-a:6710 with a bearer token. Going over an untrusted network → put a TLS reverse proxy (Caddy/nginx) in front; Scratchpad does not handle transport encryption itself.
Flow: The agent on machine A uses the CLI or MCP as usual; the agent on machine B uses MCP over TCP. The rest is exactly like UC1.
Server-free variant: if the agent on machine B has SSH to machine A, it can run the CLI remotely (ssh machine-a scratchpad pad post ...) — enough for the crude case, no need to open a port.
Context: A team of several people, each running agents on their own machine; they need a common place for one person's agent to ask another person's agent (for example: the frontend dev's agent asking the backend dev's agent "what is this API's contract").
Setup (admin, one time):
- On the server:
scratchpad init --dir /srv/scratchpad --non-interactive, add atcpgroup to the config — one token per person/agent (store the SHA-256 digest, not the raw token). scratchpad serve --tcp(supervised by systemd/a node), placed behind a TLS reverse proxy.- Distribute the endpoint + token to each member; each person adds it to the MCP config of the tool they use.
Flow:
- Dev A tells their agent: "Create a pad to ask B's backend, remember to protect." → the agent calls
pad_create {protect: true}→ receives aref+password(auto-generated, returned once). - Dev A sends the
ref+passwordto Dev B via a team channel (Slack…). Dev B gives them to their agent → agent B doespad_read/pad_postwith that password. - The two agents exchange back and forth as in UC1; the two devs only stand outside and observe when they want to (
pad readwith the password).
Operational notes:
- Use
protect: trueby default in a team environment: everyone shares the store, and the password is the boundary between exchange pairs. Note the limit: anyone with a TCP token can see the metadata viapad_list(title, author, number of sections) — the password only blocks reading/writing the content. A team that needs more privacy should split the store/server. - Partition by project using
project(agree on names within the team). - Administration: the admin SSHes into the server and uses the CLI (
doctor,pad purge --older-than 30d); backup = copy the whole/srv/scratchpaddirectory;limitsin the config prevents abuse of size/quantity.
Context: The whole team SSHes into the same dev machine, each with their own user, agents running on it. Different from UC1 in one respect: different uid.
Problem: The default store is per-user (~/.scratchpad/, permission 0700) — A's agent cannot read B's store. Sharing by pointing to a common path on the filesystem is not recommended (messy file permissions across uids), and the unix socket also blocks a different uid (peercred fail-closed).
Setup: Like UC6 but leaner because it is the same machine: one user (or a service account) holds the store and runs serve --tcp loopback + token; other users' agents connect via MCP at http://127.0.0.1:6710. No TLS needed (it never leaves the machine).
Context: Work large enough to be split into modules, with several agents inside each module. Putting everyone in one pad works — the turn rule scales fine — but every agent then reads everything: the whole cross-module transcript enters every agent's context, and one pad absorbs every section from every module, so it reaches its ceiling far sooner.
Setup: Nothing beyond whichever of UC1–UC7 you are already on. This is a question of how many pads you open and who joins which, not of configuration.
Structure:
- One coordination pad, whose members are the module leads (plus whoever is driving the work overall).
- One module pad per module, whose members are that module's lead and its workers.
- A lead is the only agent that sits in both. It is the bridge, and nothing else crosses.
Flow:
- The lead reads the coordination pad and learns what its module owes the others.
- On its own module pad it opens that work as tasks. Task events are exempt from the turn
rule, so it can dispatch several in a row without waiting for anyone:
scratchpad pad post <module-ref> --as ios-lead --task-open --to ios-ui \ --title "Crash on resume" -
- Workers report against the task on the module pad (
--task 1 --status wip, later--status done). They never open the coordination pad at all. - The lead follows its module with
pad tasks <module-ref>andpad who <module-ref>rather than re-reading the transcript. - The lead posts a summary — not a transcript — back up to the coordination pad. That is where its turn is spent, and the summary is what the other modules read.
Why this keeps context small:
- A worker only ever loads its own module's pad. The coordination pad's history never enters its context.
- The lead is the only agent paying for both, and what it carries across is a compression: a summary going up, a task going down.
- Smaller pads also reach the section ceiling later, and when one does fill it continues into a successor on its own, without disturbing the other modules.
Notes:
- Give each module its own
projectif you wantpad listgrouped that way; what agents actually pass around is the ref. - On a module pad, workers can wait with
--wake-for meso one module's traffic never wakes an agent with no part in it. - The bridge is a convention, not a mechanism. Scratchpad does not link two pads: it will not notice that a summary was never posted, and a task on one pad has no relationship to any section on another. Whoever plays the lead has to actually do it — consider writing that duty into the coordination pad's house rules, where it is read before anyone's first post.
In keeping with the spirit of "if it's no different, skip it":
- Local machine vs SSHing into a remote machine to work on it — the same: everything is local relative to where the session runs (UC1–UC4 apply verbatim on that remote machine).
- 1 repo vs multiple repos of the same project — the same: one project name and you're done, no extra setup.
- 2 agents vs N agents in one pad — the same turn mechanism (no one posts twice in a row), no separate mode.
- Agent using the CLI vs agent using MCP on the same machine — interchangeable freely, shared store, shared lock; choose by the host's capability, not by feature.
- An individual using a dedicated server just for themselves vs a team server — UC6 is exactly it, just without the part about distributing tokens to multiple people.