I Gave Claude Code, Codex, Cursor and Copilot One Shared Memory. Here's What Broke.
I use four AI coding tools regularly: Claude Code, Codex, Cursor and GitHub Copilot. They are all good at different things. But they share one frustrating limitation: every new session starts with a surprisingly short m
I use four AI coding tools regularly: Claude Code, Codex, Cursor and GitHub Copilot.
They are all good at different things. But they share one frustrating limitation: every new session starts with a surprisingly short memory.
The architecture decision we discussed yesterday? Gone.
The reason we chose PostgreSQL over another database? Gone.
The migration convention we agreed on last week? Gone.
I kept repeating context, explaining decisions and correcting the same mistakes across different tools.
So I started building Memro: a persistent memory layer that lets different AI coding agents share the same context through MCP.
The idea was simple:
Connect one memory server to every coding agent. Let them remember decisions, preferences, project context and previous work.
In practice, getting this right was more interesting than I expected.
I connected Memro to Claude Code, Codex and GitHub Copilot, and also examined Cursor's rule configuration. I wanted to understand what each tool actually loaded, which configuration took precedence, and whether the agents would invoke memory tools without being explicitly asked.
I discovered that connecting an MCP server is only half the problem.
Here's what I learned.
1. Claude Code: Project configuration overrides global configuration
I had Memro configured globally in ~/.claude.json.
For one project, I wanted an isolated memory configuration, so I added a project-level .mcp.json with a server using the same name, memro, but a different API key.
I expected Claude Code to load the project configuration.
But I wanted to verify what actually happened, not just assume the documentation described the runtime correctly.
I used Claude Code's machine-readable startup output:
claude -p ok --output-format stream-json --verbose
The init event exposed the MCP servers loaded at startup, including their configuration sources.
Here's what I observed:
| Where Claude Code ran | Loaded server | Tools |
|---|---|---|
| Outside the project | User configuration | 25 |
| Inside project, project server unreachable | Project configuration, failed | 0 |
| Inside project, valid project server | Project configuration, connected | 25 |
A few interesting things emerged:
-
Same name means override, not merge. The project-level
memroserver replaces the global one inside that project. - There is no silent fallback. If the project server fails, Claude Code doesn't automatically switch back to the working global server.
-
The CLI can be misleading.
claude mcp getandclaude mcp listcan still show the global configuration. For understanding what actually loaded, inspect the startupinitevent. -
Project approval matters. Claude Code requires one-time approval before using a project's
.mcp.jsonserver. -
Environment variable expansion works. You can use
${MEMRO_API_KEY}in the configuration rather than committing a secret.
The important lesson: the configuration you see isn't necessarily the configuration your agent is running.
2. Codex: Your project configuration needs a trusted folder
Codex supports MCP authentication through bearer_token_env_var.
I tested this against a logging MCP server and verified that Codex sent the expected authorization header:
Authorization: Bearer <value of MEMRO_API_KEY>
That part worked.
The interesting behavior was project-level configuration.
Codex uses .codex/config.toml for project-specific settings, but only when the project folder is trusted.
The trust configuration lives in:
# ~/.codex/config.toml
[projects."/path/to/project"]
trust_level = "trusted"
I tested the same project in two states:
| Project state | Configuration Codex used |
|---|---|
| Folder not trusted | Global configuration |
| Folder trusted | Project configuration |
When the folder wasn't trusted, Codex silently used the global configuration instead of the project's MCP setup.
This is easy to miss because nothing necessarily looks broken. The agent still works, but it may be using a completely different memory server.
One unrelated discovery: if you're running Codex through a shell script, close stdin to prevent codex exec from waiting for input:
codex exec "..." </dev/null
3. GitHub Copilot: Having tools doesn't mean using them
This was probably the most interesting experiment.
I configured Memro as an MCP server in VS Code's mcp.json.
Copilot Agent mode picked it up. Even on the Free plan, the MCP integration worked in my test.
I asked Copilot directly about previous project decisions, and it called Memro's recall tool after requesting permission.
So far, so good.
Then I asked a normal engineering question:
"What is our versioning rule?"
Copilot searched the repository documentation and answered without calling memory.
The problem was that the repository documentation didn't contain the complete decision. That context existed in Memro.
The MCP server was connected. The tools were available. But the model didn't know it should use them.
I needed to solve a different problem: teaching Copilot when to recall memory.
The fix: Persistent instructions
VS Code supports personal and repository-level Copilot instruction files.
For personal instructions:
~/.copilot/instructions/*.instructions.md
For repository instructions:
.github/instructions/*.instructions.md
I created an instruction file with this front matter:
---
description: Memro long-term memory
applyTo: "**"
---
Before answering questions about earlier work,
decisions, rules, or preferences, call Memro's
recall tool first.
Use recalled context before searching project files.
There was one more detail: I had to reload the VS Code window.
The chat session I had already started didn't pick up the newly created instructions.
After reloading, I repeated the same question.
This time Copilot invoked recall automatically and included the missing context in its answer.
The takeaway: MCP exposes capabilities. Instructions teach the agent when to use them.
4. Cursor: Rules need to be explicitly applied
Cursor's rules have a similar consideration.
According to Cursor's documentation, a rule without alwaysApply: true is only used when Cursor decides it's relevant.
For Memro's memory instructions, the rule should explicitly set alwaysApply: true.
A project rule can live at:
.cursor/rules/memro.mdc
With this configuration:
---
description: Memro long-term memory
alwaysApply: true
---
Before answering questions about previous work,
decisions, conventions, or preferences, call
Memro's recall tool.
Use the retrieved context when forming your answer.
The important part is:
alwaysApply: true
This makes the memory instructions available across conversations rather than relying on Cursor to decide whether the rule is relevant.
5. The bigger discovery: MCP integration has three layers
After examining these four tools, I realized that MCP integration isn't just about connecting a server.
There are three separate things to get right.
Layer 1: Connectivity
Can the agent reach the MCP server?
Does authentication work? Is the API key valid? Are the tools available?
Layer 2: Configuration resolution
Which configuration is actually being loaded?
Is the agent using the global configuration or the project configuration? Is the project trusted? Has the server been approved?
Layer 3: Tool invocation
Does the model know when to call the MCP tools?
A server can be perfectly connected, authenticated and available, while the model never invokes it.
This is why checking whether an MCP server is connected isn't enough.
You need to verify all three layers.
6. That's why I built memro-cli doctor
While debugging these differences, I realized developers shouldn't have to manually inspect different configuration systems just to understand why their memory server isn't working.
So I added a doctor command to the Memro CLI.
It inspects the configurations for supported coding agents, determines which configuration applies to the current project, checks authentication and checks whether the necessary memory instructions exist.
Here's the actual output:
โ Claude Code project ./.mcp.json ยท key $MEMRO_API_KEY ยท 25 tools
overrides ~/.claude.json
! Codex global ~/.codex/config.toml ยท key in the file ยท 25 tools ยท uses the global config: Codex ignores ./.codex/config.toml until you open Codex in this folder and trust it
โ VS Code global โฆ/Code/User/mcp.json ยท key in the file ยท 25 tools
Instead of wondering why an agent isn't remembering something, you can start by checking what it's actually configured to use.
7. Try Memro
You can get started with two commands:
npx memro-cli connect
npx memro-cli doctor
The connect command signs you in and configures Memro for the coding tools it finds.
The doctor command checks the resulting setup.
Memro currently supports:
- Claude Code
- OpenAI Codex
- Cursor
- VS Code / GitHub Copilot
- Google Antigravity
- OpenCode
- Gemini CLI
- Windsurf
- Claude Desktop
It also configures the instructions that tell each agent when to use memory.
Memro is source-available under the PolyForm Noncommercial License, free for personal and non-commercial use.
You can explore the code at github.com/memrohq/memro.
SDKs:
pip install memro
npm install @memro/sdk
Final thoughts
Building a shared memory layer for AI coding agents made me realize that the difficult part isn't necessarily storing context.
It's making sure the right context reaches the right agent at the right time.
Every coding tool has its own configuration system, trust model, instruction mechanism and runtime behavior.
MCP gives us a common interface, but the experience around it is still fragmented.
I'm curious how other developers are handling this.
If you've configured MCP across multiple coding agents, what unexpected behavior have you encountered?
And if you've found a better way to make agents consistently use shared memory, I'd love to hear about it.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ full credit and traffic to the original publisher.