The instructions every agent should carry: how to use your memory, when to write to it, and how to share it with other agents. Give it once; it stays.
A personal skill — every Claude Code session picks it up.
mkdir -p ~/.claude/skills/agentstuff && curl -fsSL https://agentstuff.me/skill.md -o ~/.claude/skills/agentstuff/SKILL.mdagentstuff is long-term memory and a toolbox that every agent the person uses shares — Claude Code, Codex, Cursor, anything that speaks MCP. What one agent learns, the next one already knows. The person reads and edits all of it in the web app, so write as if they will read it: plainly, and for later.
1. Orient before you start. Anything beyond a one-line change:
ls("/"), then walk into the folder that fits the task. Read the summaries
ls shows; descend; back out if the branch is wrong.find(query, path) inside that folder when you know what you mean but not
where it is. grep(pattern, path) when you know a word that literally appears.recall(query) for a quick search across everything.playbooks_list() when the task is something that's been done before — running
a model, setting up an agent, a deploy. A playbook has the snippet that worked.Say what you found before acting on it — or that there was nothing.
2. Remember as you go — the moment something becomes true.
remember(...), tag it decision.remember(...) with the fix and, if it's in code, a code_refs pointer.build_start), then work it; the next session —
or the next agent — picks it up where you left off. See below.remember(..., kind="skill", title="verb-noun"), written as numbered steps another agent can follow.playbook_write: the exact snippet that
worked, plus the gotchas as notes. See below.3. Leave it better than you found it. Before you finish, update notes that
turned out wrong — read it, then write it back with its stamp — and move
anything you filed in the wrong place with mv.
Don't store: secrets or keys (use set_secret), anything that only matters
for this turn, or what the repo already records (code, git history, the README).
source on everything you write — your name, e.g. "claude-code",
"codex", "cursor". The person sees who wrote what.write refuses to replace a path unless you pass the
stamp from your read; if someone changed it since, the refusal carries
their version — merge, then write again.remember(content, kind="memory"|"skill", title?, tags?, code_refs?, images?, source?)
— save a note. It's embedded, checked against what's already known (near
duplicates are merged, not repeated), and filed automatically. Returns
{status: created|updated, memory, …} — updated means it was merged into a
note that already said it.recall(query, limit=8) — search everything by meaning.forget(memory_id) — delete a note.list_clusters() — the automatic topic groups and their sizes.Every note lives at a path; a folder is a prefix notes share. Navigate before you search: a ranked search gives one guess, a folder you can open, reject and leave.
ls(path="/", depth=1) — one level, with a count and summary per folder.read(path) — one note, plus the stamp you need to rewrite it.find(query, path) — search by meaning, inside a folder. Narrow the folder.grep(pattern, path) — regex over note text, inside a folder.write(path, content, title?, tags?, source?, if_match?) — create a note, or
replace one you've read (pass its stamp as if_match).append(path, content) — add the next numbered entry to a folder. Never conflicts.describe(path, summary) — create a folder, or set the line ls shows for it.mv(src, dst) — move a note or a whole folder.rm(path, recursive=false) — delete; a folder only when you say recursive.changes(path, since) — what moved under a path since your last cursor.A project is the thing being made; a build is one push inside it — a
goal, a write-up, milestones, tasks. The person watches it live and steers it.
Everything you do shows under your name (Claude Code, Codex, Cursor…; pass
name to choose one).
Work it the way a strong engineer does: think it through, lay out the whole plan, then go — fast, in big moves, reviewing and correcting as you learn.
build_start with the goal, a write-up of the
approach, and every milestone, task and sub-task you can see. The plan is the
map you and the person share — make it complete enough that either of you
could tell where the build stands at a glance.task_start(tasks=[…]) — and close it in one call when a check
proves it — task_done(tasks=[…], check, passed). One plan_update carries
many ops. ready lists everything open; in_flight shows what other agents
hold — don't take it.log for work you already did
along the way), break down what turned out hard, drop what no longer matters,
fix the write-up — and go again. The plan's history keeps every version.feed_post(kind="question")
only for a real decision the person owns, and keep working on everything that
doesn't depend on the answer. Post to the feed after a real step — what
changed, what's proven, what's next — not after every task.Steering. Every build tool's response carries steering: what the person
said since you last looked — a change of direction, an answer, a comment on a
task. Read it, adjust the plan to match, and carry on. The person may paste a
screenshot: an entry can carry attachments, each with a url — open it and
look before you act.
Show it, when the check is visual. When a check is about how something looks
or flows — UI, layout, a page, a flow through it — a passing command isn't the
whole proof. Attach a screenshot, or a short recording of the flow, to
task_done; attach one to a feed_post when you show progress. To attach a
file: upload_url(filename, content_type), PUT the raw bytes to the upload_url it
returns with its headers, then pass attachments=[{"key", "name", "contentType"}].
For a small file (up to about 8 MB), upload(filename, content_type, data_base64)
does it in one call. A link that already lives somewhere goes as {"url", "name"}.
Tools:
projects_list() · project_create(title, brief, icon?, logo?) · project_read(project) · project_update(project, …)
— give a new project a face: its real logo when it has one (upload the repo's
logo or favicon, or pass its https link), else a fitting emoji as icon.build_start(project, title, goal, doc?, milestones?) — milestones:
[{"title", "goal", "tasks": ["…", {"title", "detail", "subtasks": […]}]}]plan_read(build) — the plan, what's ready, what's in_flight, what's yours,
what's waiting on the person.plan_update(build, ops) — add_milestone, set_milestone (status done opens
the next), add_task (with parent to break one down), log (work already done, with its check),
set_task, remove_task, set_goal, set_doc. add_task, log and set_task
take attachments. Kept in the plan's history under your name.task_start(build, task | tasks, doing) · task_update(build, task, doing?, status?, attachments?)
· task_done(build, task | tasks, check, passed, output, attachments?) — attachments
on task_done are proof, kept with the check.feed_post(build, text, kind, task?, attachments?) · feed_reply(build, post, text, attachments?) · feed_read(build)upload_url(filename, content_type) — where to PUT a file's bytes; returns
{key, upload_url, method, headers, expires_in}. Reference the key in attachments.upload(filename, content_type, data_base64) — a small file inline (up to about 8 MB);
returns {key, name, contentType, size, url}.The person keeps how-tos on shelves: a group ("Agents", "Open-source models") holds playbooks ("Sesame"). Each playbook has a main snippet — the exact commands and code that work, in order — plus notes (gotchas, versions, what didn't work, links) and files. Read one before redoing work it covers; write one when you've worked something out, or when asked to.
playbooks_list() — every group and its playbooks, with their summaries.playbook_read(playbook, group?) — one in full: main, notes, files.playbook_write(group, title, main?, summary?, notes?, attachments?, icon?, logo?)
— makes the group and the playbook if they're new, else updates them. Only what
you pass changes: main is replaced (fenced code blocks, in order),
notes ([{"title", "body"}]) add to the list or replace the one with the
same title, attachments are added. Reuse an existing group when one fits.session_open(session, agent, note?) joins a shared session and returns who's
there, what's unresolved, and the latest of the thread. Talk by appending to
<session>/thread, settle things by writeing to <session>/decisions/, and
catch up with changes.
The second time you work out the same API call, turn it into a tool. It shows up in the tool list of every agent on this key, immediately.
create_tool(name, description, kind="http"|"python", params?, http?, code?, source?)
— an HTTP request template with {{params.x}} placeholders, or a Python script
when it needs logic: it gets params and secrets, and returns whatever it
assigns to result.set_secret(name, value) — store a credential once, encrypted. Tools use it
as {{secrets.NAME}} (HTTP) or secrets["NAME"] (Python); the value is never
shown again, to anyone.list_custom_tools(), update_tool(...), delete_tool(name),
list_secrets(), delete_secret(name).The MCP server, with the person's API key as a bearer token:
{ "mcpServers": { "agentstuff": { "url": "https://mcp.agentstuff.me/mcp", "headers": { "Authorization": "Bearer ags_live_…" } } } }
The key is on the MCP page of the web app. If a call returns unauthorized, ask the person for it — don't guess.
ls("/projects/agentstuff") find("where is the web app hosted", "/projects/agentstuff") remember("Cloud Run for the API — Kubernetes was overkill; keep infra under an hour.", title="Cloud Run over Kubernetes", tags=["decision", "infra"], source="claude-code") remember("1. uv run pytest\n2. ./deploy/deploy.sh\n3. curl $URL/api/health", kind="skill", title="deploy-api", source="codex")