Add the Atlaso Memory plugin - #157
Open
imashishkh21 wants to merge 10 commits into
Open
Conversation
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.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
…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.
imashishkh21
force-pushed
the
add-atlaso-plugin
branch
from
August 2, 2026 11:01
825966c to
0897b4b
Compare
- 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.
…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.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Add the Atlaso Memory plugin
Adds Atlaso (
atlaso/) — automatic long-term memory for Cursor. It recalls whatyou'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
sessionStartrecalls relevant notes into a rules file;stop/sessionEndcapture the exchange. The automatic loop, zero model involvement.atlaso)recall,remember,forget,recent,status— for deliberate moves.alwaysApply, with frontmatter)Self-contained — no external binary
The MCP server is
lib/mcp.ts, which ships inside the plugin and runs on thebunCursor already provides (
bun run ${CURSOR_PLUGIN_ROOT}/lib/mcp.ts). There is nounpublished CLI or npm package to install — the whole plugin is self-contained and
works on a fresh machine. Rule has valid
description+alwaysApplyfrontmatter; theskill has
name+description; rule and skill are distinct (orientation vs judgment).Privacy (a memory plugin should be explicit here)
tokens, and credentialed URLs are redacted client-side (regex + entropy), and again
server-side.
Cursor — nothing else on the machine.
recall never block or break a turn.
app.atlaso.ai/dashboard.
Validation
node scripts/validate-plugins.mjs(marketplace + plugin manifests).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):
sessionStartwrites recalled notes to.cursor/rules/atlaso-recall.mdc;beforeSubmitPrompt/afterAgentResponsestash the turn;stop/sessionEndgate, 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
alwaysApplyrule and memory curation skill.Reviewed by Cursor Bugbot for commit 96fb8ff. Bugbot is set up for automated code reviews on this repo. Configure here.