Skip to content

Conversation

@jhaynie
Copy link
Member

@jhaynie jhaynie commented Jun 11, 2025

Summary by CodeRabbit

  • New Features

    • Added distinct support for AMP clients with separate server configurations.
    • Introduced a new MCP client configuration specifically for AMP with unique settings.
  • Enhancements

    • Improved detection and management of MCP servers by handling standard and AMP servers separately.
  • Chores

    • Updated Go module version from 1.24.2 to 1.24.4.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 11, 2025

Caution

Review failed

The pull request is closed.

"""

Walkthrough

A new boolean IsAMP was added to MCPClientConfig to distinguish AMP clients. The MCPConfig struct now holds separate maps for regular and AMP MCP servers, an AMPURL string, a client pointer, and an Extra map for unknown JSON fields. Methods were updated to handle these maps accordingly, including adding, detecting, saving, installing, and uninstalling servers. An "Amp" client config with IsAMP set was appended in init(). The Go module version was updated from 1.24.2 to 1.24.4.

Changes

File(s) Change Summary
internal/mcp/config.go Added IsAMP to MCPClientConfig; added AMPMCPServers, AMPURL, client, and Extra fields to MCPConfig; implemented custom JSON marshal/unmarshal; updated AddIfNotExists, Save, Detect, Install, and Uninstall to handle AMP servers; appended "Amp" client config and AMP variants in init().
go.mod Updated Go module version from 1.24.2 to 1.24.4.

Poem

A toggle for AMP, a new path to choose,
Servers split neatly, no chance to confuse.
Configs now dance in dual maps so bright,
"Amp" takes its place, stepping into the light.
Go version climbs, with fresh steps to explore,
Rabbits hop forward, always seeking more! 🐇✨
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8bbd99 and 8c978b1.

📒 Files selected for processing (1)
  • internal/mcp/config.go (9 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch amp-mcp
  • Post Copyable Unit Tests in Comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/mcp/config.go (1)

83-90: Hook invocation looks good but error propagation could be clearer

The hook is invoked and its (possibly mutated) buffer replaces content, which is fine.
Consider wrapping the error to provide context about which client failed, e.g.:

- content, err = c.client.BeforeSaveHook(content)
- if err != nil {
-     return err
- }
+ if content, err = c.client.BeforeSaveHook(content); err != nil {
+     return fmt.Errorf("BeforeSaveHook (%s): %w", c.client.Name, err)
+ }

This makes debugging easier when multiple client configs are processed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d4064c and 12e056f.

📒 Files selected for processing (1)
  • internal/mcp/config.go (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Test CLI Upgrade Path (windows-latest)
  • GitHub Check: Analyze (go)
🔇 Additional comments (2)
internal/mcp/config.go (2)

42-44: 👍 New hook field is well-isolated from JSON marshalling

The BeforeSaveHook is tagged with json:"-", so it will not leak into the persisted config.
No issues spotted here.


56-57: Potential for reference cycles & unintended captures

Adding a back-pointer (client *MCPClientConfig) makes sense for invoking the hook, but it also:

  1. Creates a cyclic reference (MCPClientConfig → MCPConfig → MCPClientConfig) that prevents the GC from freeing either object until both are out of scope. This is fine for short-lived CLI execution, but be mindful if these structs are ever kept globally.
  2. Relies on the pointer being set correctly (see comment below on the for _, config := range detected loop).

No action required here, but worth noting.

Comment on lines 230 to 232
config.Config.client = &config
if config.Config.AddIfNotExists(agentuityToolName, executable, append(agentuityToolArgs, "--"+config.Transport), agentuityToolEnv) {
if err := config.Config.Save(); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

❗️ Taking the address of the loop variable breaks the hook mechanism

for _, config := range detected { ... } creates a new copy of each element; config is re-used on every iteration.
Doing config.Config.client = &config therefore stores a pointer to the same loop variable, so after the loop all client pointers reference the last element.
Hooks for every other client will never fire (or will fire with the wrong data).

Fix:

-for _, config := range detected {
+for i := range detected {
+    config := &detected[i]   // pointer to the slice element
     ...
-    config.Config.client = &config
+    config.Config.client = config

or any equivalent pattern that avoids taking the address of the loop variable.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
config.Config.client = &config
if config.Config.AddIfNotExists(agentuityToolName, executable, append(agentuityToolArgs, "--"+config.Transport), agentuityToolEnv) {
if err := config.Config.Save(); err != nil {
// change the loop to index-based so we can take the address of each slice element
-for _, config := range detected {
+for i := range detected {
+ config := &detected[i] // pointer to the actual slice element
// … other setup …
- config.Config.client = &config
+ config.Config.client = config
if config.Config.AddIfNotExists(agentuityToolName,
executable,
append(agentuityToolArgs, "--"+config.Transport),
agentuityToolEnv,
) {
if err := config.Config.Save(); err != nil {
// …
}
}
}
🤖 Prompt for AI Agents
In internal/mcp/config.go around lines 230 to 232, the code takes the address of
the loop variable 'config' inside a range loop, causing all pointers to
reference the same variable and leading to incorrect hook behavior. To fix this,
create a new variable inside the loop that copies the current element, then take
the address of that new variable instead of the loop variable. This ensures each
pointer references a distinct element and hooks work correctly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
internal/mcp/config.go (1)

279-289: ⚠️ Potential issue

Uninstall requires the entry to be present in both maps, making AMP-only installs impossible to remove

The code skips when the agentuity entry is missing from either map, so an install that exists only in amp.mcpServers is never uninstalled.

-            if _, ok := mcpconfig.MCPServers[agentuityToolName]; !ok {
+            if _, ok := mcpconfig.MCPServers[agentuityToolName]; !ok {
                 logger.Debug("config for %s not found in %s, skipping", config.Name, config.ConfigLocation)
-                continue
+                // continue only if it is *also* not in the AMP map
+                if _, ok := mcpconfig.AMPMCPServers[agentuityToolName]; !ok {
+                    continue
+                }
             }
-            if _, ok := mcpconfig.AMPMCPServers[agentuityToolName]; !ok {
-                logger.Debug("config for %s not found in %s, skipping", config.Name, config.ConfigLocation)
-                continue
-            }
             delete(mcpconfig.MCPServers, agentuityToolName)
             delete(mcpconfig.AMPMCPServers, agentuityToolName)

This allows removal when the tool is present in either map.

♻️ Duplicate comments (1)
internal/mcp/config.go (1)

217-239: ⚠️ Potential issue

Still taking the address of the range loop variable – same bug as flagged earlier

The pointer stored in config.Config.client = &config will reference the re-used loop variable, not the slice element, so only the last client’s hooks behave correctly.

This was already pointed out in a previous review and remains unfixed.

-for _, config := range detected {
-    ...
-    config.Config.client = &config
+for i := range detected {
+    cfg := &detected[i]          // pointer to the slice element
+    ...
+    cfg.Config.client = cfg
🧹 Nitpick comments (1)
internal/mcp/config.go (1)

52-57: Consider backwards compatibility for the new amp.mcpServers JSON key

Using a dotted key is valid JSON, but existing tooling or grep-based scripts may not expect it. If you ever need to rename it, add a complementary load-hook/alias to keep older files working.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3a3c81 and c8bbd99.

📒 Files selected for processing (1)
  • internal/mcp/config.go (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build and Test (macos-latest)
  • GitHub Check: Test CLI Upgrade Path (windows-latest)
  • GitHub Check: Analyze (go)

Comment on lines 59 to 80
func (c *MCPConfig) AddIfNotExists(name string, command string, args []any, env map[string]any, isAMP bool) bool {
if isAMP {
if _, ok := c.AMPMCPServers[name]; ok {
return false
}
c.AMPMCPServers[name] = MCPServerConfig{
Command: command,
Args: args,
Env: env,
}
} else {
if _, ok := c.MCPServers[name]; ok {
return false
}
c.MCPServers[name] = MCPServerConfig{
Command: command,
Args: args,
Env: env,
}
}
return true
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Possible nil-map panic in AddIfNotExists

c.AMPMCPServers (and c.MCPServers) may be nil when the config was just unmarshalled and the JSON key was absent.
Writing to a nil map panics, so install on a pre-existing file without AMP entries will crash.

-func (c *MCPConfig) AddIfNotExists(name string, command string, args []any, env map[string]any, isAMP bool) bool {
+func (c *MCPConfig) AddIfNotExists(name string, command string, args []any, env map[string]any, isAMP bool) bool {
+    // lazily initialise to avoid nil-map panics
+    if c.MCPServers == nil {
+        c.MCPServers = make(map[string]MCPServerConfig)
+    }
+    if c.AMPMCPServers == nil {
+        c.AMPMCPServers = make(map[string]MCPServerConfig)
+    }

Add the above guard before the isAMP branching.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (c *MCPConfig) AddIfNotExists(name string, command string, args []any, env map[string]any, isAMP bool) bool {
if isAMP {
if _, ok := c.AMPMCPServers[name]; ok {
return false
}
c.AMPMCPServers[name] = MCPServerConfig{
Command: command,
Args: args,
Env: env,
}
} else {
if _, ok := c.MCPServers[name]; ok {
return false
}
c.MCPServers[name] = MCPServerConfig{
Command: command,
Args: args,
Env: env,
}
}
return true
}
func (c *MCPConfig) AddIfNotExists(name string, command string, args []any, env map[string]any, isAMP bool) bool {
// lazily initialise to avoid nil-map panics
if c.MCPServers == nil {
c.MCPServers = make(map[string]MCPServerConfig)
}
if c.AMPMCPServers == nil {
c.AMPMCPServers = make(map[string]MCPServerConfig)
}
if isAMP {
if _, ok := c.AMPMCPServers[name]; ok {
return false
}
c.AMPMCPServers[name] = MCPServerConfig{
Command: command,
Args: args,
Env: env,
}
} else {
if _, ok := c.MCPServers[name]; ok {
return false
}
c.MCPServers[name] = MCPServerConfig{
Command: command,
Args: args,
Env: env,
}
}
return true
}
🤖 Prompt for AI Agents
In internal/mcp/config.go around lines 59 to 80, the maps c.AMPMCPServers and
c.MCPServers may be nil if the config was unmarshalled from JSON without those
keys, causing a panic when writing to them. To fix this, add a nil check before
the isAMP conditional and initialize the maps if they are nil to prevent nil-map
panics when adding entries.

@jhaynie jhaynie merged commit 430af8e into main Jun 11, 2025
13 of 14 checks passed
@jhaynie jhaynie deleted the amp-mcp branch June 11, 2025 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants