Agent skill

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.

Give it to an agent

A personal skill — every Claude Code session picks it up.

terminal
mkdir -p ~/.claude/skills/agentstuff && curl -fsSL https://agentstuff.me/skill.md -o ~/.claude/skills/agentstuff/SKILL.md
/skill.mdThe agent also needs the MCP server — connect it here.

What the agent reads

agentstuff/SKILL.md

agentstuff

agentstuff 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.

The loop

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.

  • A decision and why → remember(...), tag it decision.
  • A gotcha that cost time (wrong flag, silent failure, non-obvious fix) → remember(...) with the fix and, if it's in code, a code_refs pointer.
  • Work that will outlive this session (a feature, a migration, a goal with steps) → plan it in a build (build_start), then work it; the next session — or the next agent — picks it up where you left off. See below.
  • A procedure you'd repeat (release, setup, review) → remember(..., kind="skill", title="verb-noun"), written as numbered steps another agent can follow.
  • Something you got working that's worth doing again (a model running, an agent wired up, a tricky install) → 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).

Always

  • Set source on everything you write — your name, e.g. "claude-code", "codex", "cursor". The person sees who wrote what.
  • Never clobber. 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.
  • Titles are for scanning. Short, specific, no dates: "Cloud Run over Kubernetes", not "Note from Tuesday".

Tools

Memory

  • 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.

Folders — memory as a tree

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.

Projects and builds — plan it whole, then full send

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.

  • Plan the whole thing first. 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.
  • Then execute like it's yours — not one step per turn. The plan is a map, not a queue. Take on as much as you can hold: a whole milestone, several milestones, the whole build. Independent work runs in parallel — sub-agents, or several tasks at once. Milestones group and order the work; they are not gates, and nothing waits for the previous one to close.
  • Tracking follows the work, it never paces it. Mark what you're taking in one call — 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.
  • The check is the claim. A task is done when the command that proves it ran and passed. A failed check leaves it open with the failure shown.
  • Review, then iterate. After a sweep, look back over what you did against the plan: what's proven, what's weak, what you missed. Update the plan to match reality — add the tasks you discovered (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.
  • Don't stop to ask what you can decide. Ask with 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}.

Playbooks — how it was done, with the snippet that works

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.

Working with another agent

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.

Your own tools

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).

Connect

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.

Examples

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")