Skip to content

mcp · claude-code · revops · ai-governance · agencies

How to Share MCP Servers Across Projects Without Mixing Client Data

Walling every MCP connection off from every other one is half the answer. You want your own tools and playbooks in every client folder, and client instances isolated from each other. Here is the one-way setup, the naming rule it depends on, and the warning Claude Code gives you.

On this page
  1. A one-way membrane, not a wall
  2. How to set it up
  3. The test that proves it works
  4. The collision, and the warning I did not expect
  5. What belongs on each side
  6. Why not just copy your playbooks into each client folder?
  7. Where this runs out

I have written twice now about walling MCP connections off from each other. Once about the leak, once about the machinery. Both posts land on the same advice: keep each client's tools in that client's folder and nowhere else.

That advice is half right, and the missing half is the part I actually use every day.

I do not want isolation from everything. I want isolation from other clients. My own stuff, the Inform Growth tools, my playbooks, the way I have learned to do this work, should be in the room no matter which client I am sitting with. That is the whole reason to have playbooks.

So the shape I want is not a wall. It is a membrane that lets things through in exactly one direction. My context flows down into every client folder. No client's tools flow sideways into another.

Turns out Claude Code gives you that for free, using the exact behaviour I called a hazard in the first post.

A one-way membrane, not a wall.

The first post established that .mcp.json inherits downward. Put a server in a parent folder and every folder beneath it gets that server, even if the child has its own .mcp.json and its own git repository.

I framed that as the trap. It is only a trap when the thing sitting in the parent is client-specific. When the thing sitting in the parent is yours, downward inheritance is precisely the mechanism you want.

So split the two by intent:

-> Shared, in a parent .mcp.json. Your own tools. Your notes, your knowledge base, your internal gateway, anything carrying your process rather than a client's data. Inherits into every client folder underneath.

-> Per-client, at local scope. Their CRM, their Stripe, their analytics. Keyed to that exact folder path, inherits nowhere.

One direction open, the other closed.

There is a side benefit to putting the shared half in .mcp.json rather than user scope, and it is the reason I keep coming back to that file. It is visible. A plain file at a known path that says exactly what is connected. User scope is buried in ~/.claude.json and you will forget it exists. Since the shared servers are the ones you want in every folder, having them written down where you can see them is a feature rather than a hazard.

How to set it up.

Flat client folders under one parent that holds only your own tooling.

~/clients/
  .mcp.json          <- your tools only, nothing client-specific
  acme/              <- Acme's instances, local scope
  northwind/         <- Northwind's instances, local scope
  portfolio-co-1/

The parent file. Note the prefix on every server name, which matters more than it looks:

{
  "mcpServers": {
    "ig-playbooks": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "your-notes-mcp-server"]
    },
    "ig-gateway": {
      "type": "http",
      "url": "https://your-internal-gateway.example.com/mcp"
    }
  }
}

Then each client, from inside their own folder:

cd ~/clients/acme
claude mcp add attio -- npx -y attio-mcp-server
claude mcp add stripe --transport http https://mcp.stripe.com

No scope flag needed. Local is the default.

The test that proves it works.

Same shape as the test in the first post, run on Claude Code v2.1.218. Parent .mcp.json holding a shared server, client folder holding its own at local scope, listed from inside the client folder:

ig-playbooks: echo MY-PLAYBOOKS - Pending approval
attio: echo CLIENT-ATTIO - Failed to connect

Both present. The shared server came down from the parent. The client server is scoped to that folder. Move to ~/clients/northwind and ig-playbooks is still there while Acme's attio is gone.

That is the membrane, and it is two files.

The collision, and the warning I did not expect.

Here is where it gets interesting, and where I was wrong about something.

If your own stack includes a tool in the same category as a client's, you get a name collision. I run Attio for Inform Growth. My clients run Attio. Name both servers attio and the local one wins, because local beats project. Inside Acme's folder, my own Attio is shadowed and I lose access to it without asking to.

I assumed that happened silently. It does not. Claude Code raises a diagnostic:

[Conflicting scopes]
Server "attio" is defined in multiple scopes with different endpoints:
project (echo MY-OWN-ATTIO), local (echo CLIENT-ATTIO).
OAuth tokens are stored per endpoint, so authenticating in one
context will not carry over.

Credit where it is due. That is a good warning, it names both endpoints, and it flags the OAuth consequence, which is the part that would have cost me an afternoon.

But do not rely on it, for one reason. The warning fires on a name collision. It cannot fire when there is no collision, and no collision is exactly the state you are in when a client-specific server is sitting in your shared parent file by mistake. The diagnostic catches the noisy failure. The quiet one is still yours to prevent.

Prefix everything shared. ig-attio, not attio. Then nothing you own can ever be shadowed by a client, and anything unprefixed showing up in the parent file is visibly out of place.

What belongs on each side.

The test is not technical. It is a question about the data.

Shared, in the parent: things that carry how you work. Playbooks, frameworks, internal notes, your own gateway, your standard operating procedures. If it would be equally true and equally useful in front of any client, it goes up top.

Per-client, at local scope: things that carry whose data it is. Any CRM, any billing system, any analytics property, any client file store. If a wrong answer from it would name the wrong company, it goes in the folder.

Anything you are unsure about goes in the folder. The cost of over-isolating is a little friction. The cost of under-isolating is a write to the wrong client's CRM.

Why not just copy your playbooks into each client folder?

Because then you have nine copies and eight of them are stale.

The membrane is not only about access. It is about there being one canonical version of how you work, which you improve in one place and which is immediately live everywhere. Copy-paste gives you the access and loses the single source of truth, which was the actual asset.

This is also why I would rather connect a knowledge tool than paste a document. A document in a folder is a snapshot. A connected server is current.

Where this runs out.

Same place as before. Two files and a naming convention is a real answer for one operator on one machine. It is not an answer for two operators, and nothing here audits itself. You find out it failed when a client tells you.

The pattern is right. The enforcement is manual, and manual enforcement is a promise rather than a control. If you are past the point where a promise is enough, book a chat.

If you have not run the leak test yet, start there. Build the membrane after you know which side of it you are currently on.

- Jaron

Frequently asked questions

How do I share some MCP servers across all projects but keep others per-client?

Put your own shared servers in a .mcp.json at the parent folder that contains your client folders, and add each client's servers at local scope from inside that client's own folder. Project-scope servers in .mcp.json inherit downward into every subfolder, so your tools reach every client. Local-scope servers are keyed to an exact folder path and inherit nowhere, so no client's tools reach another client. The result is one-way access rather than full isolation.

What happens if a shared MCP server and a client MCP server have the same name?

Local scope wins, because local takes precedence over project scope. Your own server is shadowed inside that client's folder and you lose access to it there. Claude Code does raise a [Conflicting scopes] diagnostic naming both endpoints and warning that OAuth tokens are stored per endpoint, so the failure is not silent. Avoid it entirely by prefixing every shared server name, for example ig-attio rather than attio.

Which MCP servers should be shared across clients and which should be isolated?

Shared servers should carry how you work rather than whose data it is: playbooks, frameworks, internal notes, your own gateway, standard operating procedures. Per-client servers should carry client data: any CRM, billing system, analytics property, or client file store. If a wrong answer from a tool would name the wrong company, it belongs at local scope in that client's folder.

Should I use a parent .mcp.json or user scope for tools I want in every client folder?

Yes, and putting them in a parent .mcp.json is usually better than user scope for this. Both reach every client folder, but .mcp.json is a plain visible file at a known path that states exactly what is connected, while user scope is buried in ~/.claude.json and easy to forget. Since shared servers are the ones you want everywhere, visibility is an advantage rather than a risk.

Why connect a shared knowledge server instead of copying playbooks into each client folder?

Copies go stale. Nine client folders means nine versions of your process, eight of which are out of date the moment you improve one. Connecting a shared knowledge server keeps a single canonical version that updates everywhere at once. A pasted document is a snapshot; a connected server is current.