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/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 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. 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..e867a501 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -4,13 +4,16 @@ 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. +See {ref}`migration` for the recommended `tmux` registration slug +(existing `libtmux` registrations keep working). + ## 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 +21,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 +35,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 +51,7 @@ With [uv](https://docs.astral.sh/uv/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "uvx", "args": ["libtmux-mcp"] } @@ -63,7 +66,7 @@ With [pipx](https://pipx.pypa.io/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "pipx", "args": ["run", "libtmux-mcp"] } @@ -84,7 +87,7 @@ Then use this config: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "libtmux-mcp" } } @@ -98,7 +101,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 +109,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 +123,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 +133,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 +146,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 +154,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 +168,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 +184,7 @@ With [uv](https://docs.astral.sh/uv/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "uvx", "args": ["libtmux-mcp"] } @@ -196,7 +199,7 @@ With [pipx](https://pipx.pypa.io/) installed: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "pipx", "args": ["run", "libtmux-mcp"] } @@ -217,7 +220,7 @@ Then use this config: ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "libtmux-mcp" } } @@ -252,7 +255,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 +266,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 +276,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 +286,7 @@ $ gemini mcp add \ ```json { "mcpServers": { - "libtmux": { + "tmux": { "command": "uv", "args": [ "--directory", "~/work/python/libtmux-mcp", 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 ``` 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 + +``` 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"