Skip to content

Add the Atlaso Memory plugin - #157

Open
imashishkh21 wants to merge 10 commits into
cursor:mainfrom
imashishkh21:add-atlaso-plugin
Open

Add the Atlaso Memory plugin#157
imashishkh21 wants to merge 10 commits into
cursor:mainfrom
imashishkh21:add-atlaso-plugin

Conversation

@imashishkh21

@imashishkh21 imashishkh21 commented Jul 15, 2026

Copy link
Copy Markdown

Add the Atlaso Memory plugin

Adds Atlaso (atlaso/) — automatic long-term memory for Cursor. It recalls what
you've decided and remembers what matters across sessions, projects, and tools, so the
agent starts each session with the relevant context instead of a blank slate.

Homepage: atlaso.ai · Source: atlaso-labs/cursor

What it adds

Component
Hooks sessionStart recalls relevant notes into a rules file; stop/sessionEnd capture the exchange. The automatic loop, zero model involvement.
MCP server (atlaso) 5 tools — recall, remember, forget, recent, status — for deliberate moves.
Rule (alwaysApply, with frontmatter) Orients the agent: treat recall as known context.
Skill Curation judgment — what's worth keeping, personal vs project.

Self-contained — no external binary

The MCP server is lib/mcp.ts, which ships inside the plugin and runs on the bun
Cursor already provides (bun run ${CURSOR_PLUGIN_ROOT}/lib/mcp.ts). There is no
unpublished CLI or npm package to install
— the whole plugin is self-contained and
works on a fresh machine. Rule has valid description + alwaysApply frontmatter; the
skill has name + description; rule and skill are distinct (orientation vs judgment).

Privacy (a memory plugin should be explicit here)

  • Secrets are scrubbed on the user's machine before anything is sent — API keys,
    tokens, and credentialed URLs are redacted client-side (regex + entropy), and again
    server-side.
  • Per-tool credentials. The plugin holds its own token, so removing it revokes only
    Cursor — nothing else on the machine.
  • Fails open. If memory is unreachable, Cursor works exactly as usual — capture and
    recall never block or break a turn.
  • Users own their data and can view/delete any memory at
    app.atlaso.ai/dashboard.

Validation

  • Passes node scripts/validate-plugins.mjs (marketplace + plugin manifests).
  • The plugin is covered by 100+ unit tests plus an offline end-to-end harness in the
    source repo.

Maintained by Atlaso Labs (we ship the same memory for Claude Code, Codex, and
Antigravity). Happy to make any changes the team would like. Contact: [email protected]


Note

Medium Risk
New third-party plugin that sends scrubbed chat content and bearer tokens to an external service on every session/turn; large new surface (hooks + MCP + auth) though designed fail-open and with client-side redaction.

Overview
Adds the Atlaso Memory plugin (atlaso/) to the official marketplace and ships a self-contained bun connector (no extra install) that syncs with Atlaso’s cloud brain.

Automatic loop (hooks): sessionStart writes recalled notes to .cursor/rules/atlaso-recall.mdc; beforeSubmitPrompt / afterAgentResponse stash the turn; stop / sessionEnd gate, scrub secrets, scope personal vs project, enqueue durably, then deposit. First run can spawn a detached PKCE device browser connect. Hooks always exit 0 and skip when unlinked.

Deliberate control: Inline stdio MCP (recall, remember, forget, recent, status) reuses the same per-tool credential and entitlement checks as hooks.

Supporting behavior: Per-tool tokens minted under lock (with a Windows O_EXCL fallback), write-ahead outbox + drain retries, cached cloud entitlement (free = one active tool), tri-state project keys and cross-project recall filtering, plus an alwaysApply rule and memory curation skill.

Reviewed by Cursor Bugbot for commit 96fb8ff. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread atlaso/lib/atlaso.ts
Comment thread atlaso/lib/mcp.ts Outdated
Comment thread atlaso/lib/connect.ts
Comment thread atlaso/lib/credential.ts
Comment thread atlaso/lib/connect.ts
Comment thread atlaso/lib/mcp.ts
Comment thread atlaso/lib/pending.ts
Comment thread atlaso/hooks/capture.ts Outdated
Comment thread atlaso/lib/connect.ts
Comment thread atlaso/hooks/hooks.json
Comment thread atlaso/hooks/capture.ts Outdated
Comment thread atlaso/hooks/capture.ts
Comment thread atlaso/hooks/capture.ts Outdated
Comment thread atlaso/hooks/capture.ts Outdated
Ashish Khandelwal and others added 7 commits August 2, 2026 16:30
Automatic long-term memory for Cursor: recall + capture hooks, the self-contained
atlaso MCP server (recall/remember/forget/recent/status), a usage rule, and a
curation skill. Client-side secret scrub, per-tool credentials, fails open.
Passes scripts/validate-plugins.mjs.
…ndows revoke

This branch had drifted from the connector's home in our monorepo: it carried the
Bugbot fixes, the monorepo carried later work, and neither was a superset. The
monorepo is now the single source of truth and this directory is generated from it,
so the two cannot diverge again.

Two behaviour changes ride along:

DURABLE OUTBOX (lib/outbox.ts, lib/drain.ts). Capture was online-first: it POSTed a
memory once and, on any failure — timeout, 5xx, 429, a dropped connection — logged
saved=false and moved on, losing the memory with nothing on disk. Memories are now
written ahead of the network call and retried by later hook runs, so a process
killed inside fetch has already recorded them. One file per item, tmp+fsync+rename;
the filename is a hash of client_id, which is already the server's idempotency key,
so a retry after an ambiguous timeout cannot create a duplicate. Nothing is ever
deleted: items that exhaust their retries, age out, or exceed the queue bound are
quarantined with a reason rather than dropped.

WINDOWS REVOKE (lib/lock.ts) — the outstanding Bugbot finding, "Lock miss skips
tool revoke". withToolLock yielded held:false wherever flock(2) is unavailable,
which is always on Windows, so resolveCredential returned the shared bearer without
ever calling /v1/device/exchange. The tool never minted its own credential and
never observed tool_revoked: removing the plugin on Windows did not stop it
syncing. Calling exchange unlocked would have been wrong — the server rotates the
credential on every call, so an un-persisted mint per hook run churns tokens
forever. Windows now gets an O_EXCL lockfile instead, held only across one exchange
with a 60s stale threshold; a concurrent mint leaves the loser holding a
rotated-away token that 401s and re-mints, which is self-healing rather than
corrupting. The flock path on macOS/Linux is untouched and uses a separate file.

Also brought forward from the monorepo: tri-state project attribution, so a capture
we cannot attribute is marked with provenance instead of being filed under a junk
project key, and a scrub of the recall QUERY so a pasted secret cannot escape
through the read path.

marketplace.json rebased onto main — upstream's Google Workspace entries and this
one both appended to the same array.

Verified: scripts/validate-plugins.mjs passes; every hook and the MCP server build
under bun. The full test suite for this code lives in the monorepo and is green
(169 tests) with typechecking clean.
Comment thread atlaso/lib/entitlement.ts
Comment thread atlaso/lib/mcp.ts Outdated
Comment thread atlaso/hooks/recall.ts
Comment thread atlaso/lib/atlaso.ts
- remember() no longer refuses to save when the project cannot be identified. The
  MCP server has no hook payload and an arbitrary cwd, so the project key is often
  null and a deliberate save was failing on the user's highest-intent memory. It is
  now stored and tagged project-unknown, which the server already treats as
  visible-with-provenance — the same fail-open rule automatic capture uses.
- remember() derives its idempotency key from the scrubbed content and tags instead
  of a random UUID, so a timeout after the server committed no longer duplicates the
  memory on retry.
- The sessionStart recall fallback over-fetches before applying the client-side
  project filter. /v1/memories is global newest-first, so requesting exactly LIMIT
  could return nothing right after switching projects.
- online()/cloudMode() take named arguments, so a swapped tool/deviceId can no
  longer typecheck and silently scope the entitlement verdict to the wrong identity.

Verified: validate-plugins.mjs passes and every entrypoint builds. Upstream tests
are green at 171 with typechecking clean.
Comment thread atlaso/hooks/recall.ts
Comment thread atlaso/lib/mcp.ts
…emember

- The sessionStart recall hook filtered results on tags alone while the MCP path
  also honoured a top-level scope field. Some server versions normalize scope out
  of tags, so a row carrying a project key but expressing scope in the field read
  as personal and could reach another project's rules file — and the previous
  commit's larger fetch window enlarged that. The predicate now lives once in
  project.ts and both paths call it.
- remember() no longer treats every unresolved project as unknown. A genuinely
  non-project root is personal scope; only a garbage measurement stays
  project-scoped and unattributed, matching automatic capture.

validate-plugins.mjs passes, every entrypoint builds, upstream tests green at 177.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

Reviewed by Cursor Bugbot for commit d7e9a26. Configure here.

Comment thread atlaso/lib/mcp.ts
The previous commit downgraded a `none` project resolution to personal scope, but
root discovery falls back to cwd when the editor exports no workspace variables,
and for an MCP server that cwd is frequently $HOME — which resolves to `none`. A
deliberately project-specific remember could therefore be saved as personal and
follow the user into every other repository.

`none` is the one status that makes a memory global forever, so it may now only
come from a root the editor actually supplied; a missing workspace reports
`unknown`, matching automatic capture. The project KEY keeps its cwd fallback,
because a key that resolves is self-validating while the absence of one is not.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant