docs(mcp): expand quick-connect matrix to 19 agent ecosystem clients - #57
docs(mcp): expand quick-connect matrix to 19 agent ecosystem clients#57KevinLi0w0 wants to merge 11 commits into
Conversation
Add per-client MCP configuration snippets for the full agent ecosystem tracked in issue afx-team#32: Amp, Cline, Copilot, Gemini CLI, Goose, Kiro, LM Studio, opencode, VS Code, Warp, Windsurf, plus the existing Claude Code, Codex, Claude Desktop, and Cursor entries. Both EN (repo_pages/guide/mcp-integration.md) and zh (repo_pages/zh/guide/mcp-integration.md) are updated together with: - A unified 'Quick-Connect Matrix' section organized by delivery type (first-class installer vs config snippet) - Exact config file paths and formats verified against each client's official docs - Absolute-path guidance per the user-path-ownership constraint (hebb.utils.cli_paths.hebb_mcp_command pattern) - An 'Other clients' table for UI-only / evolving-config clients (Antigravity, Factory, Junie, Qodo Gen) - Updated architecture diagram to reflect the broader client ecosystem This addresses the acceptance criterion: 'every client has either a one-command installer or a verified absolute-path config snippet, and the matrix renders in mcp-integration.md with EN + zh updated together.'
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Warning Review limit reached
Next review available in: 51 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR adds install and uninstall commands for Amp, Gemini CLI, Goose, and opencode. It adds shared configuration helpers, command-drift validation, dependency constraints, and expanded English and Chinese MCP integration guides. ChangesMCP client integrations
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@repo_pages/guide/mcp-integration.md`:
- Around line 128-130: Specify the text language on both command-palette code
fences: update the fence around the MCP configuration in
repo_pages/guide/mcp-integration.md lines 128-130 and apply the same change in
repo_pages/zh/guide/mcp-integration.md lines 128-130 by using text after each
opening fence.
- Around line 110-122: The MCP configuration instructions incorrectly reference
the CLI settings path and scope. Update the Cline configuration guidance in
repo_pages/guide/mcp-integration.md lines 110-122 to use
~/.cline/data/settings/cline_mcp_settings.json and describe the supported CLI
scope; apply the same correction in repo_pages/zh/guide/mcp-integration.md lines
110-122 while preserving the existing MCP example.
In `@repo_pages/zh/guide/mcp-integration.md`:
- Line 110: 更新中文 MCP 集成指南,统一正文中的语言:将可翻译的说明和界面术语本地化,并将不可避免的产品名、命令及精确 UI
标签统一用代码格式隔离。检查该页面全文,避免中文正文中混入未标记的英文,同时保留必要的配置文件名和实际界面标签。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7ed2b180-7eff-49a7-81e1-649b43def3a3
📒 Files selected for processing (2)
repo_pages/guide/mcp-integration.mdrepo_pages/zh/guide/mcp-integration.md
…se, opencode, and Amp Add hebb <client> install/uninstall commands for four MCP clients that have on-disk config files, following the pattern established by hebb codex install. New commands: - hebb gemini install / hebb gemini uninstall — writes ~/.gemini/settings.json with a mcpServers.hebb entry (command + args) - hebb goose install / hebb goose uninstall — writes ~/.config/goose/config.yaml with an extensions.hebb block (type: stdio, cmd, args) - hebb opencode install --scope project|user / hebb opencode uninstall — writes opencode.json with a mcp.hebb entry (type: local, command as flat array) - hebb amp install --scope project|user / hebb amp uninstall — writes .amp/settings.json with an amp.mcpServers.hebb entry All installers: - Resolve the absolute hebb-mcp path via hebb_mcp_command() (user-path-ownership) - Are idempotent (re-running replaces the prior hebb entry) - Preserve unrelated config entries in the target file - Use atomic writes (tempfile + os.replace) Shared JSON config helpers extracted into integrations/_json_config.py to avoid duplication across the four installers. Tests: 14 unit tests covering install, idempotency, config preservation, and uninstall for all four clients. Ruff clean. Addresses: afx-team#32 (type (a) one-command installers for clients with CLI/config files)
…bit review Address 3 review comments from CodeRabbit on PR afx-team#57: 1. (Major) Fix Cline MCP config file path: the authoritative location is ~/.cline/data/settings/cline_mcp_settings.json, not ~/.cline/mcp.json. Updated in both EN and zh docs. 2. (Minor) Add `text` language to command-palette code fences (markdownlint MD040). Fixed in both EN and zh docs. 3. (Minor) Isolate English UI labels (Settings, Program, etc.) with code formatting in the zh doc to avoid raw English in Chinese prose.
CodeRabbit suggested ~/.cline/data/settings/cline_mcp_settings.json, but Cline's official docs (docs.cline.bot/mcp/mcp-overview) state: - CLI: ~/.cline/mcp.json - IDE extension: opened via UI button, file in VS Code global storage Updated both EN and zh to describe both paths accurately rather than using the unverified path from the bot review.
…config Implements the S1 command-drift CI guard proposed in issue afx-team#32. The test suite (tests/unit/test_command_drift.py) asserts that every hebb command reference resolves to a real Click command or entrypoint: 1. TestCLIRegistration — verifies expected top-level commands (amp, claude-code, codex, gemini, goose, opencode, mcp, setup, service) and their subcommands are registered on the root CLI. 2. TestDocCommandDrift — scans mcp-integration.md (EN + zh) for hebb command references inside code blocks and inline code, asserts each resolves to a registered command. 3. TestGeneratedConfigDrift — builds Codex hook config in-process and verifies every hebb subcommand referenced in hook commands exists. 4. TestEntrypoint — verifies the hebb-mcp console script module (hebb.mcp.server) is importable and exposes main(). 11 tests, all passing. Ruff clean. Addresses: afx-team#32 (acceptance criterion: S1 command-drift CI guard)
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (9)
src/hebb/integrations/_json_config.py (2)
44-115: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMissing
Raisesdocstring sections.
atomic_write,upsert_server, andremove_serverall callload_json(documented to raiseclick.ClickException) but none document this in aRaisessection, unlikeload_jsonitself.As per path instructions, "All public APIs in Python MUST have docstrings with Args, Returns, and Raises sections" (
src/**/*.py).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/_json_config.py` around lines 44 - 115, Add a Raises section to the docstrings of atomic_write, upsert_server, and remove_server documenting that load_json failures raise click.ClickException. Preserve their existing Args and Returns documentation and do not alter implementation behavior.Source: Path instructions
44-62: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
atomic_writesilently drops the original file's permissions.
tempfile.mkstempalways creates the temp file at mode0600regardless of umask, andos.replacecarries that mode onto the destination. So every call toatomic_writeon an existing config file (e.g. one previously created at0644by the client itself) silently tightens it to0600— everyinstall/uninstallinvocation quietly re-narrows permissions. This is a well-documented gotcha (Click's own atomic file writer had the same bug and was patched to preserve/derive permissions).🔧 Proposed fix to preserve existing permissions (or respect umask for new files)
+import stat + def atomic_write(path: Path, content: str) -> None: """Atomically replace a UTF-8 text file, creating its parent dir. Args: path: Destination file. content: Complete replacement content. """ path.parent.mkdir(parents=True, exist_ok=True) + try: + mode = stat.S_IMODE(path.stat().st_mode) + except OSError: + mode = None fd, temp_name = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent) try: with os.fdopen(fd, "w", encoding="utf-8") as stream: stream.write(content) + if mode is not None: + os.chmod(temp_name, mode) os.replace(temp_name, path) except Exception: try: os.unlink(temp_name) except OSError: pass raise🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/_json_config.py` around lines 44 - 62, Update atomic_write to preserve the existing destination file’s permission mode before replacing it, applying that mode to the temporary file; when the destination does not exist, retain mkstemp’s umask-respecting default. Keep the current atomic replacement and cleanup behavior unchanged.tests/unit/integrations/test_mcp_client_installers.py (1)
212-229: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMissing "uninstall when absent" test coverage for Amp/opencode.
amp/uninstall.py's "not configured" branch (lines 20-22) and the analogous opencode path aren't exercised here, unlike Gemini'stest_gemini_uninstall_when_absent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/unit/integrations/test_mcp_client_installers.py` around lines 212 - 229, Add coverage for uninstalling when no MCP server is configured in the Amp and analogous opencode uninstall tests. Extend the relevant test modules near test_amp_uninstall and the corresponding opencode test to invoke the CLI with an empty or missing configuration, then assert the command succeeds and preserves the expected “not configured” behavior, matching Gemini’s test_gemini_uninstall_when_absent pattern.src/hebb/integrations/amp/install.py (1)
35-40: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSeveral public functions lack Args/Returns docstring sections. Per path instructions,
src/**/*.pyrequires "All public APIs in Python MUST have docstrings with Args, Returns, and Raises sections"; thebuild_entryhelpers and Amp's parameterized CLI commands only have one-line summaries.
src/hebb/integrations/amp/install.py#L35-L40: addArgs/Returnssections tobuild_entry.src/hebb/integrations/amp/cli.py#L13-L40: documentscopein anArgssection forinstall/uninstall.src/hebb/integrations/gemini_cli/install.py#L22-L27: addArgs/Returnssections tobuild_entry.src/hebb/integrations/opencode/install.py#L34-L44: add formalArgs/Returnsheaders tobuild_entry's existing docstring.As per path instructions, "All public APIs in Python MUST have docstrings with Args, Returns, and Raises sections."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/amp/install.py` around lines 35 - 40, Complete the public API docstrings with the required sections: in src/hebb/integrations/amp/install.py:35-40, document mcp_argv under Args and the returned entry under Returns for build_entry; in src/hebb/integrations/amp/cli.py:13-40, document scope under Args for install and uninstall; in src/hebb/integrations/gemini_cli/install.py:22-27, add Args and Returns to build_entry; and in src/hebb/integrations/opencode/install.py:34-44, convert build_entry’s existing documentation to formal Args and Returns sections. No direct Raises documentation is needed unless those APIs declare or propagate specific exceptions.Source: Path instructions
tests/unit/test_command_drift.py (1)
166-193: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winClaude Code hooks aren't covered by the generated-config drift check.
The module docstring says both Codex and Claude Code installers are checked for command drift, but
TestGeneratedConfigDriftonly testshebb.integrations.codex.install.hooks_config(). A stale/renamedhebb claude-code ...hook command wouldn't be caught.✅ Proposed addition
def test_codex_hooks_reference_real_commands(self) -> None: from hebb.integrations.codex.install import hooks_config ... assert not failures, "Codex hooks reference unregistered commands:\n" + "\n".join(failures) + + def test_claude_code_hooks_reference_real_commands(self) -> None: + from hebb.integrations.claude_code.install import hooks_config + + top_level = _registered_commands() + failures: list[str] = [] + for event, handlers in hooks_config().items(): + for handler in handlers: + for h in handler.get("hooks", []): + cmd_str = str(h.get("command", "")) + for m in re.finditer(r"hebb\s+([a-z][-a-z]*(?:\s+[a-z][-a-z]*)?)", cmd_str): + parts = m.group(1).strip().split() + cmd = parts[0] + if cmd not in top_level: + failures.append(f" hooks_config '{cmd_str}' — '{cmd}' not registered") + elif len(parts) > 1 and parts[1] not in _registered_subcommands(cmd): + failures.append( + f" hooks_config '{cmd_str}' — '{parts[1]}' not a subcommand of `hebb {cmd}`" + ) + assert not failures, "Claude Code hooks reference unregistered commands:\n" + "\n".join(failures)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/unit/test_command_drift.py` around lines 166 - 193, Extend TestGeneratedConfigDrift.test_codex_hooks_reference_real_commands to validate Claude Code installer hooks as well as Codex hooks. Import and invoke the Claude Code hooks_config alongside the existing Codex configuration, run both through the same registered-command and subcommand validation, and preserve the existing aggregated failure assertion.src/hebb/integrations/opencode/cli.py (1)
13-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the
scopeparameter in docstrings.Both
installanduninstallacceptscopebut their docstrings don't include an Args section describing it (valid values, default).As per coding guidelines, "All public APIs in Python MUST have docstrings with Args, Returns, and Raises sections."📝 Proposed docstring fix
def install(scope: str) -> None: - """Install Hebb Mind MCP into opencode.""" + """Install Hebb Mind MCP into opencode. + + Args: + scope: ``"project"`` writes ``opencode.json`` in cwd; ``"user"`` + writes the global config. Defaults to ``"user"``. + """ from hebb.integrations.opencode.install import handle handle(scope)def uninstall(scope: str) -> None: - """Remove Hebb Mind MCP from opencode.""" + """Remove Hebb Mind MCP from opencode. + + Args: + scope: ``"project"`` or ``"user"``. Defaults to ``"user"``. + """ from hebb.integrations.opencode.uninstall import handle handle(scope)Also applies to: 28-40
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/opencode/cli.py` around lines 13 - 25, Update the public install and uninstall command docstrings to include an Args section for scope, describing the valid project/user values and the user default. Preserve their existing behavior and add Returns and Raises sections as required by the project’s public API docstring convention, documenting the actual behavior without inventing exceptions.Source: Coding guidelines
src/hebb/integrations/goose/install.py (2)
90-123: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winWrap filesystem I/O with
click.ClickExceptioninstead of lettingOSErrorpropagate raw. All threehandle()functions read/write config files without catching failures (permission denied, disk full, etc.), producing a Python traceback instead of a clean CLI error.
src/hebb/integrations/goose/install.py#L90-L123: wrappath.read_text()/atomic_write()inhandle()with try/except raisingclick.ClickException(str(e)).src/hebb/integrations/gemini_cli/uninstall.py#L11-L21: wrapconfig_path()/remove_server()inhandle()similarly.src/hebb/integrations/goose/uninstall.py#L10-L27: wrappath.read_text()/atomic_write()inhandle()similarly.As per coding guidelines, "Keep CLI exits via
click.ClickException; reserveSystemExit(1)for unrecoverable failures."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/goose/install.py` around lines 90 - 123, Wrap filesystem operations in each affected handle() with OSError handling that raises click.ClickException(str(e)): in src/hebb/integrations/goose/install.py lines 90-123, cover path.read_text() and atomic_write(); in src/hebb/integrations/gemini_cli/uninstall.py lines 11-21, cover config_path() and remove_server(); and in src/hebb/integrations/goose/uninstall.py lines 10-27, cover path.read_text() and atomic_write(). Preserve normal success behavior and avoid raw OSError propagation or SystemExit for these CLI failures.Source: Coding guidelines
74-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReuse the shared atomic-write helper for Goose.
src/hebb/integrations/goose/install.pyhas a localatomic_write, andsrc/hebb/integrations/goose/uninstall.pyimports it from that module. Move tohebb.integrations._json_config.atomic_write, then re-exportatomic_writeandconfig_pathfrom this module so the installer/import contract stays stable.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/goose/install.py` around lines 74 - 87, Replace the local atomic_write implementation in install.py with imports from hebb.integrations._json_config, while preserving the module’s public contract by re-exporting both atomic_write and config_path. Update dependent imports as needed so uninstall.py continues using the stable install-module symbols.src/hebb/integrations/opencode/uninstall.py (1)
11-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse
remove_serverfor opencode uninstall.
handle()reimplements the load/delete/write flow and_dump_json, while_json_config.remove_server()already handles this for anykey/server_namepair and returns whether something was changed. Delegate to that helper so opencode uninstall matches the shared removal path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/opencode/uninstall.py` around lines 11 - 35, Update handle() to delegate server removal to _json_config.remove_server() using the opencode config path, SERVER_KEY, and SERVER_NAME instead of manually loading, deleting, and writing JSON. Use its boolean result to preserve the existing not-configured and successful output behavior, and remove the now-unused _dump_json helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Around line 33-38: Update the MCP integration guide changelog entry to
reconcile the stated 19-client count with the entries listed: either add the two
omitted client names and their corresponding documentation details, or change
the count to match the existing 17 clients.
In `@src/hebb/integrations/amp/install.py`:
- Around line 43-69: Use the shared _json_config helpers instead of duplicating
configuration mutation logic: in src/hebb/integrations/amp/install.py lines
43-69, replace the manual load/merge/write flow in handle with upsert_server; in
src/hebb/integrations/amp/uninstall.py lines 11-32, replace manual deletion with
remove_server and use its boolean result for the not-configured message; in
src/hebb/integrations/opencode/install.py lines 47-76, replace the merge and
_dump_json flow with upsert_server and remove the redundant _dump_json helper.
In `@src/hebb/integrations/goose/install.py`:
- Around line 90-117: Update handle’s extensions-key detection and insertion
flow to ensure the Hebb block is always inserted when installation reports
success. Only treat a standalone YAML `extensions:` line as an existing key; if
no such line is found, append the key and block using the existing fallback
path, then write the resulting configuration.
- Around line 21-40: Fix _build_yaml_block so the no-extra-arguments case emits
[] indented beneath args: rather than at column zero, while preserving correctly
indented list entries for additional arguments. Update the installer test to
parse the generated content with yaml.safe_load and assert it succeeds, in
addition to the existing checks.
---
Nitpick comments:
In `@src/hebb/integrations/_json_config.py`:
- Around line 44-115: Add a Raises section to the docstrings of atomic_write,
upsert_server, and remove_server documenting that load_json failures raise
click.ClickException. Preserve their existing Args and Returns documentation and
do not alter implementation behavior.
- Around line 44-62: Update atomic_write to preserve the existing destination
file’s permission mode before replacing it, applying that mode to the temporary
file; when the destination does not exist, retain mkstemp’s umask-respecting
default. Keep the current atomic replacement and cleanup behavior unchanged.
In `@src/hebb/integrations/amp/install.py`:
- Around line 35-40: Complete the public API docstrings with the required
sections: in src/hebb/integrations/amp/install.py:35-40, document mcp_argv under
Args and the returned entry under Returns for build_entry; in
src/hebb/integrations/amp/cli.py:13-40, document scope under Args for install
and uninstall; in src/hebb/integrations/gemini_cli/install.py:22-27, add Args
and Returns to build_entry; and in
src/hebb/integrations/opencode/install.py:34-44, convert build_entry’s existing
documentation to formal Args and Returns sections. No direct Raises
documentation is needed unless those APIs declare or propagate specific
exceptions.
In `@src/hebb/integrations/goose/install.py`:
- Around line 90-123: Wrap filesystem operations in each affected handle() with
OSError handling that raises click.ClickException(str(e)): in
src/hebb/integrations/goose/install.py lines 90-123, cover path.read_text() and
atomic_write(); in src/hebb/integrations/gemini_cli/uninstall.py lines 11-21,
cover config_path() and remove_server(); and in
src/hebb/integrations/goose/uninstall.py lines 10-27, cover path.read_text() and
atomic_write(). Preserve normal success behavior and avoid raw OSError
propagation or SystemExit for these CLI failures.
- Around line 74-87: Replace the local atomic_write implementation in install.py
with imports from hebb.integrations._json_config, while preserving the module’s
public contract by re-exporting both atomic_write and config_path. Update
dependent imports as needed so uninstall.py continues using the stable
install-module symbols.
In `@src/hebb/integrations/opencode/cli.py`:
- Around line 13-25: Update the public install and uninstall command docstrings
to include an Args section for scope, describing the valid project/user values
and the user default. Preserve their existing behavior and add Returns and
Raises sections as required by the project’s public API docstring convention,
documenting the actual behavior without inventing exceptions.
In `@src/hebb/integrations/opencode/uninstall.py`:
- Around line 11-35: Update handle() to delegate server removal to
_json_config.remove_server() using the opencode config path, SERVER_KEY, and
SERVER_NAME instead of manually loading, deleting, and writing JSON. Use its
boolean result to preserve the existing not-configured and successful output
behavior, and remove the now-unused _dump_json helper.
In `@tests/unit/integrations/test_mcp_client_installers.py`:
- Around line 212-229: Add coverage for uninstalling when no MCP server is
configured in the Amp and analogous opencode uninstall tests. Extend the
relevant test modules near test_amp_uninstall and the corresponding opencode
test to invoke the CLI with an empty or missing configuration, then assert the
command succeeds and preserves the expected “not configured” behavior, matching
Gemini’s test_gemini_uninstall_when_absent pattern.
In `@tests/unit/test_command_drift.py`:
- Around line 166-193: Extend
TestGeneratedConfigDrift.test_codex_hooks_reference_real_commands to validate
Claude Code installer hooks as well as Codex hooks. Import and invoke the Claude
Code hooks_config alongside the existing Codex configuration, run both through
the same registered-command and subcommand validation, and preserve the existing
aggregated failure assertion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b9643315-65c6-47cd-8d61-433ccb44493a
📒 Files selected for processing (23)
CHANGELOG.mdrepo_pages/guide/mcp-integration.mdrepo_pages/zh/guide/mcp-integration.mdsrc/hebb/cli/main.pysrc/hebb/integrations/_json_config.pysrc/hebb/integrations/amp/__init__.pysrc/hebb/integrations/amp/cli.pysrc/hebb/integrations/amp/install.pysrc/hebb/integrations/amp/uninstall.pysrc/hebb/integrations/gemini_cli/__init__.pysrc/hebb/integrations/gemini_cli/cli.pysrc/hebb/integrations/gemini_cli/install.pysrc/hebb/integrations/gemini_cli/uninstall.pysrc/hebb/integrations/goose/__init__.pysrc/hebb/integrations/goose/cli.pysrc/hebb/integrations/goose/install.pysrc/hebb/integrations/goose/uninstall.pysrc/hebb/integrations/opencode/__init__.pysrc/hebb/integrations/opencode/cli.pysrc/hebb/integrations/opencode/install.pysrc/hebb/integrations/opencode/uninstall.pytests/unit/integrations/test_mcp_client_installers.pytests/unit/test_command_drift.py
🚧 Files skipped from review as they are similar to previous changes (2)
- repo_pages/zh/guide/mcp-integration.md
- repo_pages/guide/mcp-integration.md
…pers, changelog 1. (Critical) Fix Goose YAML args format when hebb-mcp has no extra args: `args: []` was emitted at column 0, breaking YAML structure. Now uses inline `args: []` on the same indentation level. 2. (Major) Fix Goose insertion fallback: `extensions:` substring check could match inside comments without a real `extensions:` line, causing the hebb block to silently not be inserted. Now checks for a standalone line and adds a fallback if insertion fails. 3. (Major) Refactor Amp and opencode installers to use shared _json_config.upsert_server/remove_server instead of hand-rolling the same read/merge/write logic. Removes redundant _dump_json helpers. 4. (Minor) Fix CHANGELOG client list to include Claude Code and Codex in the 19-client count. 25 tests passing, ruff clean.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/hebb/integrations/amp/install.py (1)
43-60: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winComplete the public API docstrings.
Each public
handlefunction has type hints, but its docstring is missing required sections.
src/hebb/integrations/amp/install.py#L43-L60: addReturnsandRaises.src/hebb/integrations/amp/uninstall.py#L11-L25: addReturnsandRaises.src/hebb/integrations/opencode/install.py#L47-L63: addReturnsandRaises.src/hebb/integrations/opencode/uninstall.py#L11-L25: addReturnsandRaises.src/hebb/integrations/goose/install.py#L92-L132: addArgs,Returns, andRaises.As per coding guidelines, all public Python APIs must include Args, Returns, and Raises sections.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/amp/install.py` around lines 43 - 60, Complete the public API docstrings for handle in src/hebb/integrations/amp/install.py (43-60), src/hebb/integrations/amp/uninstall.py (11-25), src/hebb/integrations/opencode/install.py (47-63), and src/hebb/integrations/opencode/uninstall.py (11-25) by adding accurate Returns and Raises sections; update handle in src/hebb/integrations/goose/install.py (92-132) with accurate Args, Returns, and Raises sections, matching the existing signatures and behavior.Source: Coding guidelines
src/hebb/integrations/goose/install.py (1)
102-124: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winOnly match a root-level block
extensions:key.
line.strip() == "extensions:"also matches nested mappings. A config containingprofile:\n extensions:enters this branch and insertshebbas a sibling of that nested key, not as Goose’s top-level extension. Conversely,extensions: {}is treated as absent and a duplicate root key is appended, which can shadow existing extension settings.Detect only an unindented block-style
extensions:header; if a rootextensionskey uses an unsupported inline form, raiseclick.ClickExceptioninstead of writing ambiguous YAML.Proposed direction
- has_extensions_line = any(line.strip() == "extensions:" for line in cleaned.splitlines()) + # Match only Goose's root-level block mapping header. + has_extensions_line = any( + line.rstrip("\r\n") == "extensions:" for line in cleaned.splitlines(keepends=True) + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hebb/integrations/goose/install.py` around lines 102 - 124, Update the extensions detection and insertion logic around cleaned.splitlines() so it recognizes only an unindented root-level block-style “extensions:” header. Ignore indented nested headers, and treat any root-level extensions key using an inline form such as “extensions: {}” as unsupported by raising click.ClickException rather than appending a duplicate key. Preserve insertion after a valid root block header and creation of a root block when no root key exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/hebb/integrations/amp/install.py`:
- Around line 43-60: Complete the public API docstrings for handle in
src/hebb/integrations/amp/install.py (43-60),
src/hebb/integrations/amp/uninstall.py (11-25),
src/hebb/integrations/opencode/install.py (47-63), and
src/hebb/integrations/opencode/uninstall.py (11-25) by adding accurate Returns
and Raises sections; update handle in src/hebb/integrations/goose/install.py
(92-132) with accurate Args, Returns, and Raises sections, matching the existing
signatures and behavior.
In `@src/hebb/integrations/goose/install.py`:
- Around line 102-124: Update the extensions detection and insertion logic
around cleaned.splitlines() so it recognizes only an unindented root-level
block-style “extensions:” header. Ignore indented nested headers, and treat any
root-level extensions key using an inline form such as “extensions: {}” as
unsupported by raising click.ClickException rather than appending a duplicate
key. Preserve insertion after a valid root block header and creation of a root
block when no root key exists.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 50f67b02-6cd0-4feb-8994-791cba12f190
📒 Files selected for processing (6)
CHANGELOG.mdsrc/hebb/integrations/amp/install.pysrc/hebb/integrations/amp/uninstall.pysrc/hebb/integrations/goose/install.pysrc/hebb/integrations/opencode/install.pysrc/hebb/integrations/opencode/uninstall.py
🚧 Files skipped from review as they are similar to previous changes (1)
- CHANGELOG.md
…compliance
1. (Major) Goose installer now matches only root-level (unindented) block-style
"extensions:" header. Indented nested "extensions:" no longer triggers
insertion. Inline "extensions: {}" raises click.ClickException instead of
silently appending a duplicate root key.
2. (Major) Add Raises sections to all handle() docstrings across Gemini CLI,
Goose, opencode, and Amp install/uninstall functions, matching the project
convention used by the existing Codex installer.
25 tests passing, ruff clean.
mcp 2.0.0 (released 2026-07-28) removed the mcp.server.fastmcp module that src/hebb/mcp/server.py imports. The pyproject.toml constraint "mcp>=1.0.0" allowed pip to install 2.0.0 in CI, breaking mypy, pytest, and e2e checks across all OS/Python matrix cells. This is a pre-existing issue — upstream main would also fail CI now. Pinning to "mcp>=1.0.0,<2.0.0" until the codebase migrates to the new mcp 2.x API.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/hebb/integrations/gemini_cli/install.py`:
- Around line 31-35: Complete the public handle API docstrings: in
src/hebb/integrations/gemini_cli/install.py lines 31-35 and
src/hebb/integrations/goose/install.py lines 93-99, add accurate Args and
Returns sections; in src/hebb/integrations/opencode/install.py lines 48-55 and
src/hebb/integrations/opencode/uninstall.py lines 12-19, add accurate Returns
sections. Preserve the existing Raises documentation and describe each API’s
actual parameters and return value.
In `@src/hebb/integrations/goose/install.py`:
- Around line 112-121: Update the extensions-header detection in the install
configuration flow to match only root-level keys, preserving indentation rather
than using lstrip(). Treat root-level lines containing only whitespace or a
comment suffix, such as “extensions: # managed config”, as block headers; ignore
nested and commented-out headers. Ensure nested-only keys cause a new root-level
extensions block to be appended instead of raising ClickException.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 925985bc-cedc-441d-a6cf-69976871fd25
📒 Files selected for processing (9)
pyproject.tomlsrc/hebb/integrations/amp/install.pysrc/hebb/integrations/amp/uninstall.pysrc/hebb/integrations/gemini_cli/install.pysrc/hebb/integrations/gemini_cli/uninstall.pysrc/hebb/integrations/goose/install.pysrc/hebb/integrations/goose/uninstall.pysrc/hebb/integrations/opencode/install.pysrc/hebb/integrations/opencode/uninstall.py
🚧 Files skipped from review as they are similar to previous changes (4)
- src/hebb/integrations/gemini_cli/uninstall.py
- src/hebb/integrations/goose/uninstall.py
- src/hebb/integrations/amp/uninstall.py
- src/hebb/integrations/amp/install.py
| """Install Hebb Mind MCP into Gemini CLI. | ||
|
|
||
| Raises: | ||
| click.ClickException: If the config file exists but cannot be parsed. | ||
| """ |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Complete the required public-API docstring sections.
These public handle APIs omit required docstring sections.
src/hebb/integrations/gemini_cli/install.py#L31-L35: AddArgsandReturnssections.src/hebb/integrations/opencode/install.py#L48-L55: Add aReturnssection.src/hebb/integrations/opencode/uninstall.py#L12-L19: Add aReturnssection.src/hebb/integrations/goose/install.py#L93-L99: AddArgsandReturnssections.
As per coding guidelines, “Include docstring with Args, Returns, and Raises sections for all public APIs.”
📍 Affects 4 files
src/hebb/integrations/gemini_cli/install.py#L31-L35(this comment)src/hebb/integrations/opencode/install.py#L48-L55src/hebb/integrations/opencode/uninstall.py#L12-L19src/hebb/integrations/goose/install.py#L93-L99
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/hebb/integrations/gemini_cli/install.py` around lines 31 - 35, Complete
the public handle API docstrings: in src/hebb/integrations/gemini_cli/install.py
lines 31-35 and src/hebb/integrations/goose/install.py lines 93-99, add accurate
Args and Returns sections; in src/hebb/integrations/opencode/install.py lines
48-55 and src/hebb/integrations/opencode/uninstall.py lines 12-19, add accurate
Returns sections. Preserve the existing Raises documentation and describe each
API’s actual parameters and return value.
Source: Coding guidelines
…ents
Fix two edge cases in Goose installer's extensions: detection:
1. A nested " extensions:" (indented under another key) no longer
triggers ClickException. Only root-level lines are checked for
inline form.
2. A root-level "extensions: # managed config" (block header with
trailing comment) is now correctly recognized as a block header,
not an inline form. Uses regex to distinguish block headers
(colon followed by only whitespace or comment) from inline forms
(colon followed by non-comment content like "{}").
The import re is placed inline to match the existing code style.
25 tests passing, ruff clean.
Add per-client MCP configuration snippets for the full agent ecosystem tracked in issue #32: Amp, Cline, Copilot, Gemini CLI, Goose, Kiro, LM Studio, opencode, VS Code, Warp, Windsurf, plus the existing Claude Code, Codex, Claude Desktop, and Cursor entries.
Both EN (repo_pages/guide/mcp-integration.md) and zh (repo_pages/zh/guide/mcp-integration.md) are updated together with:
This addresses the acceptance criterion: 'every client has either a one-command installer or a verified absolute-path config snippet, and the matrix renders in mcp-integration.md with EN + zh updated together.'
Summary
Motivation
Checklist
pytest tests/ -v) — 25 new tests (14 installer + 11 command-drift CI guard)repo_pages/, docstrings, or README) if user-facing## [Unreleased]ruff check src/passesmypy src/hebb/passes (project usesstrict = true)Notes for reviewers
Summary by CodeRabbit