mcp-stdio-mux 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ /dist/
4
+ /build/
5
+ *.egg-info/
6
+ .venv/
7
+ .worktrees/
8
+ .ruff_cache/
9
+ .serena/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ahmad Muhyidin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.5
2
+ Name: mcp-stdio-mux
3
+ Version: 0.1.0
4
+ Summary: One shared process per MCP server across every AI agent session, app and profile on your machine.
5
+ Project-URL: Homepage, https://github.com/techidin/mcp-stdio-mux
6
+ Project-URL: Issues, https://github.com/techidin/mcp-stdio-mux/issues
7
+ Author: Ahmad Muhyidin
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: ai-agents,claude-code,codex,mcp,model-context-protocol,stdio
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+
25
+ # mcp-stdio-mux
26
+
27
+ One shared process per MCP server across every AI agent session, app and
28
+ profile on your machine.
29
+
30
+ Open four Claude Code sessions and each one starts its own copy of every stdio
31
+ MCP server you configured. Add Codex, Cursor, or a second profile and the copies
32
+ multiply. `mcp-stdio-mux` puts one shared backend behind all of them; each
33
+ session reaches it through a 1.2 MB relay instead of a server of its own.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ uvx mcp-stdio-mux setup
39
+ ```
40
+
41
+ Setup finds Claude Code (every profile), Claude Desktop, Codex (every profile),
42
+ Gemini CLI, Cursor, Windsurf and OpenCode, shows what it will change, and asks
43
+ once. It installs itself as a `uv` tool so your configs point at a path that
44
+ stays. Restart your agent sessions afterwards.
45
+
46
+ Without `uv`: `pipx install mcp-stdio-mux && mcp-stdio-mux setup`.
47
+
48
+ Setup also gives Claude Code and Codex an agent skill, so you can ask an agent
49
+ to "share my MCP servers" or "share the server I just added".
50
+
51
+ ## Measured
52
+
53
+ Four sessions of one server, every process the sessions caused (relays, daemon,
54
+ backend and its children), macOS 27.2 on Apple silicon with 16 GB, three runs on
55
+ 10 November 2026. The unit is `phys_footprint`, the "Memory" column of Activity
56
+ Monitor.
57
+
58
+ | Server | Without a mux | With mcp-stdio-mux | Saved |
59
+ |---|---|---|---|
60
+ | serena (Python) | 679–757 MB | 202–203 MB | 70–73% |
61
+ | tilth (Node) | 57 MB | 36 MB | 37% |
62
+
63
+ Each session's own process drops from 12–94 MB to 1.2 MB. The saving grows with
64
+ the number of sessions and with how heavy the server is. Reproduce it with any
65
+ server:
66
+
67
+ ```bash
68
+ python scripts/benchmark.py --sessions 4 -- tilth --mcp
69
+ python scripts/benchmark.py --sessions 4 \
70
+ --prefix "mcp-stdio-mux run --domain bench --server tilth" -- tilth --mcp
71
+ ```
72
+
73
+ ## What setup changes, and what it never touches
74
+
75
+ - Each local (stdio) server's command in your user-level config files becomes
76
+ `mcp-stdio-mux run --domain <profile> --server <name> -- <original command>`.
77
+ The original command stays readable after `--`.
78
+ - Every file is backed up to `~/.local/state/mcp-stdio-mux/backups/` first,
79
+ written atomically through symlinks with its permissions kept, then read back.
80
+ - Remote (HTTP or SSE) servers, project `.mcp.json` files, and servers you mark
81
+ `native` are never touched. A file that nothing changes keeps its exact bytes.
82
+ - `mcp-stdio-mux undo` restores each file's exact bytes when the app has not
83
+ written to it since setup, and removes only the wrapper when it has.
84
+ - Running setup a second time changes nothing that is already shared.
85
+
86
+ ## Who shares with whom
87
+
88
+ Two sessions share one backend only when all of these match:
89
+
90
+ | Part | Where it comes from |
91
+ |---|---|
92
+ | Domain | The profile name: `~/.claude-work` and `~/.codex-work` are both `work`; default profiles are `default`. |
93
+ | Command | The exact backend command and arguments. |
94
+ | Credentials | A SHA-256 of the environment variables the config declares. Values are never logged. |
95
+ | Workspace | The git root, for servers bound to the directory they start in. |
96
+
97
+ Differently named profiles never share unless you map them to one domain.
98
+
99
+ Each backend also gets a scope:
100
+
101
+ | Scope | When | Backend |
102
+ |---|---|---|
103
+ | `global` | Default. | One per signature, started in your home directory. |
104
+ | `workspace` | An argument flag names `cwd`, `project`, `workspace` or `root`, an argument is `.`, or the config sets `cwd`. | One per signature and git root. |
105
+ | `session` | The first `tools/list` reply has a tool named like `browser`, `tab`, `page`, `navigate`, `click`, `screenshot`, `session`, `login` or `logout`. | One per session. |
106
+
107
+ Until a server is classified, a second session waits (up to 20 seconds), so no
108
+ session attaches to a stateful server before the mux knows it is one.
109
+
110
+ ## Configuration
111
+
112
+ Optional. `~/.config/mcp-stdio-mux/config.toml`:
113
+
114
+ ```toml
115
+ [profiles]
116
+ work = "default" # let the work profile share with the default one
117
+
118
+ [servers]
119
+ my-browser = "session" # by server name or executable name
120
+ heavy-indexer = "native" # leave it alone; takes effect on the next setup
121
+ ```
122
+
123
+ Scopes are `global`, `workspace`, `session` and `native`.
124
+
125
+ ## Commands
126
+
127
+ | Command | What it does |
128
+ |---|---|
129
+ | `mcp-stdio-mux status` | Which servers each config shares, and every running backend with its sessions and memory. |
130
+ | `mcp-stdio-mux setup [--dry-run] [--yes]` | Share every stdio server in every detected config. |
131
+ | `mcp-stdio-mux undo [--yes]` | Put every config back and remove the skill. |
132
+ | `mcp-stdio-mux run ...` | What your apps call. You do not run this yourself. |
133
+
134
+ ## How it works
135
+
136
+ 1. The app starts `mcp-stdio-mux run`, a short-lived shim.
137
+ 2. The shim finds or starts the daemon for its launch signature (one lock per
138
+ signature), passes its stdin and stdout to the daemon over the Unix socket
139
+ (`SCM_RIGHTS`), and replaces itself with `/bin/cat` named
140
+ `mcp-stdio-mux: <server>`. That relay is the 1.2 MB the app keeps.
141
+ 3. The daemon runs the backend in its own process group. It gives each session's
142
+ JSON-RPC ids and progress tokens a private namespace, answers later
143
+ `initialize` calls from the first result, and sends server requests (roots,
144
+ sampling, elicitation) to a session that supports them.
145
+ 4. A session ends when the app closes its stdin, kills the relay, or exits. When
146
+ the last session is gone, the daemon waits five minutes, then stops the
147
+ backend's whole process group, so `npx` children do not outlive it.
148
+
149
+ Sockets live in a directory only you can read (`$XDG_RUNTIME_DIR/mcp-stdio-mux`
150
+ or `/tmp/mcp-stdio-mux-<uid>`), and a Unix socket cannot be reached from another
151
+ machine.
152
+
153
+ ## Limits
154
+
155
+ - macOS and Linux. Windows is not supported.
156
+ - A shared backend inherits environment variables the config does not declare
157
+ from the session that started it. Declare anything that differs.
158
+ - A server that keeps per-client state but whose tool names do not show it must
159
+ be marked `session`.
160
+ - When a backend crashes, its in-flight requests fail and are not replayed; the
161
+ next session start launches a new backend.
162
+ - An app that dies without being reaped by its parent keeps its session until
163
+ its relay is killed.
164
+
165
+ ## Development
166
+
167
+ Runtime code is Python 3.11+ standard library only.
168
+
169
+ ```bash
170
+ PYTHONPATH=src python -m unittest discover -s tests -t .
171
+ ruff format --check src tests scripts && ruff check src tests scripts
172
+ ```
173
+
174
+ ## License
175
+
176
+ MIT
@@ -0,0 +1,152 @@
1
+ # mcp-stdio-mux
2
+
3
+ One shared process per MCP server across every AI agent session, app and
4
+ profile on your machine.
5
+
6
+ Open four Claude Code sessions and each one starts its own copy of every stdio
7
+ MCP server you configured. Add Codex, Cursor, or a second profile and the copies
8
+ multiply. `mcp-stdio-mux` puts one shared backend behind all of them; each
9
+ session reaches it through a 1.2 MB relay instead of a server of its own.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ uvx mcp-stdio-mux setup
15
+ ```
16
+
17
+ Setup finds Claude Code (every profile), Claude Desktop, Codex (every profile),
18
+ Gemini CLI, Cursor, Windsurf and OpenCode, shows what it will change, and asks
19
+ once. It installs itself as a `uv` tool so your configs point at a path that
20
+ stays. Restart your agent sessions afterwards.
21
+
22
+ Without `uv`: `pipx install mcp-stdio-mux && mcp-stdio-mux setup`.
23
+
24
+ Setup also gives Claude Code and Codex an agent skill, so you can ask an agent
25
+ to "share my MCP servers" or "share the server I just added".
26
+
27
+ ## Measured
28
+
29
+ Four sessions of one server, every process the sessions caused (relays, daemon,
30
+ backend and its children), macOS 27.2 on Apple silicon with 16 GB, three runs on
31
+ 10 November 2026. The unit is `phys_footprint`, the "Memory" column of Activity
32
+ Monitor.
33
+
34
+ | Server | Without a mux | With mcp-stdio-mux | Saved |
35
+ |---|---|---|---|
36
+ | serena (Python) | 679–757 MB | 202–203 MB | 70–73% |
37
+ | tilth (Node) | 57 MB | 36 MB | 37% |
38
+
39
+ Each session's own process drops from 12–94 MB to 1.2 MB. The saving grows with
40
+ the number of sessions and with how heavy the server is. Reproduce it with any
41
+ server:
42
+
43
+ ```bash
44
+ python scripts/benchmark.py --sessions 4 -- tilth --mcp
45
+ python scripts/benchmark.py --sessions 4 \
46
+ --prefix "mcp-stdio-mux run --domain bench --server tilth" -- tilth --mcp
47
+ ```
48
+
49
+ ## What setup changes, and what it never touches
50
+
51
+ - Each local (stdio) server's command in your user-level config files becomes
52
+ `mcp-stdio-mux run --domain <profile> --server <name> -- <original command>`.
53
+ The original command stays readable after `--`.
54
+ - Every file is backed up to `~/.local/state/mcp-stdio-mux/backups/` first,
55
+ written atomically through symlinks with its permissions kept, then read back.
56
+ - Remote (HTTP or SSE) servers, project `.mcp.json` files, and servers you mark
57
+ `native` are never touched. A file that nothing changes keeps its exact bytes.
58
+ - `mcp-stdio-mux undo` restores each file's exact bytes when the app has not
59
+ written to it since setup, and removes only the wrapper when it has.
60
+ - Running setup a second time changes nothing that is already shared.
61
+
62
+ ## Who shares with whom
63
+
64
+ Two sessions share one backend only when all of these match:
65
+
66
+ | Part | Where it comes from |
67
+ |---|---|
68
+ | Domain | The profile name: `~/.claude-work` and `~/.codex-work` are both `work`; default profiles are `default`. |
69
+ | Command | The exact backend command and arguments. |
70
+ | Credentials | A SHA-256 of the environment variables the config declares. Values are never logged. |
71
+ | Workspace | The git root, for servers bound to the directory they start in. |
72
+
73
+ Differently named profiles never share unless you map them to one domain.
74
+
75
+ Each backend also gets a scope:
76
+
77
+ | Scope | When | Backend |
78
+ |---|---|---|
79
+ | `global` | Default. | One per signature, started in your home directory. |
80
+ | `workspace` | An argument flag names `cwd`, `project`, `workspace` or `root`, an argument is `.`, or the config sets `cwd`. | One per signature and git root. |
81
+ | `session` | The first `tools/list` reply has a tool named like `browser`, `tab`, `page`, `navigate`, `click`, `screenshot`, `session`, `login` or `logout`. | One per session. |
82
+
83
+ Until a server is classified, a second session waits (up to 20 seconds), so no
84
+ session attaches to a stateful server before the mux knows it is one.
85
+
86
+ ## Configuration
87
+
88
+ Optional. `~/.config/mcp-stdio-mux/config.toml`:
89
+
90
+ ```toml
91
+ [profiles]
92
+ work = "default" # let the work profile share with the default one
93
+
94
+ [servers]
95
+ my-browser = "session" # by server name or executable name
96
+ heavy-indexer = "native" # leave it alone; takes effect on the next setup
97
+ ```
98
+
99
+ Scopes are `global`, `workspace`, `session` and `native`.
100
+
101
+ ## Commands
102
+
103
+ | Command | What it does |
104
+ |---|---|
105
+ | `mcp-stdio-mux status` | Which servers each config shares, and every running backend with its sessions and memory. |
106
+ | `mcp-stdio-mux setup [--dry-run] [--yes]` | Share every stdio server in every detected config. |
107
+ | `mcp-stdio-mux undo [--yes]` | Put every config back and remove the skill. |
108
+ | `mcp-stdio-mux run ...` | What your apps call. You do not run this yourself. |
109
+
110
+ ## How it works
111
+
112
+ 1. The app starts `mcp-stdio-mux run`, a short-lived shim.
113
+ 2. The shim finds or starts the daemon for its launch signature (one lock per
114
+ signature), passes its stdin and stdout to the daemon over the Unix socket
115
+ (`SCM_RIGHTS`), and replaces itself with `/bin/cat` named
116
+ `mcp-stdio-mux: <server>`. That relay is the 1.2 MB the app keeps.
117
+ 3. The daemon runs the backend in its own process group. It gives each session's
118
+ JSON-RPC ids and progress tokens a private namespace, answers later
119
+ `initialize` calls from the first result, and sends server requests (roots,
120
+ sampling, elicitation) to a session that supports them.
121
+ 4. A session ends when the app closes its stdin, kills the relay, or exits. When
122
+ the last session is gone, the daemon waits five minutes, then stops the
123
+ backend's whole process group, so `npx` children do not outlive it.
124
+
125
+ Sockets live in a directory only you can read (`$XDG_RUNTIME_DIR/mcp-stdio-mux`
126
+ or `/tmp/mcp-stdio-mux-<uid>`), and a Unix socket cannot be reached from another
127
+ machine.
128
+
129
+ ## Limits
130
+
131
+ - macOS and Linux. Windows is not supported.
132
+ - A shared backend inherits environment variables the config does not declare
133
+ from the session that started it. Declare anything that differs.
134
+ - A server that keeps per-client state but whose tool names do not show it must
135
+ be marked `session`.
136
+ - When a backend crashes, its in-flight requests fail and are not replayed; the
137
+ next session start launches a new backend.
138
+ - An app that dies without being reaped by its parent keeps its session until
139
+ its relay is killed.
140
+
141
+ ## Development
142
+
143
+ Runtime code is Python 3.11+ standard library only.
144
+
145
+ ```bash
146
+ PYTHONPATH=src python -m unittest discover -s tests -t .
147
+ ruff format --check src tests scripts && ruff check src tests scripts
148
+ ```
149
+
150
+ ## License
151
+
152
+ MIT
@@ -0,0 +1,10 @@
1
+ # Documentation
2
+
3
+ Start with the [README](../README.md) for installation and behaviour.
4
+
5
+ | Document | What it holds |
6
+ |---|---|
7
+ | [specs/2026-11-10-v0.1-scope.md](specs/2026-11-10-v0.1-scope.md) | The contract for the first public release. |
8
+ | [../skills/mcp-stdio-mux/SKILL.md](../skills/mcp-stdio-mux/SKILL.md) | The agent skill that setup installs. |
9
+ | [../scripts/benchmark.py](../scripts/benchmark.py) | How the README's memory numbers are measured. |
10
+ | [../AGENTS.md](../AGENTS.md) | Rules for contributors and coding agents. |
@@ -0,0 +1,49 @@
1
+ # v0.1 Scope
2
+
3
+ Approved on 10 November 2026. This file is the contract for the first public
4
+ release; a change to a criterion is agreed in writing before the code changes.
5
+
6
+ ## Story
7
+
8
+ As a developer who runs several AI agent apps (Claude Code, Codex, and others),
9
+ each with several profiles, I run one command and every stdio MCP server is
10
+ shared safely across my sessions, so duplicate MCP processes stop eating my RAM.
11
+
12
+ ## Acceptance Criteria
13
+
14
+ 1. **One command.** `uvx mcp-stdio-mux setup` finds every supported app and
15
+ profile, shows which servers it will route through the mux in which file,
16
+ and applies after one confirmation. `--yes` skips the question.
17
+ 2. **Detection.** Claude Code (every `~/.claude*` profile and
18
+ `$CLAUDE_CONFIG_DIR`), Claude Desktop, Codex (every `~/.codex*` home and
19
+ `$CODEX_HOME`), Gemini CLI, Cursor, Windsurf, and OpenCode.
20
+ 3. **Profiles stay isolated.** Profiles with the same name share backends across
21
+ apps (`~/.claude-work` and `~/.codex-work`); differently named profiles never
22
+ share unless the user maps them to one domain in the config file. Different
23
+ declared credentials never share.
24
+ 4. **User configs are safe.** Every file is backed up before it changes, written
25
+ atomically, and re-checked after writing. A second `setup` changes nothing.
26
+ `undo` restores the original bytes when the app has not touched the file
27
+ since, and unwraps in place when it has. HTTP servers are never touched.
28
+ 5. **Lighter shims.** The per-session shim uses at least 50% less memory than the
29
+ internal runtime it replaces, measured the same way. All ported tests pass.
30
+ Baseline corrected on 10 November 2026 from 14 MB (a bare import probe) to
31
+ 18.2–18.5 MB `phys_footprint`, measured with `scripts/benchmark.py`, the same
32
+ tool that measures the new relay.
33
+ 6. **Agent skill.** `SKILL.md` lets a user ask an agent to "share my MCP
34
+ servers": the agent previews, applies after consent, verifies with
35
+ `mcp-stdio-mux status`, and knows how to undo.
36
+ 7. **Release.** macOS and Linux CI pass on Python 3.11 and 3.13, the wheel
37
+ installs into a clean environment, the private-data scan is clean, and the
38
+ README carries before/after numbers measured on a real machine.
39
+
40
+ ## Out of Scope
41
+
42
+ Windows; project files such as a repository's `.mcp.json` (they belong to a
43
+ team); HTTP and SSE servers; request replay after a backend crash; a dashboard;
44
+ re-wrapping new servers without a command (re-run `setup` or ask the skill).
45
+
46
+ ## Definition of Done
47
+
48
+ Each criterion has evidence in the release pull request; CI is green; the
49
+ owner makes the repository public and registers the PyPI trusted publisher.
@@ -0,0 +1,54 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.26"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mcp-stdio-mux"
7
+ dynamic = ["version"]
8
+ description = "One shared process per MCP server across every AI agent session, app and profile on your machine."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Ahmad Muhyidin" }]
13
+ requires-python = ">=3.11"
14
+ dependencies = []
15
+ keywords = ["mcp", "model-context-protocol", "claude-code", "codex", "ai-agents", "stdio"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: MacOS",
21
+ "Operating System :: POSIX :: Linux",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Software Development :: Libraries",
27
+ "Topic :: Utilities",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/techidin/mcp-stdio-mux"
32
+ Issues = "https://github.com/techidin/mcp-stdio-mux/issues"
33
+
34
+ [project.scripts]
35
+ mcp-stdio-mux = "mcp_stdio_mux.cli:main"
36
+
37
+ [tool.hatch.version]
38
+ path = "src/mcp_stdio_mux/__init__.py"
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/mcp_stdio_mux"]
42
+
43
+ [tool.hatch.build.targets.wheel.force-include]
44
+ "skills/mcp-stdio-mux/SKILL.md" = "mcp_stdio_mux/SKILL.md"
45
+
46
+ [tool.hatch.build.targets.sdist]
47
+ include = ["src", "tests", "skills", "docs", "README.md", "LICENSE"]
48
+
49
+ [tool.ruff]
50
+ line-length = 88
51
+ target-version = "py311"
52
+
53
+ [tool.ruff.lint]
54
+ select = ["E", "F", "W", "I", "B", "UP"]
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: mcp-stdio-mux
3
+ description: Use when the user wants MCP servers to stop piling up across agent sessions, asks to share or dedupe MCP server processes to save memory, added a new stdio MCP server after mcp-stdio-mux setup, sees an MCP server fail after setup, or wants to undo mcp-stdio-mux.
4
+ ---
5
+
6
+ # mcp-stdio-mux
7
+
8
+ `mcp-stdio-mux` makes every session of every agent app (Claude Code, Claude
9
+ Desktop, Codex, Gemini CLI, Cursor, Windsurf, OpenCode) share one process per
10
+ stdio MCP server instead of starting its own copy. It rewrites each server's
11
+ command in the user's own config files, with backups and a full undo.
12
+
13
+ ## Share the user's servers
14
+
15
+ 1. Look before changing anything:
16
+
17
+ ```bash
18
+ mcp-stdio-mux status # or: uvx mcp-stdio-mux status
19
+ mcp-stdio-mux setup --dry-run
20
+ ```
21
+
22
+ 2. Show the user the plan: which apps, profiles, and how many servers. Say that
23
+ profiles with different names never share (unless mapped in the config), and
24
+ that remote (HTTP) servers and project `.mcp.json` files are not touched.
25
+ 3. Apply only after the user agrees:
26
+
27
+ ```bash
28
+ mcp-stdio-mux setup --yes
29
+ ```
30
+
31
+ If `mcp-stdio-mux` is not on PATH, `uvx mcp-stdio-mux setup --yes` installs it
32
+ as a tool first, so the configs point at a path that stays.
33
+ 4. Tell the user to restart agent sessions; open sessions keep their old servers.
34
+ 5. After the restart, `mcp-stdio-mux status` lists each running backend and how
35
+ many sessions it serves.
36
+
37
+ Never wrap or unwrap a server by editing a config file by hand; re-run `setup`.
38
+
39
+ ## When the user adds a server later
40
+
41
+ Run `mcp-stdio-mux setup --dry-run`, show the one new line, then `setup --yes`.
42
+ A second `setup` changes nothing that is already shared.
43
+
44
+ ## When a server misbehaves
45
+
46
+ - Find its daemon in `mcp-stdio-mux status`; its log is
47
+ `<runtime dir>/<key>.log` (runtime dir: `$MCP_STDIO_MUX_RUNTIME_DIR`, else
48
+ `$XDG_RUNTIME_DIR/mcp-stdio-mux`, else `/tmp/mcp-stdio-mux-<uid>`).
49
+ - A server that keeps per-client state (a browser, a login) must not be shared.
50
+ The mux detects most of them from their tool names. For one it misses, add to
51
+ `~/.config/mcp-stdio-mux/config.toml`:
52
+
53
+ ```toml
54
+ [servers]
55
+ my-browser = "session" # one backend per session
56
+ # other scopes: "global", "workspace" (one per git root), "native" (leave alone)
57
+ ```
58
+
59
+ Keys are the server name or the executable name. `native` takes effect after
60
+ `setup` runs again; the other scopes apply at the next session start.
61
+ - To let two differently named profiles share (for example `work` and `default`):
62
+
63
+ ```toml
64
+ [profiles]
65
+ work = "default"
66
+ ```
67
+
68
+ then run `setup` again.
69
+
70
+ ## Undo
71
+
72
+ ```bash
73
+ mcp-stdio-mux undo --yes
74
+ ```
75
+
76
+ It restores each file's exact bytes when the app has not written to it since
77
+ setup, and removes only the mux wrapper when it has. It also removes this skill.
@@ -0,0 +1,3 @@
1
+ """Share one stdio MCP server process across agent sessions, apps and profiles."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from mcp_stdio_mux.cli import main
2
+
3
+ raise SystemExit(main())