From daf1d824c05325088f91ae9d2dace4d9da3a7c83 Mon Sep 17 00:00:00 2001 From: AusafMo Date: Sun, 2 Aug 2026 15:08:40 +0530 Subject: [PATCH] fix(mcp): actionable error when the mcp extra is missing + document it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cfg-mcp is commonly launched by an MCP client (e.g. a one-click install deeplink) against a cfgit installed without the [mcp] extra — a plain 'pipx install cfgit' or 'pip install cfgit'. It then dies with 'install cfgit[mcp]', which is the WRONG fix for a pipx install (pip won't touch the pipx venv), so the client just shows a failed connection. Detect a pipx venv and lead with 'pipx inject cfgit mcp>=1.0,<2'; otherwise show 'pip install cfgit[mcp]'. Both note that the extra pins mcp<2. Add a README note to the MCP server section covering the extra and the deeplink footgun. --- README.md | 13 +++++++++++++ src/cfg/mcp/server.py | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2669f2..5a78c1a 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,19 @@ Run the MCP server: cfg-mcp ``` +`cfg-mcp` requires the `mcp` extra. If you installed cfgit without it (a plain +`pip install cfgit` / `pipx install cfgit`), `cfg-mcp` exits with +`ModuleNotFoundError` — which is what an MCP client (or a one-click install +deeplink) will surface as a failed connection. Install the extra: + +```bash +pip install 'cfgit[mcp]' # pip / venv +pipx inject cfgit 'mcp>=1.0,<2' # if cfgit was installed via pipx +``` + +The extra currently pins `mcp>=1.0,<2` — the cfgit MCP server targets the mcp 1.x +`FastMCP` API and is not yet ported to mcp 2.0. + ## Record syntax Records are addressed as: diff --git a/src/cfg/mcp/server.py b/src/cfg/mcp/server.py index 9c06e9d..afe7fff 100644 --- a/src/cfg/mcp/server.py +++ b/src/cfg/mcp/server.py @@ -14,9 +14,28 @@ FastMCP = None # type: ignore[assignment] +def _mcp_missing_message() -> str: + """Actionable install hint. `cfg-mcp` is commonly launched by an MCP client (e.g. via a + one-click deeplink) against a cfgit that was installed WITHOUT the mcp extra. For a pipx + install, `pip install cfgit[mcp]` is the wrong fix (it won't touch the pipx venv), so lead + with `pipx inject` when we detect we're running from one.""" + import sys + + base = ( + "The cfgit MCP server needs the 'mcp' package, which is not installed in this " + "environment. cfgit was installed without the [mcp] extra." + ) + if "/pipx/venvs/" in sys.prefix or "/pipx/venvs/" in sys.executable: + return ( + f"{base}\nFix (pipx): pipx inject cfgit 'mcp>=1.0,<2'\n" + "or reinstall with the extra: pipx install 'cfgit[mcp]' --force" + ) + return f"{base}\nFix: pip install 'cfgit[mcp]' (mcp 2.0 is not yet supported; the extra pins mcp<2)" + + def _mcp() -> Any: if FastMCP is None: - raise ModuleNotFoundError("install cfgit[mcp] to run the cfgit MCP server") + raise ModuleNotFoundError(_mcp_missing_message()) return FastMCP("cfgit")