Cursor
Apothem harness adapter for Cursor (GA).
Vendor: Anysphere
Install name: cursor
Status: GA
Native config: .cursor/rules/ in the project root
Installation
apothem install --harness cursor --project /path/to/projectThe adapter renders a single project-scope .mdc rules file from the shared
Apothem rules and governance surface, writes Apothem's helpers as Cursor
subagents in the project (see Subagents), and adds one hook to
the project's hooks.json (see Hooks).
It also writes Apothem's skills, and the rules and templates they cite, to your user home, before it touches the project (see Files outside the project).
Files written:
<project>/.cursor/rules/apothem-rules.mdc, the rules file.<project>/.cursor/agents/<name>.mdfor each Apothem helper, in the project.<project>/.cursor/hooks.json, with onesessionStartentry added to it. Your own entries and keys in it stay.<project>/.apothem/support/cursor/hooks/, the hook scripts, in the project.~/.agents/skills/<name>/SKILL.mdfor each Apothem skill and command, in your user home.~/.config/apothem/rules/and~/.config/apothem/templates/, in your user home.
The rules file summarizes the disciplines and names those folders, so the model can open a skill or a rule file when a task calls for it.
Files outside the project
The install also writes Apothem's skills to your user home, before it changes anything in the project:
| Folder | What Apothem writes there |
|---|---|
~/.agents/skills/ | One folder with a SKILL.md for each Apothem skill, and one for each Apothem command (a command becomes a skill of the same name). |
~/.config/apothem/rules/, ~/.config/apothem/templates/ | The rules and templates that the skills and the rules file refer to. |
These folders are shared. They are not private to the project:
- Every project you install
cursorinto, and every other Apothem install that names the folder, uses the same copy and writes the same files, so the order you install in does not matter. Several other tools read~/.agents/skills/too; the harness registry lists them. --projectchooses the rules file to write and which project the install belongs to. It does not change where the skills go.- The install adds no skill or rule file to your repository. The project
gets the rules file, the subagent files in
.cursor/agents/, the hook entry in.cursor/hooks.json, plus the.apothem/folder every project install creates, which also holds the hook scripts. - The home folders are written first. If that fails, for example because a folder in the path is a link that leaves your home directory (a link that stays inside it is followed) or cannot be written, the install stops with the error before anything in the project changes.
- A skill folder with an Apothem skill's name that Apothem did not write is
left alone, and the install prints a warning that names it. Rename or move
it, then run
apothem update.apothem verifyfails while that name is held. - The files add up to a few megabytes.
The install prints a note that names the folders it writes outside --project,
and --dry-run lists them.
Subagents
Cursor reads a subagent from a Markdown file in <project>/.cursor/agents/, per
the Cursor subagents documentation. The
install writes one file per Apothem helper into that folder. It installs for the
project only and writes no ~/.cursor/agents/ folder.
Each file keeps the helper's instructions unchanged and carries these frontmatter keys:
| Key | What Apothem writes |
|---|---|
name, description | The helper's name and description. |
readonly | true for five helpers: citation-auditor, convention-auditor, fact-checker, memory-auditor and research-scout. |
Cursor has no key that lists or denies tools: a subagent inherits every tool of
its parent. The one limit it can enforce is readonly: true, which allows no file
edits and no state-changing shell commands. So the helper's tools and
disallowedTools lines are not written, and the limit survives only as that flag:
- The five helpers above are read-only and have no
Bash, so they getreadonly: trueand keep the read-only wording in their descriptions. - Seven helpers are read-only but run commands (
codebase-explorer,dependency-auditor,design-critic,prompt-evaluator,quality-gate,security-scannerandtest-runner).readonly: truewould also stop their test and lint runs, so they get no flag, and their descriptions drop the read-only label that Cursor would not enforce. Only the description changes: the instructions are copied unchanged, so they still call the helper read-only and mention a tool restriction that a Cursor file does not have. The model follows that text, but Cursor does not enforce it, and the helper runs with every tool the parent has. mcp-builderandrefactor-surgeonwrite files and are unchanged.
The install writes no model key, so a helper runs on the model the parent uses,
and none of is_background, a turn limit, or Apothem's version, updated and
portability keys.
Things to know:
- The subagent files are ordinary project files. Commit them with the project or
list
.cursor/agents/in.gitignore; Apothem does not choose for you. - Cursor also loads helper folders written for other tools, among them
.claude/agents/in the project and~/.claude/agents/in your home directory (the harness registry lists the rest). On a name clash the project wins over the home folder and.cursor/wins over the others, so in a project with this install the native files supersede the Claude Code copies Cursor would import from~/.claude/agents/. Cursor's documentation does not say whether it loads both copies or drops the lower one, nor whether it applies thetoolsanddisallowedToolslines of a Claude Code file it imports. - A file of yours with an Apothem helper's name is saved under
~/.apothem/backups/and then replaced. The uninstall does not put it back. Files with other names are never touched. - Apothem has not confirmed whether Cursor reads the TOML files another tool writes
to the folders it imports, whether the Third-Party Imports setting turns those
imported folders off, or whether it reads extensions other than
.mdor nested folders in.cursor/agents/.
Hooks
Cursor runs hooks from hooks.json files, per the
Cursor hooks documentation. The install adds one
entry to <project>/.cursor/hooks.json:
| Event | What runs |
|---|---|
sessionStart | The session bootstrap: session metadata, the skill index, the memory and plan summaries and the standing posture, added to the conversation's initial context. |
The hook adds context for the model. It does not block anything, and Cursor does
not wait for a sessionStart hook.
This first version registers nothing else. Cursor's documentation lists
additional_context for postToolUse as well, and Apothem will register the
context-size counter there once a probe shows that the context reaches the model.
It registers no preToolUse guard: Cursor documents agent_message, the field a
guard would speak through, only for an action it denies, and Apothem's guards never
deny. The write, edit and shell guards, the AskUserQuestion check and the
session-end protocol stay on the tools that deliver them.
Where the files go
| File | What it holds |
|---|---|
<project>/.cursor/hooks.json | One sessionStart entry, merged into the file's hooks map. |
<project>/.apothem/support/cursor/hooks/ | The dispatcher script, its helpers and its message files. |
hooks.json is your file, and Cursor documents project hooks as checked into
version control. The install adds Apothem's entry after yours and leaves your
entries and other keys as they were; an update replaces only the entry whose
command runs the Apothem dispatcher (.apothem/support/cursor/hooks/dispatch.py
with --contract cursor, whichever project path it was written under), and an
uninstall removes only that entry. A hook of yours that only shares the name, such
as tools/hooks/dispatch.py in your project, or that runs python -m apothem.conformity.gate, is never taken for Apothem's. The uninstall deletes the
file when nothing else remains in it, after saving a copy under
~/.apothem/backups/. A file with comments, a trailing comma or a hooks value of the
wrong shape cannot be rewritten without losing something, so the install reports a
config.unparseable error for that file, leaves it untouched and stops, with the
other files it had begun to write removed again: fix the file, or add the entry
yourself.
The committed file names your machine. The entry's command holds the
interpreter Apothem found when it ran and the absolute path of the project, so
a teammate who checks out the file gets a command that points at your machine.
Cursor reports a command it cannot find as failed and the session goes on, so
nothing breaks, but the hook does nothing there. Commit the file only if your team
shares that layout. Cursor documents no uncommitted variant of the project hook
file. The .apothem/ folder is where the scripts live, and the project's
.gitignore snippet keeps it out of version control.
A command looks like this, with your interpreter and project path in place of the two paths:
"/path/to/python" "/path/to/project/.apothem/support/cursor/hooks/dispatch.py" --contract cursor sessionStartOn a Windows host the command starts with & , PowerShell's call operator, because
Cursor's desktop app runs hook commands through PowerShell, where a line that
starts with a quoted program path is not a call. sh reads a leading & as a
syntax error, so no other host gets it. The documentation names the shell and not
the quoting, so this is Apothem's reading of PowerShell's syntax.
--contract cursor reads Cursor's conversation_id and workspace_roots and
answers with {"additional_context": ...} and nothing else.
Paths the shell would misread. A project or interpreter path that contains
$, a backtick, a double quote or a backslash is refused before anything is
written: inside the quoted command it would run a different file, or break the
JSON the command is written into. The error names the path; move or rename the
project and run the install again. A space or an apostrophe in a path is fine.
Cursor also runs the hooks Claude Code wrote. Cursor loads the hooks in
~/.claude/settings.json, .claude/settings.json and .claude/settings.local.json
while "Include Third-Party Plugins, Skills, and Other Configs" is on (in Cursor
Settings, under Third-Party Imports), which is the default, and it runs every
matching hook from every source. If you also installed Apothem for Claude Code,
both sets of hooks can run. The sessionStart command here and the Claude Code
copy of it share one marker per session in Apothem's hook state folder, so
whichever runs second is silent and the bootstrap reaches the model once; Apothem
finds Cursor from the CURSOR_PROJECT_DIR and CURSOR_VERSION variables Cursor
sets for its hooks. The marker covers ten seconds, so a later start of the same
session, such as a second compaction, still delivers. The Claude Code copy's
context-size counter runs in addition, and Apothem does not de-duplicate the
counters. To run only the hook here, turn that setting off; it also
stops Cursor importing third-party plugins, skills and other configs. The install
prints this as a note.
Things to know. Cursor reloads hooks.json when it is saved, so a restart is
not needed. Project hooks run in trusted workspaces. Cursor's cloud runs a
repository's project hooks but defers sessionStart, so the entry does not fire
there. Set APOTHEM_HOOKS_DISABLE=1 in Cursor's environment to silence the Apothem
hook.
Profile-to-native-config mapping
The adapter reads Apothem's shared profile and renders the project rules file
on every apothem install or apothem update run. The shared profile is the
source of truth; project-local edits to the generated file are backed up before
the next sync replaces the Apothem-managed content.
The file opens with its YAML frontmatter (description, globs,
alwaysApply: true), because Cursor reads a rule's type only from frontmatter
at the start of the file. The Apothem-managed block follows it; text you add
after the block is kept on every sync.
Compatibility notes
Cursor 0.45+ supports project-level instructions via .cursor/rules/. The
adapter writes to the project-scoped .cursor/rules/ directory by default;
Cursor has no documented file-based user-global rules path for this adapter to
manage.
Cursor loads skills from ~/.agents/skills/, so the skills the install writes
appear in Cursor without further setup. Cursor also loads ~/.claude/skills/,
so on a machine that also has a Claude Code install it can list the same skill
names twice, and its documentation does not say which copy wins. Apothem has
not confirmed how Cursor treats a SKILL.md header key it does not list; the
skills carry user-invocable, disable-model-invocation, allowed-tools,
argument-hint, and a metadata map.
Verification
apothem verify --harness cursor --project /path/to/projectThe verify command confirms that:
- The native config exists at the expected path.
- Each managed target exists, the
.cursor/agents/folder and the hook file.cursor/hooks.jsonincluded; managed files are non-empty, and JSON or YAML configs parse. The hook file must hold an entry that runs the Apothem dispatcher (the check does not run it), so a file that was reverted or emptied no longer verifies. Add--profile PATHto also confirm that the installed files match that profile. For.cursor/agents/the check is that the folder exists, not that each helper file is in it;apothem diff --harness cursor --project /path/to/projectlists the helper files that are missing or out of date. - Every Apothem skill folder is in place with a
SKILL.md, whichever install wrote it, and no skill folder with an Apothem name belongs to something Apothem did not write. A failed check names the missing or foreign folders. - The adapter-specific verification routine reports success.
Updating
apothem update --harness cursor --project /path/to/projectRe-derives the project rules file from the current shared profile state.
The update also rewrites any skill folder whose files differ from the current ones.
If you installed with an earlier release that wrote no skills, the update adds them.
It rewrites subagent files that differ from the current ones, and adds any that are missing.
It also refreshes the hook scripts and the Apothem entry in .cursor/hooks.json,
leaving your own entries alone.
Uninstalling
apothem uninstall --harness cursor --project /path/to/projectRemoves the Apothem block, and the frontmatter Apothem wrote above it, from
<project>/.cursor/rules/apothem-rules.mdc and keeps any other text in it. The
file is deleted only when nothing else remains in it. Before the change, a
timestamped copy of the file is saved under ~/.apothem/backups/; no backup
file is left in the project. The shared profile YAML and Apothem engine are
unaffected.
The uninstall also removes the subagent files it wrote in <project>/.cursor/agents/
and keeps any other file there; the folder is removed when it is left empty.
It removes the Apothem entry from <project>/.cursor/hooks.json, recognising it by
the dispatcher path in its command, and keeps your own entries and keys. The file is
deleted only when nothing else remains in it. The hook scripts in
<project>/.apothem/support/cursor/hooks/ go too.
If a file has comments that the uninstall cannot read, it leaves that file as it
is and reports the entry as skipped, with the reason; remove the Apothem entry by
hand.
It removes the skill folders it wrote in ~/.agents/skills/ and the
rules and templates in ~/.config/apothem/, but only when no other Apothem
install still uses them. Another project, or another tool that shares the
folder, may. In that case the uninstall keeps the folders, prints which install
uses them, and the last uninstall removes them. Files you added to those
folders stay, and a folder left empty is removed. Each
folder is backed up under ~/.apothem/backups/ before it is removed.
Conformity gate
python -m apothem.conformity.gate --all .Troubleshooting
| Symptom | Fix |
|---|---|
| Config file not found | Re-run apothem install --harness cursor --project /path/to/project |
| Verification failed | Run apothem update --harness cursor --project /path/to/project, then verify again |
| Cursor lists none of the Apothem helpers | Run apothem diff --harness cursor --project /path/to/project. A pending line for the .cursor/agents folder means helper files are missing or out of date, so run apothem update --harness cursor --project /path/to/project. apothem verify is not a test of this: it passes when .cursor/agents/ exists, even with no helper file in it. If diff reports no pending changes, check that the project is open in Cursor and start a new chat |
| The Apothem hook does not run | Cursor runs project hooks in trusted workspaces only. Open the Hooks tab in Customize, or the Hooks output channel, to see whether the entry loaded and what it reported. A file written on another machine names that machine's interpreter, so Cursor reports the command as failed: run apothem update --harness cursor --project /path/to/project here |
An install reports config.unparseable for hooks.json | The file has comments, a trailing comma or a hooks value of the wrong shape. Fix the file and install again, or add the sessionStart entry yourself |
| The Apothem context appears twice | Cursor also runs the hooks the Claude Code install wrote. Turn off "Include Third-Party Plugins, Skills, and Other Configs" in Cursor Settings, under Third-Party Imports, to run only the hook in .cursor/hooks.json |
apothem verify names a missing skill folder | Run apothem install --harness cursor --project /path/to/project; it restores the folder |
| An install or update warns that it skipped a skill folder | A folder with an Apothem skill's name already exists in the skills folder and Apothem did not write it. Rename or move it, then run apothem update |
| An install stops before it changes the project | A write in your home failed. Read the error, fix the folder it names (a link that leaves your home directory, a file where a folder belongs, or a read-only folder), and install again |
| Unexpected config content | Check ~/.config/apothem/profile.yaml or --profile PATH, then re-run apothem update --harness cursor --project /path/to/project |
Configuration knobs
| Flag | Default | Description |
|---|---|---|
--dry-run | false | Preview install without writing files. |
See also
- All harnesses — the full catalog of supported tools
- Install guide — install Apothem into this harness
apothem harnessesreference — list and inspect adapters from the CLI