Summary
iai-mcp capture-hooks install rewrites ~/.claude.json and ~/Library/Application Support/Claude/claude_desktop_config.json so that the iai-mcp MCP server is launched via the wrapper shipped inside the wheel:
/Users/<user>/<env>/.venv/lib/python3.11/site-packages/iai_mcp/_wrapper/index.js
That directory ships the wrapper JS files but no package.json and no node_modules/. As soon as Claude Desktop or Claude Code tries to spawn it, Node fails with:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk' imported from
.../site-packages/iai_mcp/_wrapper/index.js
and the MCP entry shows up as failed in the Claude Desktop developer panel.
Repro
- Clone the repo, set up the venv,
pip install . (so the wheel is installed into site-packages with the bundled _wrapper/ JS but no node deps).
- Run
iai-mcp capture-hooks install.
- Restart Claude Desktop.
- Open Settings → Developer → MCP. The
iai-mcp entry is failed; the log shows ERR_MODULE_NOT_FOUND: @modelcontextprotocol/sdk.
Why it works on dev installs that build the wrapper separately
In a dev layout, the actually-runnable wrapper lives at mcp-wrapper/dist/index.js next to its node_modules/ (after npm install && npm run build in mcp-wrapper/). The pre-v1.2.0 Claude configs on at least this machine pointed there and worked. The new capture-hooks install replaces that path with the in-wheel one and breaks startup.
Affected versions
Observed on v1.2.0 (latest at the time of writing). Did not check whether the same rewrite happened in v1.1.x — happy to confirm if helpful.
Expected behaviour
Either:
- ship the wrapper's npm dependencies inside the wheel (so the in-wheel
_wrapper/index.js is genuinely runnable as-is), or
- have
capture-hooks install detect a usable mcp-wrapper/dist/index.js next to the venv root and prefer that path, or
- document that
capture-hooks install is intended only for self-contained installs and skip the MCP config rewrite when the in-wheel wrapper has no node_modules/.
Local workaround
Repoint mcpServers.iai-mcp.args in both ~/.claude.json and ~/Library/Application Support/Claude/claude_desktop_config.json to <repo>/mcp-wrapper/dist/index.js, then restart Claude.
Environment
- macOS arm64, Node 26.0.0
- Python 3.11, iai-mcp 1.2.0, installed via
pip install --upgrade --no-deps . against the v1.2.0 tag
Summary
iai-mcp capture-hooks installrewrites~/.claude.jsonand~/Library/Application Support/Claude/claude_desktop_config.jsonso that theiai-mcpMCP server is launched via the wrapper shipped inside the wheel:That directory ships the wrapper JS files but no
package.jsonand nonode_modules/. As soon as Claude Desktop or Claude Code tries to spawn it, Node fails with:and the MCP entry shows up as
failedin the Claude Desktop developer panel.Repro
pip install .(so the wheel is installed into site-packages with the bundled_wrapper/JS but no node deps).iai-mcp capture-hooks install.iai-mcpentry isfailed; the log showsERR_MODULE_NOT_FOUND: @modelcontextprotocol/sdk.Why it works on dev installs that build the wrapper separately
In a dev layout, the actually-runnable wrapper lives at
mcp-wrapper/dist/index.jsnext to itsnode_modules/(afternpm install && npm run buildinmcp-wrapper/). The pre-v1.2.0 Claude configs on at least this machine pointed there and worked. The newcapture-hooks installreplaces that path with the in-wheel one and breaks startup.Affected versions
Observed on v1.2.0 (latest at the time of writing). Did not check whether the same rewrite happened in v1.1.x — happy to confirm if helpful.
Expected behaviour
Either:
_wrapper/index.jsis genuinely runnable as-is), orcapture-hooks installdetect a usablemcp-wrapper/dist/index.jsnext to the venv root and prefer that path, orcapture-hooks installis intended only for self-contained installs and skip the MCP config rewrite when the in-wheel wrapper has nonode_modules/.Local workaround
Repoint
mcpServers.iai-mcp.argsin both~/.claude.jsonand~/Library/Application Support/Claude/claude_desktop_config.jsonto<repo>/mcp-wrapper/dist/index.js, then restart Claude.Environment
pip install --upgrade --no-deps .against the v1.2.0 tag