agent-julia
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Agent Julia
One AI that knows you, in every Claude you use.
You build the persona once: what it is called, which language it answers in, how it writes and what it must never store. From then on you talk to it by name in Claude Code, Claude Desktop, claude.ai, the Claude app on your phone and on your other computers, and it is the same one everywhere. It remembers what you decided and writes the way you taught it. Everything it knows is plain markdown in a git repo you own.
npx agent-julia initWhat it looks like
The phone and claude.ai reach your memory through server mode.
Related MCP server: LLM Memory MCP Server
Why it helps
You keep re-teaching the same preferences. You told Claude Code to skip the "Great question!" preamble and to answer in Polish. Tomorrow, in Claude Desktop, the preamble is back and the answer comes in English. With Agent Julia you say it once, and every app reads the same correction from the next turn on.
Your CLAUDE.md has grown to 500 lines. All of it loads on every turn of every session, and the answers get worse as the window fills with things the task at hand does not need. Agent Julia keeps a persona core of about 1,200 tokens in context and leaves the rest in memory, where the agent finds the one page it needs when you ask.
Where it works
How it connects | |
Claude Code | registered by the wizard; the persona is in every session from the first message |
Claude Desktop (Cowork) | registered by the wizard; you paste one short block into its settings once |
claude.ai | a custom connector to your server, approved with your own password |
The Claude app on your phone | the same connector: add it on the web and it is there |
Your other computers |
|
A team or a household | a shared store mounted next to your own memory |
Codex, Gemini CLI | the persona exported into their instruction file and kept current |
Highlights
A persona you call by name. The wizard asks what it is called, then its pronouns, its language and how it writes. You open with "Julia, look at this" as you would with a colleague, and Julia is the one who answers.
A voice you shape by talking. "Stop hedging." "Don't open with my name." Say it once, in passing, and it holds in every app. Take it back the same way.
It catches what you forget to save. Ask it to remember and it does. With capture hooks on, a background pass after a Claude Code session also saves the decisions and corrections nobody asked it to keep.
Yours, in plain files. Markdown in a git repo you control: open it, edit it by hand,
git logit, take it elsewhere. The search index is built from those files and rebuilds itself if you delete it.Light on context. About 1,200 tokens of persona ride each turn. Everything else waits in memory until a question needs it.
Search that gets your meaning. Keyword search with stemming and accent folding is always on. Add the optional multilingual model, which runs on your machine, and a question in Polish finds a note you wrote in English.
Private where it counts. You decide what it must never store, starting from passwords, keys, card numbers and other people's private details, and that rule rides every message. The server listens only on your own machine until you turn on authentication, and claude.ai gets in only after you type the owner password.
Install
npx agent-julia initRequires Node.js 24+ (it uses the built-in node:sqlite — no native module to compile or rebuild). There's no separate install step: npx fetches agent-julia into its own cache and runs the wizard in one go, and the MCP server launches the same way (npx -y agent-julia@latest serve), so it stays current. Prefer it installed permanently? npm i -g agent-julia.
Choosing the local model for search changes how the server is launched. npx runs from a cache that cannot load the optional model package, so the wizard registers an installed copy instead (npm i -g agent-julia @huggingface/transformers), after checking that it can load the model. Node is registered by a path that survives upgrades: on Homebrew that is opt/node, not the versioned Cellar directory the next brew upgrade deletes. If the registered program ever disappears, agent-julia doctor says so.
The wizard starts with the name you will be calling it by, then pronouns, language, and voice; where your memory lives and whether to version it with git; search; and which Claude apps to register. It either writes a small persona block into each app's startup context — backed up first, inside a marked block, fully reversible — or prints the exact changes for you to make by hand (see Manual setup).
When you're done, restart your Claude apps so they pick up the new MCP server.
Usage
You don't call tools or memorize commands. You talk to your agent by name, and it reaches into memory on its own. A few natural examples:
Save something (→ ingest)
"Remember that we dropped Redis — we're on Postgres LISTEN/NOTIFY now."
"Note for the Atlas project: the weekly review moved to Mondays."
The agent also tries to capture durable facts on its own — but treat that as a bonus, not a guarantee (see the note below). Saying "remember: …" is the reliable channel.
On automatic capture. agent-julia is an MCP server, which is pull-only: it never writes on its own, only when the model calls a tool. So "save this" happens only if the agent decides to call
ingestmid-conversation — reliable when you ask explicitly ("remember: …"), best-effort when left to the agent's judgment, and easy to miss during a focused task. The persona core nudges it to capture and to say what it saved, so a miss is visible. If something important didn't land, just say "remember: …".
Recall (→ search, read)
"What did we decide about auth?"
"What do you know about the Atlas pricing model?"
"Did I say anything about onboarding last week?"
Steer the voice (→ correct_voice)
"Stop hedging — commit to an answer."
"Don't open every reply with my name."
The correction is recorded and applied from the next turn, on every surface.
Browse (→ list)
"What's in my memory?" · "List every page you have."
Think something through (→ the brainstorm skill)
"Help me decide whether to take the Berlin offer."
"Let's brainstorm the pricing for the new plan."
"Back to the office-move question from last week." — sessions are resumable; the state lives in memory, so you can start on one machine and finish on another.
Everything you save lands as markdown in your repo and is committed, so you can open it, edit it by hand, or git log the history any time.
How it works
Canonical store — plain markdown in a git repo. Human-readable, portable, versioned, private. This is the source of truth, not a database.
Derived index — SQLite (FTS5 full-text + optional vector embeddings) built from the markdown, via Node's built-in
node:sqlite(no native module to compile). It's disposable: delete it and it rebuilds itself from your files.Budgeted core — a compact persona block is injected into Claude Code's
CLAUDE.mdand Claude Desktop's global instructions. It stays within a token budget you set, so it never crowds out the conversation. Each layer is budgeted separately, and the part that yields is ours: identity and the privacy rail come off the top, your voice and your corrections each get a share, and the shipped universal rules take what's left.maintenanceanddoctorboth say when something didn't fit, rather than trimming in silence.A server per session, one memory — every Claude Code and Claude Desktop session starts its own
agent-juliaserver over stdio, and all of them read and write the same store and index, so they share one memory and one persona. Writes from different sessions take turns under a lock, startup chores that one server can do for all of them (maintenance, refreshing installed files, re-embedding after a model change) are done by whichever starts first, and a server exits when its session does. The local embedding model runs in a separate process that exits after a minute without use, so an idle server holds about 40-50 MB.
Skills
agent-julia ships one skill, installed into ~/.claude/skills/ (which both Claude Code and Cowork read) by the wizard and refreshed automatically every time the server starts — so existing installs pick it up on their next session, no manual step:
brainstorm — a structured facilitator that takes a fuzzy idea or an open decision to a committed outcome. Built for business and life questions, not code. What makes it different from just chatting:
A real process — frame (question, criteria, constraints) → diverge → challenge (assumptions, pre-mortem, inversion) → converge on a recommendation you confirm section by section.
One question per message, with answer options — a dialogue, not a questionnaire.
Thinking lenses — distillations of proven tools (strategy kernel, jobs-to-be-done, willingness to pay, fear-setting, inversion, regret minimization, one-way vs two-way doors…), picked to fit the topic and named when used.
Deep mode — for high-stakes calls the agent offers a panel of 3–4 adversarial perspectives (skeptic, the other side, operator…) run as parallel subagents where available. It costs real tokens, so it never runs without your yes.
It remembers — session state is saved to memory after every phase, so a brainstorm survives days and devices ("back to the X question"); the outcome lands as a decision doc with the options you killed and why, so nothing gets relitigated.
Your places, not hardcoded ones — at the end it offers the doc as a Markdown/HTML file and, based on what tools you have connected, proposes where the actions should go.
The skill starts only when you ask for it (or accept a one-line offer). Your own skill under the same name is never overwritten: installs and uninstalls only touch copies carrying the author: agent-julia marker.
Capture hooks
The agent saves what it is told to save and, on a good day, what it notices. Both slip in a long session. agent-julia hooks install adds three Claude Code hooks that catch what slips, without touching any hook of yours:
On every prompt (
UserPromptSubmit): when your message reads like a correction of the voice ("don't say", "nie pisz", "sounds off", "zamiast"), a one-line reminder to callcorrect_voicebefore replying. EverynudgeEveryTurnsturns (10 by default), a one-line reminder toingestwhat the session decided.Before a compaction and at the end of a session (
PreCompact,SessionEnd): a backgroundclaude -preads what was said since the last pass, searches the memory, and saves the durable facts and voice corrections the session left out. It can only search, read,ingestandcorrect_voice, runs with hooks off, gives up after five minutes, and never holds up your session. What it did goes tohooks.lognext to the config.
agent-julia hooks install # or: uninstall, status"capture": { "hooks": true, "nudgeEveryTurns": 10, "extractOnCompact": true }The hooks go into
settings.jsonof the Claude Code account in use ($CLAUDE_CONFIG_DIR, else~/.claude), with a one-time backup. They run a small script next to the config with Node directly, so a prompt costs one Node start and no package download; the server keeps the script current with each update.The background pass runs
claude -pon your Claude plan, with Sonnet. Anthropic has changed howclaude -pusage counts against plans before and may again; setextractOnCompacttofalseto keep only the reminders.It works the same on a machine connected to a server: the pass saves through the relay.
Claude.ai, the mobile app and Claude Desktop run no hooks. For them, "serverNudge": true in capture has the server itself ask: when a session has kept reading for 20 minutes and saved nothing, the next search, read or list result carries one extra line asking whether something is worth keeping. Once per 20 minutes at most, and never inside the result itself, which stays as it was. Off by default.
Beyond Claude
The persona you built is not locked to Claude. agent-julia export codex writes it into ~/.codex/AGENTS.md, export gemini into ~/.gemini/GEMINI.md, and export <path> into any AGENTS.md-style instruction file — as a marked, removable block, backed up on first touch, and kept refreshed by the server on every boot (a voice correction you make in Claude reaches Codex on its next session). The export carries the persona itself — identity, voice, corrections, privacy rail — without the Claude-specific memory instructions; attach the same MCP server in the other tool if it supports MCP, and the memory follows too.
Run as a server
By default every Claude session starts its own Agent Julia over stdio, on the machine the session runs on. agent-julia serve --http runs one long-lived process instead, serving every session of every client over MCP's Streamable HTTP transport at /mcp. It is the way to reach one memory from more than one machine, and the only way to reach it from a client that cannot start local processes.
"server": { "host": "127.0.0.1", "port": 8787, "auth": "none", "maintenanceEveryMinutes": 60 }One process, one index per store, many sessions. Writes from different sessions are ordered by the same store lock the stdio servers use, so a CLI command on the same machine is still safe to run.
It pulls and maintains every store on start and then every
maintenanceEveryMinutes. It never touches~/.claude, skills, exports or Claude Code's memory on the machine it runs on: there is no local Claude there to serve.GET /healthzreturns JSON for a monitor: version, open sessions, and per store the last write, the last maintenance and its outcome, and how many commits are waiting to be pushed.It binds loopback by default and refuses to start without authentication on any other address, or with a
publicUrlset. Requests must carry a Host the server answers to, and withauth: "none"a request that came through a proxy is refused.--hostand--portoverride the config for one run. Each persona is its own process with its own config (AGENT_JULIA_CONFIG).
Tokens ("auth": "bearer") are for machine clients: a remote proxy, a monitor, a bot.
agent-julia server token add laptop # prints the token once
agent-julia server token add group --stores team # this one reaches only the store "team"
agent-julia server token list
agent-julia server token revoke laptopClients send Authorization: Bearer <token>. Tokens are kept as SHA-256 hashes in secrets/tokens.json next to the config, readable by its owner only, and a running server picks up an added or revoked token without a restart. A token with --stores sees only those stores (primary is your own): the others are absent from search, list and read, it writes only with store, and it cannot change the voice. It still reads the voice: get_core gives it the persona and your corrections, so a group-chat process speaks as your persona over a shared memory. Don't hand such a token to anyone who should not see your corrections. A session belongs to the token that opened it. Without a token, /healthz answers only whether the server is up and its version; with one, it lists the stores that token reaches.
Claude.ai and the Claude mobile app ("auth": "oauth") connect as a custom connector, over OAuth. Claude.ai reaches the server from Anthropic's cloud, so it has to be reachable from the internet over HTTPS: put a reverse proxy or tunnel on the same machine in front of it (Caddy, nginx, cloudflared) and give its address as publicUrl.
"server": { "auth": "oauth", "publicUrl": "https://julia.example.com" }agent-julia server set-owner # the password that approves a connection
agent-julia serve --httpThen in claude.ai: Settings → Connectors → Add custom connector, URL https://julia.example.com/mcp. Claude registers itself and opens the server's consent page, which names the app asking and where it will be sent back; type the owner password and allow. A connector added on the web is in the mobile app too. On a Team or Enterprise plan every member who connects goes through the same page, so they all need the owner password: this mode is for a server one person uses.
Access tokens last an hour and are refreshed without asking; a refresh token is replaced on every use and lapses after 90 days without one. Tokens are kept as hashes in
secrets/oauth.json, readable by its owner only, so a restart logs nobody out.agent-julia server oauth listshows the connected apps;server oauth revoke <client-id>(orall) cuts one off at once, running server included. Changing the owner password does not disconnect anyone by itself.After ten wrong passwords within 15 minutes the consent page stops accepting any until the window passes.
Bearer tokens keep working next to OAuth, for the clients that are not Claude.
Another machine connects to the server instead of keeping its own memory. Make a token for it on the server, then run agent-julia init on the other machine and choose "On an agent-julia server": it asks for the address and the token, checks both, and registers the server with that machine's Claude apps. The config it writes names the server:
"remote": { "url": "https://julia.example.com/mcp", "tokenEnv": "AGENT_JULIA_TOKEN" }agent-julia serveon that machine is then a relay: stdio towards Claude, HTTP towards the server. Tools, theagent-julia://coreresource and the instructions come from the server unchanged. No store, index or git runs there, and the commands that work on a store say to run them on the server.At each session start it refreshes the persona block in
~/.claude/CLAUDE.mdand the shipped skills from the server's core, and again aftercorrect_voice, as a local install does.The token is read from the variable named in
tokenEnv, else fromsecrets/remote-tokennext to the config, where the wizard keeps it (readable by you only). It is never written to the config.When the server is down, a session still starts within seconds: it gets the tools it saw last, and each call answers with an error naming the server instead of hanging. The relay tries again every 30 seconds and picks up a restarted server by itself.
agent-julia doctorchecks the way to the server: that it answers, that it takes the token, and whether its version matches this machine's.serve --remote <url>points one run at another server.
Reference
Deeper detail — search, persona, the file layout, and the full configuration and command reference.
Search
Two layers work together, and both run locally.
Keyword (always on). SQLite FTS5 with Porter stemming, so debug matches debugging, and diacritics folding, so cafe matches café and lodz matches Łódź (the letters SQLite cannot fold on its own — ł, đ, ø, ß — are carried by a folded shadow column, so titles and snippets keep their real spelling). For languages without spaces between words — Chinese, Japanese, Korean, Thai — Agent Julia switches to a trigram tokenizer, with a substring fallback for the one- and two-character queries that are ordinary in those languages. A question asked as a sentence is answered by a ladder: all terms, then content words only, then any two, then the most distinctive one alone. Each hit says which rung it came from, so a loose answer looks loose.
Meaning (optional). Turn on semantic search to find a note even when you phrase it differently, and across languages — a question in Polish can surface an English note. You choose how it runs:
Local model — a multilingual model (the
multilingual-e5family, ~118 languages) runs on your machine, in a separate process that starts when a search or a write needs it and exits after a minute without use. The memory the model takes goes back to the system then, instead of staying with every open Claude session. The first search after a quiet minute takes under a second longer while the model loads; the ones after it take milliseconds. Pages are embedded in parts, split on their own headings, so a long page is searchable to its end and not just to the model's first 512 tokens. No server, no API key, fully offline after a one-time model download. Pick a size in the wizard: small (~120 MB download, ~0.8 GB RAM while running), base (~280 MB, ~1.1 GB), or large (~560 MB, ~1.7 GB). The models run at 8-bit precision (q8): on the maintainer's store it ranked the same top page as full precision for 27 of 28 queries, at a third of the memory. Setembedding.dtypetofp32if you want full precision anyway. The wizard reads your machine's RAM and CPU cores and suggests a tier. RAM is rarely the limit, so the suggestion leans on cores, since a bigger model's main cost is slower CPU inference per query. Needs one extra package,@huggingface/transformers, which stays optional so the base install is tiny.Hosted API — any OpenAI-compatible endpoint (OpenAI, or a local server like Ollama or LM Studio). Your key is read from an environment variable and never written to disk.
None — stay keyword-only. The default, and completely dependency-free.
Hybrid mode blends keyword and meaning, and degrades gracefully: with no embeddings configured, it's simply keyword search.
Persona
The persona has three layers, with a clear order when they disagree:
User corrections (highest) — short notes you record over time, like "don't use the word X" or "less hedging". Captured with the
correct_voicetool, kept invoice-corrections.md, and applied above everything else. It's your agent.Universal core — a small set of communication rules that apply to every persona: talk like a person, lead with a recommendation, skip filler.
Style (lowest) — either one of four shipped voices (sharp co-founder, calm mentor, minimalist engineer, neutral assistant) or your own voice. For the presets, the wizard shows the same message in all four, in your language, so you choose by ear. For a custom voice, pick "Write my own voice" and describe how the agent should speak in
persona.md; it's used in place of a preset.
The composed persona core — identity, universal core, your style or custom voice, and corrections — is injected into each surface's startup context within your token budget, so the agent is always in character without fetching anything. (The get_core tool returns the same core on demand.)
Name, pronouns, and language are yours to set. The default persona is "Julia" (she/her), but you define your own.
Memory model
Your store follows a simple, enforced layout:
your-memory/
index.md catalog of pages (kept current automatically)
log.md append-only journal of changes
pages/ one page per topic, kebab-case
archive/ retired pages, read-onlyPages carry light frontmatter — title, status, last-updated date, and an auto-detected language — and link to each other with [[wiki-links]]. Writing always goes through the ingest tool, which writes the page, refreshes the catalog, appends the journal, reindexes, and commits to git in one step. A write either appends to the page or replaces it, says which it did and by how much, and refuses a replace that would throw an established page away. agent-julia undo walks the commits it wrote and reverses one.
Point the wizard at an existing markdown knowledge base and Agent Julia adopts it: your pages are indexed and a hand-written index.md is left alone — Agent Julia only manages a clearly marked block inside it.
Shared stores
A store can be mounted next to your own, for memory that belongs to more than one person (a team, a household, a project two people run). It is an ordinary Agent Julia store in its own directory, with its own index, git history and remote, and it can be served on its own as well.
"stores": [
{ "name": "team", "dir": "~/team-memory", "write": true,
"gitRemote": "git@github.com:acme/team-memory.git", "gitAutoPush": true }
]Its pages are addressed as
team:page; your own keep their bare ids.[[team:pricing]]links into it, a bare[[link]]stays inside the store it is written in.searchandlistcover every mounted store, and each hit says which one it came from. Search ranks them as if they were one store: on a test that split a real 282-page store in two, the merged results matched the unsplit store's top hit in 98-99% of queries.Writing goes to your own memory unless
ingestis givenstore: "team", and the agent is told to do that only when you ask. A shared page id alone does not count, so an agent cannot spill a private fact into a shared page by copying its id. A store without"write": trueis read-only.Your persona, voice corrections, catalog and the blocks in Claude's files stay with your own store; a shared store's
persona.mdis never read.Maintenance runs per store on startup and in
agent-julia maintenance; one store failing does not stop the others. A store with agitRemoteis pulled first.
When a project documents itself
Most projects already document themselves, and that documentation should not become a copy inside your store: it is large, it changes daily, and a copy goes stale the same week. A page can say where the rest of what it is about actually lives, and Agent Julia routes there instead.
project: ~/Sites/atlas
sources:
- kind: dir
at: _doc
about: product and technical documentation
- kind: mcp
at: acme
how: docs_search, docs_read
about: company documentation, reachable without the repokind is dir, file, mcp or url, so a documentation tree, a company MCP server, a Notion space and a repo's own CLAUDE.md are all declared the same way. A string works too ("dir:_doc — the product docs"). A documentation directory and a CLAUDE.md in the project are found without being declared; a server or a URL has to be written down, because no directory listing reveals it.
The route then travels wherever the question is asked: search attaches it to a hit on that page, read appends it to the page, and the block in Claude Code's own memory directory names it for an agent standing inside the repo. Every one of them carries the same rule — ask Agent Julia about the user, their projects and past decisions, read the project's own documentation for how the project works.
Claude Code's own memory
Claude Code keeps a memory of its own: one directory per working directory under ~/.claude/projects/<project>/memory, an index it puts into the prompt of every session started there, and one file per fact. It does the same job as this store and reaches exactly one directory — a fact saved there is invisible to Claude Desktop, to Cowork, and to the same repo opened from another machine.
Agent Julia settles it. codeMemory in the config takes three values:
What it does | |
| Owns a marked block in that index telling the client to search and save here instead. Nothing is read, nothing is moved. |
| Additionally moves what was written there anyway onto a page in your store, and leaves behind a pointer to it — keeping the description the client recalls on, so the fact still surfaces, now pointing at the current version. |
| Leaves those directories completely alone. |
Directories are never created: only the ones Claude Code made for itself are touched, the block goes in next to whatever you wrote there, and every file replaced by a pointer is backed up first. agent-julia uninstall removes the blocks and restores the files.
A directory holding more than 25 facts of its own is left alone even under absorb, and reported instead: that much is a knowledge base someone chose to keep next to the repo, not a handful of strays, and folding it in unasked would bury a decision you made. agent-julia sync --absorb-all brings it in when you mean to.
How the persona reaches each surface
Two halves, delivered differently, because one of them can be written for you and the other cannot.
Claude Code | Claude Desktop | |
Identity, language, never-store | rewritten in | pasted once by you; it only changes if you rename your agent |
Your voice and every correction | same block, always current | fetched with |
When a correction you just made applies | that turn, and in the prompt from the next session | that turn, and in the next conversation |
The server also hands every client a short set of instructions when it connects — who the agent is, what it must never store, and the instruction to load the rest. That part needs no paste at all, so a machine where you never finished the setup still gets a named agent that knows what it must not keep.
agent-julia doctor reports what it actually knows here, and says plainly what it cannot: it has no way to read the in-app field, so it tells you what it last asked you to paste, what the newest Desktop session was started with when it left a copy on disk (recent Claude Desktop versions often do not), and whether the voice has genuinely been fetched there.
Optionally back the store with a git remote — a private GitHub repo, say — set in the wizard or later with agent-julia remote <url>. By default it syncs on maintenance (and server startup), best-effort, so an offline moment or a missing credential never blocks a write; it just pushes on the next run. Turn on gitAutoPush to push after every write instead, trading a network round-trip per write for immediate off-machine backup. agent-julia push syncs on demand. With a remote set, the server also pulls on startup — so on a second machine, a session starts from what the first one pushed; a merge conflict is aborted (never left half-done) and reported for a by-hand agent-julia pull.
You drive Agent Julia by talking to it (see Usage); these are the underlying tools and the CLI.
MCP tools (the agent calls these for you):
Tool | What it does |
| Find pages by keyword and meaning |
| Read a page exactly as stored, front matter included. A page over 32 KB answers with its table of contents; |
| List pages with title, status, and date (bounded; takes |
| Write a page: |
| Record a voice correction (one rule per call, up to 1,200 characters; a longer one is refused, never cut) |
| Withdraw one, keeping the record of having had it |
| How one page changed: when, what was added, what was removed |
| Walk the |
| Retire a page into |
| Return the budgeted persona core |
| Reindex, flag stale notes and broken links, recompact, commit |
The persona core is also exposed as a resource (agent-julia://core) for clients that prefer resources to a tool call.
CLI commands (you run these):
Command | |
| Start the MCP server (default; used by the Claude apps) |
| Make a bearer token for the HTTP server ( |
| Set the password that approves OAuth connections such as claude.ai |
| List the apps connected over OAuth ( |
| Run one long-lived HTTP server for many sessions and machines (see Run as a server) |
| Relay to an agent-julia server instead of a local store; the default for |
| Run the setup wizard |
| Add the capture hooks to Claude Code ( |
| Re-apply registration, the persona block, the shipped skills and the Claude Code memory handling ( |
| Remove the managed blocks, registration, and shipped skills (backups are kept) |
| Search your memory from the terminal (same hybrid index the agent uses) |
| Print one memory page |
| Export the persona to another tool's instruction file ( |
| Run automatic store maintenance from the terminal (reindex, flag stale/orphans, refresh catalog, commit) |
| Check the whole installation: MCP registration and whether the registered program still exists, persona blocks (including Cowork paste drift), skills, store, index, and whether semantic search actually loads — with a suggested fix per finding. |
| Show or set a git remote to back up your memory |
| Push the memory store to its remote now |
| Pull the memory store from its remote now (two-machine sync) |
| List recent changes to your memory, and undo one by id |
| Rebuild the search index from your markdown (it is disposable) |
| List what is archived, and bring one back |
| Move the memory store and point the config at it |
| Apply pending data migrations and exit |
Settings live in ~/.config/agent-julia/config.json and carry a schemaVersion. The wizard writes it for you; the fields:
Field | Meaning |
| Persona identity |
| The agent's reply language (any code or name) |
| One of the four voices |
| Your markdown store |
| Version the store with git and commit after every write (default on) |
| Optional git remote (e.g. a private GitHub repo) to back up / sync the store |
| Push after every write, not just on maintenance (default off) |
|
|
| Provider ( |
| Token ceiling for the persona core. The memory instruction (~280 tokens) is added on top; |
| Which Claude apps to register |
| What to do about Claude Code's own per-project memory: |
| Files outside Claude that carry an exported persona block, kept current on every start (managed with |
| How the weekly digest is meant to run: |
| Categories the agent must never store (keys, card numbers, third-party private data) |
| Optional, read only by |
| Optional. The agent-julia server this machine connects to instead of keeping a store: |
| Optional. Other agent-julia stores mounted next to yours: |
| Optional: |
| Optional. Read |
The wizard can write the Claude config changes for you, or print the exact edits so you make them yourself — it asks which you prefer, and never touches a Claude file without that choice. To see the steps any time:
agent-julia sync --printWhat it adds:
Claude Code — in ~/.claude.json, add the server under mcpServers:
{ "mcpServers": { "agent-julia": { "command": "npx", "args": ["-y", "agent-julia@latest", "serve"] } } }That is the entry for the default setup. With the local model, command is your Node binary and args is the installed copy (<npm root -g>/agent-julia/dist/index.js followed by serve); agent-julia sync --print prints the exact entry for your machine.
Then append the persona block (printed by the command) to ~/.claude/CLAUDE.md.
Claude Desktop — add the same mcpServers entry to the Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS), and paste the short persona block into Settings → Instructions for Claude. That field lives inside the app and no program can write it, so it is the one manual step — which is exactly why what goes in it is only the part that never changes: the name, the pronouns, the reply language and the never-store list. Your voice and your corrections are not in it; the agent fetches those at the start of a conversation, so they are current without you pasting again. agent-julia paste prints the block and copies it.
Dispatch (mobile) isn't supported. It can't run or reach the local stdio MCP server, and it doesn't read Cowork's Global instructions — so neither the memory tools nor the persona reach it in a local-first setup. Covering Dispatch would need the server hosted remotely, which is out of scope here.
The persona block is small on purpose — identity plus an instruction to use agent-julia for memory. Everything else is fetched on demand. When the wizard does this for you, it backs up each file first, writes inside a marked block, and agent-julia uninstall removes it cleanly.
Housekeeping runs on its own. On every write, and when a server starts after something changed on disk (one server at a time; the others skip it), Agent Julia reindexes changed pages, picks up files you edited by hand, flags stale-dated notes and broken links, refreshes the catalog, recompacts the persona core, and commits. Nothing is deleted without you — stale items are flagged, not removed.
A heavier weekly pass — merging duplicates, retiring stale pages, fixing broken links — is owner's-judgment work, so it runs as a digest: ask your agent to "run the weekly digest" (or schedule a recurring Cowork task with that prompt), and it gathers the candidates — near-duplicate pages (the ten pairs whose closest parts are most alike), long-untouched facts, orphan [[links]], unlinked pages, oversized pages — and walks you through them one at a time. Nothing changes without your yes; approved retirements go to archive/ (kept on disk and in git history, out of the index). agent-julia maintenance runs the automatic half from the terminal.
Upgrades are backward-compatible, or they ship an automatic migration that runs on first launch — backed up, idempotent, and transparent. The config carries a schemaVersion; ordered migration steps bring older stores forward on startup. The derived search index is disposable and simply rebuilds itself when its shape changes. A server registered through npx (@latest) picks up a new version on its own at the next session; pin an exact version (agent-julia@<version>) if you want it fixed. An installed copy, which the local model needs, updates with npm i -g agent-julia@latest, and sessions already open keep the old version until they are restarted or reloaded with /mcp. When a release changes how vectors are made, the first server to start re-embeds the store once, in the background. Either way, upgrades never lose data and never ask you to hand-edit files.
Releasing (maintainers)
CI runs typecheck, build, and tests on every pull request and push to main (Node 24). Releases are tag-driven:
# add the new section to CHANGELOG.md, then:
npm version <patch|minor|major>
git push --follow-tagsA vX.Y.Z tag triggers the release workflow: it checks the tag against package.json, runs the tests, publishes to npm via Trusted Publishing (OIDC — no stored token, provenance attached automatically), and cuts a GitHub release from the matching CHANGELOG section.
The animation at the top of this README is scripts/demo/demo.html; node scripts/demo/render.mjs turns it into demo.gif (it needs Google Chrome and ffmpeg).
Some names must never appear in this repository. npm run hooks points git at .githooks, whose pre-commit, commit-msg and pre-push hooks run scripts/check-names.mjs over what is about to leave the machine: added lines, file paths, commit messages and branch names, ignoring case and accents. The names themselves stay out of the repo, in git config --global --add agentjulia.forbiddenName <name>, and in the AJ_FORBIDDEN_NAMES secret for CI and the release workflow, which check the whole tree. To check a PR description before posting it, pipe it to node scripts/check-names.mjs --stdin.
Credits
The persona's "avoid the tells of AI writing" rules are adapted from the humanizer skill by Siqi Chen (MIT), itself based on Wikipedia's "Signs of AI writing" (WikiProject AI Cleanup, CC BY-SA).
License
MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Persistent personal memory for AI assistants — save, search, and recall across every MCP client.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenancePersistent memory server for AI assistants with semantic search and three-layer context (global, project, personality). Works with MCP-compatible AI tools like Claude Code, Cursor, Continue, Cline, and more.1-
- AlicenseNot gradedqualityCmaintenanceA local-first, team-ready MCP server providing durable memory for LLM-based coding workflows with multiple storage backends and fast search.4MIT
- AlicenseAqualityBmaintenanceMCP server for persistent, cross-session, local-first memory for AI agents, storing memories as Markdown files with SQLite indexing for hybrid search.24Apache 2.0
- AlicenseNot gradedqualityDmaintenanceProvides a file-first personal memory layer for AI agents, enabling them to store and retrieve memories as markdown files with an SQLite index. The MCP server offers read-only search by default, with optional write tools for manual memory addition and conflict resolution.3 npmMIT