From de0ee90b58da970b272609acb25e6cf0f962a3e1 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Fri, 8 May 2026 22:15:24 +0000 Subject: [PATCH 1/5] docs(slug): use "tmux" as the registration slug throughout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit why: README's recommended registration slug is `tmux` (matches what users actually think — "the tmux MCP"), but `docs/clients.md` and the install-widget were using `libtmux`. Followers of either doc would end up with `mcp__tmux__*` or `mcp__libtmux__*` tool prefixes depending on which page they read. Aligning every doc to `tmux` removes the papercut. what: - docs/clients.md: 18 registration-slug `libtmux` -> `tmux` (in `claude mcp add ...`, `codex mcp add ...`, `gemini mcp add ...`, JSON `mcpServers.libtmux` keys, TOML `[mcp_servers.libtmux]` key). Package name `libtmux-mcp`, module `libtmux_mcp`, and GitHub link unchanged. - docs/_ext/widgets/mcp_install.py: 9 registration-slug occurrences in INSTALL_CMDS dict updated to `tmux`. `pip install libtmux-mcp` lines unchanged. - tests/docs/test_widgets.py + snapshots: assertions and stored snapshots updated to expect the new `tmux` slug. note: existing user registrations as `libtmux` keep working — the slug is a per-install user choice, not a property of the package. This change recommends `tmux` for new installs. --- AGENTS.md | 4 +- docs/_ext/widgets/mcp_install.py | 24 +++++------ docs/clients.md | 49 +++++++++++++--------- scripts/mcp_swap.py | 11 ++++- tests/docs/__snapshots__/test_widgets.ambr | 4 +- tests/docs/test_widgets.py | 6 +-- tests/test_mcp_swap.py | 7 +++- 7 files changed, 64 insertions(+), 41 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b81231a7..b7fac75e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -394,7 +394,7 @@ Good: ```console $ claude mcp add \ --scope user \ - libtmux -- \ + tmux -- \ uv --directory ~/work/python/libtmux-mcp \ run libtmux-mcp ``` @@ -402,7 +402,7 @@ $ claude mcp add \ Bad: ```console -$ claude mcp add --scope user libtmux -- uv --directory ~/work/python/libtmux-mcp run libtmux-mcp +$ claude mcp add --scope user tmux -- uv --directory ~/work/python/libtmux-mcp run libtmux-mcp ``` ## Debugging Tips diff --git a/docs/_ext/widgets/mcp_install.py b/docs/_ext/widgets/mcp_install.py index 89fd89e5..9d4273a9 100644 --- a/docs/_ext/widgets/mcp_install.py +++ b/docs/_ext/widgets/mcp_install.py @@ -91,7 +91,7 @@ class Panel: """\ { "mcpServers": { - "libtmux": { + "tmux": { "command": "uvx", "args": ["libtmux-mcp"] } @@ -102,7 +102,7 @@ class Panel: """\ { "mcpServers": { - "libtmux": { + "tmux": { "command": "pipx", "args": ["run", "libtmux-mcp"] } @@ -113,7 +113,7 @@ class Panel: """\ { "mcpServers": { - "libtmux": { + "tmux": { "command": "libtmux-mcp" } } @@ -122,15 +122,15 @@ class Panel: } _CLI_BODIES: collections.abc.Mapping[tuple[str, str], str] = { - ("claude-code", "uvx"): "claude mcp add libtmux -- uvx libtmux-mcp", - ("claude-code", "pipx"): "claude mcp add libtmux -- pipx run libtmux-mcp", - ("claude-code", "pip"): "claude mcp add libtmux -- libtmux-mcp", - ("codex", "uvx"): "codex mcp add libtmux -- uvx libtmux-mcp", - ("codex", "pipx"): "codex mcp add libtmux -- pipx run libtmux-mcp", - ("codex", "pip"): "codex mcp add libtmux -- libtmux-mcp", - ("gemini", "uvx"): "gemini mcp add libtmux uvx -- libtmux-mcp", - ("gemini", "pipx"): "gemini mcp add libtmux pipx -- run libtmux-mcp", - ("gemini", "pip"): "gemini mcp add libtmux libtmux-mcp", + ("claude-code", "uvx"): "claude mcp add tmux -- uvx libtmux-mcp", + ("claude-code", "pipx"): "claude mcp add tmux -- pipx run libtmux-mcp", + ("claude-code", "pip"): "claude mcp add tmux -- libtmux-mcp", + ("codex", "uvx"): "codex mcp add tmux -- uvx libtmux-mcp", + ("codex", "pipx"): "codex mcp add tmux -- pipx run libtmux-mcp", + ("codex", "pip"): "codex mcp add tmux -- libtmux-mcp", + ("gemini", "uvx"): "gemini mcp add tmux uvx -- libtmux-mcp", + ("gemini", "pipx"): "gemini mcp add tmux pipx -- run libtmux-mcp", + ("gemini", "pip"): "gemini mcp add tmux libtmux-mcp", } diff --git a/docs/clients.md b/docs/clients.md index 5bb64a3c..6c338cd1 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -4,13 +4,22 @@ Copy-pasteable configuration for every supported MCP client. If your client isn't listed, any tool supporting MCP stdio transport will work with the JSON config pattern. +```{note} +**Migrating from the `libtmux` slug.** Earlier versions of these docs +used `claude mcp add libtmux …`; this page now uses `tmux` to match +`serverInfo.name` and the `mcp__tmux__*` tool prefix. Existing +`libtmux` registrations keep working — re-register only if you want +the new slug. The package name (`libtmux-mcp`), Python module +(`libtmux_mcp`), and GitHub repo are unchanged. +``` + ## Claude Code `````{tab} uvx With [uv](https://docs.astral.sh/uv/) installed: ```console -$ claude mcp add libtmux -- uvx libtmux-mcp +$ claude mcp add tmux -- uvx libtmux-mcp ``` ````` @@ -18,7 +27,7 @@ $ claude mcp add libtmux -- uvx libtmux-mcp With [pipx](https://pipx.pypa.io/) installed: ```console -$ claude mcp add libtmux -- pipx run libtmux-mcp +$ claude mcp add tmux -- pipx run libtmux-mcp ``` ````` @@ -32,7 +41,7 @@ $ pip install --user --upgrade libtmux libtmux-mcp Then register: ```console -$ claude mcp add libtmux -- libtmux-mcp +$ claude mcp add tmux -- libtmux-mcp ``` ````` @@ -48,7 +57,7 @@ With [uv](https://docs.astral.sh/uv/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "uvx", "args": ["libtmux-mcp"] } @@ -63,7 +72,7 @@ With [pipx](https://pipx.pypa.io/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "pipx", "args": ["run", "libtmux-mcp"] } @@ -84,7 +93,7 @@ Then use this config: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "libtmux-mcp" } } @@ -98,7 +107,7 @@ Then use this config: With [uv](https://docs.astral.sh/uv/) installed: ```console -$ codex mcp add libtmux -- uvx libtmux-mcp +$ codex mcp add tmux -- uvx libtmux-mcp ``` ````` @@ -106,7 +115,7 @@ $ codex mcp add libtmux -- uvx libtmux-mcp With [pipx](https://pipx.pypa.io/) installed: ```console -$ codex mcp add libtmux -- pipx run libtmux-mcp +$ codex mcp add tmux -- pipx run libtmux-mcp ``` ````` @@ -120,7 +129,7 @@ $ pip install --user --upgrade libtmux libtmux-mcp Then register: ```console -$ codex mcp add libtmux -- libtmux-mcp +$ codex mcp add tmux -- libtmux-mcp ``` ````` @@ -130,7 +139,7 @@ $ codex mcp add libtmux -- libtmux-mcp Add to `~/.codex/config.toml`: ```toml -[mcp_servers.libtmux] +[mcp_servers.tmux] command = "uvx" args = ["libtmux-mcp"] ``` @@ -143,7 +152,7 @@ args = ["libtmux-mcp"] With [uv](https://docs.astral.sh/uv/) installed: ```console -$ gemini mcp add libtmux uvx -- libtmux-mcp +$ gemini mcp add tmux uvx -- libtmux-mcp ``` ````` @@ -151,7 +160,7 @@ $ gemini mcp add libtmux uvx -- libtmux-mcp With [pipx](https://pipx.pypa.io/) installed: ```console -$ gemini mcp add libtmux pipx -- run libtmux-mcp +$ gemini mcp add tmux pipx -- run libtmux-mcp ``` ````` @@ -165,7 +174,7 @@ $ pip install --user --upgrade libtmux libtmux-mcp Then register: ```console -$ gemini mcp add libtmux libtmux-mcp +$ gemini mcp add tmux libtmux-mcp ``` ````` @@ -181,7 +190,7 @@ With [uv](https://docs.astral.sh/uv/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "uvx", "args": ["libtmux-mcp"] } @@ -196,7 +205,7 @@ With [pipx](https://pipx.pypa.io/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "pipx", "args": ["run", "libtmux-mcp"] } @@ -217,7 +226,7 @@ Then use this config: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "libtmux-mcp" } } @@ -252,7 +261,7 @@ For live development, point your client at a local checkout via `uv --directory` ```console $ claude mcp add \ --scope user \ - libtmux -- \ + tmux -- \ uv --directory ~/work/python/libtmux-mcp \ run libtmux-mcp ``` @@ -263,7 +272,7 @@ $ claude mcp add \ **Codex CLI:** ```console -$ codex mcp add libtmux -- \ +$ codex mcp add tmux -- \ uv --directory ~/work/python/libtmux-mcp \ run libtmux-mcp ``` @@ -273,7 +282,7 @@ $ codex mcp add libtmux -- \ ```console $ gemini mcp add \ --scope user \ - libtmux uv -- \ + tmux uv -- \ --directory ~/work/python/libtmux-mcp \ run libtmux-mcp ``` @@ -283,7 +292,7 @@ $ gemini mcp add \ ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "uv", "args": [ "--directory", "~/work/python/libtmux-mcp", diff --git a/scripts/mcp_swap.py b/scripts/mcp_swap.py index fe8534f2..edba135d 100644 --- a/scripts/mcp_swap.py +++ b/scripts/mcp_swap.py @@ -579,7 +579,16 @@ def _spec_from_entry(entry: t.Any, *, fmt: t.Literal["json", "toml"]) -> McpServ def resolve_repo_meta(repo: pathlib.Path) -> tuple[str, str]: - """Derive (server_name, entry_command) from the repo's pyproject.toml.""" + """Derive (server_name, entry_command) from the repo's pyproject.toml. + + The server name is the registration slug used as the config-file key + (``mcpServers.`` in JSON, ``[mcp_servers.]`` in TOML). + Default: package name with the trailing ``-mcp`` stripped + (``libtmux-mcp`` → ``libtmux``). This matches the slug existing + users registered under, so ``mcp_swap use-local`` swaps their + entry in place. README and ``serverInfo.name`` recommend ``tmux`` + for fresh installs; pass ``--server tmux`` to target that. + """ pyproject = repo / "pyproject.toml" doc = tomlkit.parse(pyproject.read_text()) project = doc.get("project") diff --git a/tests/docs/__snapshots__/test_widgets.ambr b/tests/docs/__snapshots__/test_widgets.ambr index 1e87a1a2..18970ef3 100644 --- a/tests/docs/__snapshots__/test_widgets.ambr +++ b/tests/docs/__snapshots__/test_widgets.ambr @@ -1,7 +1,7 @@ # serializer version: 1 # name: test_highlight_filter_matches_sphinx_native[console-claude-code-uvx][highlight_console-claude-code-uvx] ''' -
$ claude mcp add libtmux -- uvx libtmux-mcp
+  
$ claude mcp add tmux -- uvx libtmux-mcp
   
''' @@ -17,7 +17,7 @@ '''
{
       "mcpServers": {
-          "libtmux": {
+          "tmux": {
               "command": "uvx",
               "args": ["libtmux-mcp"]
           }
diff --git a/tests/docs/test_widgets.py b/tests/docs/test_widgets.py
index 00f39406..ec556a61 100644
--- a/tests/docs/test_widgets.py
+++ b/tests/docs/test_widgets.py
@@ -61,7 +61,7 @@ def test_build_panels_first_cell_is_claude_code_uvx() -> None:
 def test_body_for_cli_client_returns_shell_command() -> None:
     """CLI clients get the literal `` mcp add ...`` shell command."""
     body = _body_for(CLIENTS[0], METHODS[0])  # claude-code + uvx
-    assert body == "claude mcp add libtmux -- uvx libtmux-mcp"
+    assert body == "claude mcp add tmux -- uvx libtmux-mcp"
 
 
 def test_body_for_json_client_returns_config_snippet() -> None:
@@ -230,7 +230,7 @@ class HighlightCase(t.NamedTuple):
 HIGHLIGHT_CASES: list[HighlightCase] = [
     HighlightCase(
         test_id="console-claude-code-uvx",
-        code="$ claude mcp add libtmux -- uvx libtmux-mcp",
+        code="$ claude mcp add tmux -- uvx libtmux-mcp",
         language="console",
     ),
     HighlightCase(
@@ -244,7 +244,7 @@ class HighlightCase(t.NamedTuple):
             """\
             {
                 "mcpServers": {
-                    "libtmux": {
+                    "tmux": {
                         "command": "uvx",
                         "args": ["libtmux-mcp"]
                     }
diff --git a/tests/test_mcp_swap.py b/tests/test_mcp_swap.py
index ee3c7fe8..0ea3b56b 100644
--- a/tests/test_mcp_swap.py
+++ b/tests/test_mcp_swap.py
@@ -108,7 +108,12 @@ def _pinned_claude_entry() -> dict[str, t.Any]:
 
 
 def test_resolve_repo_meta_strips_mcp_suffix(fake_repo: pathlib.Path) -> None:
-    """``libtmux-mcp`` resolves to server name ``libtmux`` and entry ``libtmux-mcp``."""
+    """``libtmux-mcp`` resolves to server name ``libtmux`` and entry ``libtmux-mcp``.
+
+    The default matches the slug pre-existing users registered under;
+    ``--server tmux`` is the override to target the README/serverInfo
+    slug for fresh installs.
+    """
     server, entry = mcp_swap.resolve_repo_meta(fake_repo)
     assert server == "libtmux"
     assert entry == "libtmux-mcp"

From 3069f070ca6003ecc851fb6256008e27831ca03e Mon Sep 17 00:00:00 2001
From: Tony Narlock 
Date: Sat, 9 May 2026 07:49:40 -0500
Subject: [PATCH 2/5] =?UTF-8?q?docs(MIGRATION)=20add=20migration=20notes?=
 =?UTF-8?q?=20for=20libtmux=E2=86=92tmux=20slug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

why: PR #40 renames the recommended registration slug from `libtmux`
to `tmux` (matching `serverInfo.name`). Existing user installations
keep working, but users who want the new `mcp__tmux__*` tool prefix
need clear before/after instructions. Following the libtmux pattern
(~/work/python/libtmux/MIGRATION): a root MIGRATION file (no
extension) is the source of truth, included into the docs build via
docs/migration.md (added in the next commit).

what:
- New `MIGRATION` file at the repo root, no extension. Plain Markdown
  with MyST extensions so the future {include} from docs/migration.md
  renders cleanly under Sphinx.
- Welcome admonition with tracker link, mirroring libtmux's intro.
- Single section under "## libtmux-mcp 0.1.0a6 (unreleased)" for the
  slug rename. Before / After / What's unchanged subsections with
  4-space-indented shell examples (matches libtmux MIGRATION style).
- Confirms `claude mcp remove ` auto-detects scope (verified
  against `claude --version 2.1.138`), so migration commands work
  regardless of original registration scope.
---
 MIGRATION | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 MIGRATION

diff --git a/MIGRATION b/MIGRATION
new file mode 100644
index 00000000..86a4ad30
--- /dev/null
+++ b/MIGRATION
@@ -0,0 +1,66 @@
+# Migration notes
+
+Migration and deprecation notes for libtmux-mcp are here, see {ref}`history`
+for the full release log.
+
+```{admonition} Welcome on board! 👋
+1. 📌 For safety, **always** pin the package version in your install
+2. 📖 Check the migration notes _(You are here)_
+3. 📣 If a deprecation interrupted you - past, present, or future - voice your opinion on the [tracker].
+
+   We want to make libtmux-mcp fun, reliable, and useful for users.
+
+   API changes can be painful.
+
+   If we can do something to draw the sting, we'll do it. We're taking a balanced approach. That's why these notes are here!
+
+   (Please pin the package. 🙏)
+
+   [tracker]: https://github.com/tmux-python/libtmux-mcp/discussions
+```
+
+## libtmux-mcp 0.1.0a6 (unreleased)
+
+### Recommended registration slug: `libtmux` → `tmux`
+
+Earlier docs and install widgets recommended registering the server as
+`libtmux`. From 0.1.0a6 onward the recommended slug is `tmux`, matching
+the value of `serverInfo.name` returned in the MCP handshake and the
+`mcp__tmux__*` tool prefix that clients namespace tool calls under.
+
+**Existing installations continue to work.** The slug is a per-install
+user choice — your client looks up the server by whatever name you
+registered. Migration is optional; it only matters if you want the new
+`tmux` prefix on tool calls. Claude Code's `claude mcp remove `
+auto-detects the registration scope (verified against
+`claude --version 2.1.138`), so the commands below work whether you
+originally registered at `local`, `user`, or `project` scope.
+
+#### Before
+
+```console
+$ claude mcp add libtmux -- uvx libtmux-mcp
+```
+
+→ tools surface as `mcp__libtmux__list_panes`, `mcp__libtmux__send_keys`, …
+
+#### After
+
+```console
+$ claude mcp remove libtmux
+```
+
+```console
+$ claude mcp add tmux -- uvx libtmux-mcp
+```
+
+→ tools surface as `mcp__tmux__list_panes`, `mcp__tmux__send_keys`, …
+
+#### What's unchanged
+
+- PyPI package name: `libtmux-mcp`
+- Python module: `libtmux_mcp`
+- GitHub repository: 
+- Existing `mcp__libtmux__*` references in CLAUDE.md / AGENTS.md
+  templates and agent histories continue to work if you keep the
+  `libtmux` slug.

From a6d6aebe0737df01805aa71d74493c38208a899f Mon Sep 17 00:00:00 2001
From: Tony Narlock 
Date: Sat, 9 May 2026 07:51:50 -0500
Subject: [PATCH 3/5] docs(migration) add Sphinx wrapper for the root MIGRATION
 file

why: the root MIGRATION file is the source of truth, but it needs a
docs entry point so users can navigate to it from the docs sidebar.
Mirrors libtmux's two-file pattern (~/work/python/libtmux/docs/migration.md):
a thin MyST wrapper that {include}s the root file. The (migration)=
anchor is what other docs pages cross-reference to.

what:
- New `docs/migration.md` (5 lines): MyST anchor + ``{include}``
  directive pulling in `../MIGRATION`. No content of its own; the
  authoritative source is the root MIGRATION file.
- Sphinx warns "document isn't included in any toctree" until the
  next commit wires it in. Build still succeeds.
---
 docs/migration.md | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 docs/migration.md

diff --git a/docs/migration.md b/docs/migration.md
new file mode 100644
index 00000000..db686845
--- /dev/null
+++ b/docs/migration.md
@@ -0,0 +1,5 @@
+(migration)=
+
+```{include} ../MIGRATION
+
+```

From 525e3f1396e2697d4647e9c41073c4fe2e5bc5e1 Mon Sep 17 00:00:00 2001
From: Tony Narlock 
Date: Sat, 9 May 2026 07:53:53 -0500
Subject: [PATCH 4/5] docs(migration) wire toctree + replace clients note with
 link

why: Commit 2's docs/migration.md page is unreachable until it lives
in the docs sidebar nav. And the migration {note} I added earlier in
docs/clients.md duplicates content that now lives on the dedicated
migration page. Replace the inline admonition with a one-line
cross-reference so docs/clients.md stays focused on setup
instructions and migration content lives in one place.

what:
- docs/index.md: add `migration` to the "Project" caption toctree
  between `history` and the GitHub link, mirroring libtmux's
  placement (~/work/python/libtmux/docs/index.md). The Sphinx
  toc.not_included warning from Commit 2 clears.
- docs/clients.md: replace the 9-line {note} admonition with a
  one-line ``{ref}``-style cross-reference: "See {ref}`migration`
  for the recommended `tmux` registration slug (existing `libtmux`
  registrations keep working)." The migration anchor was added in
  Commit 2.
---
 docs/clients.md | 10 ++--------
 docs/index.md   |  1 +
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/docs/clients.md b/docs/clients.md
index 6c338cd1..e867a501 100644
--- a/docs/clients.md
+++ b/docs/clients.md
@@ -4,14 +4,8 @@
 
 Copy-pasteable configuration for every supported MCP client. If your client isn't listed, any tool supporting MCP stdio transport will work with the JSON config pattern.
 
-```{note}
-**Migrating from the `libtmux` slug.** Earlier versions of these docs
-used `claude mcp add libtmux …`; this page now uses `tmux` to match
-`serverInfo.name` and the `mcp__tmux__*` tool prefix. Existing
-`libtmux` registrations keep working — re-register only if you want
-the new slug. The package name (`libtmux-mcp`), Python module
-(`libtmux_mcp`), and GitHub repo are unchanged.
-```
+See {ref}`migration` for the recommended `tmux` registration slug
+(existing `libtmux` registrations keep working).
 
 ## Claude Code
 
diff --git a/docs/index.md b/docs/index.md
index cbc932fc..da14db8a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -139,5 +139,6 @@ glossary
 
 project/index
 history
+migration
 GitHub 
 ```

From 43a2832bca2a6cbfb04a04eba6220b77157ac5cb Mon Sep 17 00:00:00 2001
From: Tony Narlock 
Date: Sat, 9 May 2026 09:03:00 -0500
Subject: [PATCH 5/5] docs(CHANGES) note slug rename + migration page
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adds an unreleased "What's new" bullet covering the
libtmux→tmux registration slug recommendation across docs
and the new MIGRATION root file + docs/migration.md wrapper.
---
 CHANGES | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/CHANGES b/CHANGES
index 095b404f..36355b8a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -20,6 +20,13 @@ _Notes on upcoming releases will be added here_
   (Claude Code v2.1.121+). `serverInfo.name` is now `tmux`.
   Transmitted `instructions=` re-fits Claude Code's 2KB
   ceiling across all safety tiers. (#37)
+- Recommended registration slug `libtmux` → `tmux` across
+  {ref}`clients`, the install widget, and `AGENTS.md`
+  examples. Existing `libtmux` registrations keep working;
+  `mcp_swap.py` retains its `libtmux` default for backward
+  compatibility. New {ref}`migration` page (root `MIGRATION`
+  + `docs/migration.md` wrapper) documents the rename and
+  serves as the home for future migration notes. (#40)
 
 ### Documentation