feat: CLI AI providers — use Claude Code, Codex CLI, or Gemini CLI instead of API tokens#2280
feat: CLI AI providers — use Claude Code, Codex CLI, or Gemini CLI instead of API tokens#2280
Conversation
Add 3 new AI providers that invoke locally installed CLI tools as subprocesses, reusing the user's existing subscriptions instead of requiring API tokens. Providers: - claude-code: invokes `claude -p --output-format json` (Claude Pro/Max) - codex-cli: invokes `codex exec --json` (ChatGPT Plus/Pro) - gemini-cli: invokes `gemini -p --output-format json` (Google account, free tier) Each provider: - Implements full registry.Client interface (5 methods + GetModel/GetMaxTokens) - Auto-detects binary via exec.LookPath with helpful install hints - Parses structured JSON/JSONL output with plain text fallback - Returns ErrCLIProviderToolsNotSupported for tool-use methods - Registered via init() in register.go Schema: - Add CLI-specific fields to AIProviderConfig: binary, max_turns, max_budget_usd, allowed_tools, full_auto Tests: 40 unit tests across 3 providers PRD: Updated with tool/MCP integration analysis and phase statuses Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When mcp.servers is configured in atmos.yaml and a CLI provider (claude-code) is selected, Atmos generates a temp .mcp.json and passes it to the CLI tool via --mcp-config. This gives Claude Code access to all configured MCP servers (AWS billing, security, IAM, etc.) with automatic auth credential injection. Implementation: - Add pkg/mcp/client/mcpconfig.go — shared MCP config generation with toolchain PATH injection and auth wrapping - Update claudecode client to capture MCP servers and generate temp config - Resolve toolchain PATH and inject into server env so uvx/npx are available when the CLI tool starts MCP server subprocesses - Temp config cleaned up after CLI tool exits Tests: - 12 tests for mcpconfig (BuildMCPJSONEntry, GenerateMCPConfig, WriteMCPConfigToTempFile, copyEnv, toolchain PATH injection, immutability) - 4 new tests for claudecode (resolveToolchainPATH, MCP server capture) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create examples/ai-claude-code/ with full Claude Code provider config, 8 AWS MCP servers, auth, toolchain, and comprehensive README - README explains API vs CLI providers, mixing providers, comparison table - Update infra-live .atmos.d/ai.yaml to use claude-code as default provider (anthropic kept as fallback) - Update atmos-ai-global-flag.md status to Shipped (v3.1) - Update atmos-ai-local-providers.md PRD with Phase 3 MCP pass-through details, toolchain PATH injection strategy, and phase statuses Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLI providers (claude-code, codex-cli, gemini-cli) handle MCP via --mcp-config pass-through. They should not trigger MCP server routing or start servers through the Atmos tool registry — that path is for API providers only. - Add isCLIProvider() check in initializeAIToolsAndExecutor - Skip registerMCPServerTools when provider is a CLI provider - Add 7 table-driven tests for isCLIProvider Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Viper lowercasing MCP server env keys (aws_region → AWS_REGION) in both atmos mcp export and CLI provider MCP pass-through - Pre-generate MCP config in NewClient so info shows before "Thinking..." - Show AI provider name after tool initialization - Add TestCopyEnv_UppercasesKeys verifying lowercase → UPPERCASE restoration Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…EADME - Add --dangerously-skip-permissions when MCP servers are configured (required because -p mode cannot show approval prompts) - Update PRD: Phase 3 marked as shipped for Claude Code - Add "See It in Action" section to ai-claude-code example README with real security posture output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gemini CLI reads MCP servers from .gemini/settings.json (project-level). Atmos creates a temp directory with the settings file and sets cmd.Dir so Gemini CLI picks it up. Uses --yolo flag to auto-approve tool calls. - Add mcpServers, toolchainPATH, mcpSettingsDir to Gemini CLI Client - Add writeMCPSettingsFile to create temp .gemini/settings.json - Inject toolchain PATH and uppercase env keys - Use errUtils.ErrWrapFormat for consistent error wrapping - 15 tests including settings file generation, auth wrapping, toolchain PATH - Update PRD: Gemini CLI MCP pass-through marked as shipped Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codex CLI reads MCP servers from .codex/config.toml using TOML [mcp_servers.<name>] tables. Atmos creates a temp directory with the config file and sets cmd.Dir so Codex CLI picks it up. - Add writeMCPConfigTOML to generate TOML format config - Add writeTOMLServer helper for individual server sections - Inject toolchain PATH and uppercase env keys - Uses --full-auto flag for non-interactive tool approval - 18 tests including TOML generation, auth wrapping, args formatting - Coverage: 49.3% → 57.6% - Update PRD: all 3 providers now have MCP pass-through shipped - Add Codex CLI config and advanced config links to references Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e README - Add EC2 billing query example to See It in Action - Add 11-step execution flow diagram showing complete chain: atmos.yaml → toolchain → MCP config → Claude Code → auth exec → MCP server → AWS API → AI analysis → response - Clarify that MCP tool returns raw data, AI analyzes it Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add TestSendMessageWithToolsAndHistory_NotSupported for codexcli and geminicli - Add TestFormatMessages and TestFormatMessages_Empty for codexcli and geminicli - Coverage: codexcli 57.6% → 63.2%, geminicli 47.1% → 53.9% Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rmat - Write .gemini/settings.json to cwd (not temp dir) to respect Trusted Folders - Fix JSON response field: "result" → "response" (actual Gemini CLI format) - Use --approval-mode auto_edit instead of --yolo (admin may block yolo) - Pass --allowed-mcp-server-names to explicitly enable configured servers - Add filterStderr to strip deprecation warnings from error output - Pass prompt as --prompt flag value (not stdin) - Update PRD with Trusted Folders, enterprise admin restrictions, workarounds - Update tests for cwd-based settings and new response format Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The toolchain PATH injection was creating duplicated entries because
os.Getenv("PATH") already contains duplicates from the shell environment.
- Add deduplicatePATH() to remove duplicate PATH entries while preserving order
- Apply deduplication in injectToolchainPATH after combining toolchain + base PATH
- Add TestDeduplicatePATH (5 cases) and TestInjectToolchainPATH_Deduplicates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Google disables MCP on the server-side proxy for personal Google accounts using oauth-personal auth. The gemini-cli provider works for prompt-only queries but cannot use external MCP servers with the free tier. Switching to API key auth enables MCP but makes it equivalent to the existing gemini API provider. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s regardless of tier The MCP restriction is based on account type (oauth-personal), not subscription tier. Even paid Gemini 3 Pro users are affected. Added auth mode comparison table, investigation details, proxy architecture explanation, and future outlook. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…njection Three fixes for Codex CLI provider: 1. ExtractResult now handles "agent_message" item type (Codex returns item.type="agent_message" with text on item.text directly, not the "message" type with nested content array from the API docs). 2. MCP servers passed via -c flags instead of temp .codex/config.toml (Codex only reads ~/.codex/config.toml, not project-level config). 3. Use --dangerously-bypass-approvals-and-sandbox when MCP servers are configured (--full-auto only auto-approves file writes, not MCP tool calls). This is safe because MCP servers are explicitly configured by the user in atmos.yaml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Phase 3 now shipped for Claude Code AND Codex CLI - Codex CLI uses -c flag overrides (not temp config.toml) - --dangerously-bypass-approvals-and-sandbox required for MCP tool calls - Document Codex output format difference (agent_message vs message) - Add MCP config delivery summary table per provider - Update comparison tables and feature descriptions for consistency Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
-c flag overrides do NOT register MCP servers as tools in Codex CLI. Codex only loads MCP servers from ~/.codex/config.toml. Changed approach to write MCP servers to the global config with backup/restore: 1. Back up existing ~/.codex/config.toml content 2. Append MCP server TOML sections 3. After Codex exits, restore the original config Removed unused buildMCPConfigArgs function. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codex CLI MCP servers don't inherit the parent process environment. Auth-related vars like ATMOS_PROFILE must be explicitly passed in the server env section of config.toml. Without this, atmos auth exec fails with "identity not found" because it can't discover the auth config. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Codex uses ~/.codex/config.toml with backup/restore (not -c flags) - ATMOS_* env vars injected into MCP server config for auth discovery - Documented that Codex MCP servers don't inherit parent process env - Updated config delivery summary table Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PRD v1.6 (final revision): - Fix Codex JSONL output example to match actual agent_message format - Update Codex provider code example to match implementation - Fix Gemini response struct field (response, not result) - Correct Codex MCP line from "-c flags" to "~/.codex/config.toml" - Replace generic MCP pass-through description with per-provider details - Remove outdated "Implementation steps" section (already shipped) - Add full_auto vs dangerously-bypass note to config example Example fixes: - Remove --mcp flag references (not supported for CLI providers) - Increase timeout from 120s to 300s for MCP server startup - Add note that tools section is for API providers only - Add mock vpc component and stack config for self-contained example - Add MCP Support column to CLI providers table with Gemini note - Fix flow diagrams: remove smart routing, clarify all servers passed - Remove .tool-versions reference (not in example) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated 8 docs files to mention CLI providers (claude-code, codex-cli, gemini-cli): - ai/ai.mdx: CLI provider Quick Start, Providers table, MCP pass-through notes - ai/troubleshooting.mdx: CLI provider troubleshooting section - cli/configuration/ai/index.mdx: CLI provider Quick Start, provider count - cli/configuration/ai/providers.mdx: CLI Providers section with settings and examples - cli/configuration/mcp/index.mdx: CLI Provider MCP Pass-Through section - cli/commands/ai/usage.mdx: Updated provider list in intro - cli/commands/ai/ask.mdx: Smart routing note for CLI providers - cli/commands/ai/exec.mdx: Provider flag list, smart routing note Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers Claude Code, Codex CLI, and Gemini CLI as new Atmos AI providers. Includes real-world examples showing security posture assessment (Claude Code) and EC2 billing query (Codex CLI) using MCP pass-through. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 26 new unit tests across CLI provider packages: - claudecode: parseResponse edge cases, formatMessages, MCP config path - codexcli: ATMOS_* env var injection, extractTextFromEvent variants, collectAtmosEnvVars, injectAtmosEnvVars (overwrite protection, nil env) - geminicli: filterStderr (deprecation/YOLO/empty/meaningful), parseResponse, formatMessages edge cases Coverage: codexcli 62.4% → 68.2%, geminicli 46.6% → 57.8%. Remaining uncovered code is Send* methods requiring actual CLI binaries. Roadmap: add 4 shipped CLI provider milestones to ai-assistant initiative. Remove planned "Auto-detection" milestone. Progress 96% (22/23). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds three CLI-backed AI providers (Claude Code, Codex CLI, Gemini CLI), MCP pass-through and JSON/TOML config tooling, schema/config fields and sentinel errors for CLI providers, many unit tests, docs/examples/PRD/blog updates, provider registration wiring, and dependency/NOTICE updates. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Atmos
participant CLITool as CLI Provider
participant MCP as MCP Server
User->>Atmos: atmos ai ask --provider claude-code
Atmos->>Atmos: Load config, detect CLI provider
alt MCP servers configured
Atmos->>Atmos: Generate temp MCP JSON config
Atmos->>Atmos: Write /tmp/mcp-*.json
end
Atmos->>Atmos: Resolve tool binary and build args
Atmos->>CLITool: Run subprocess with stdin and MCP flags
CLITool->>CLITool: CLI selects MCP server / executes tools
alt MCP tool requires auth
CLITool->>MCP: Request tool run
MCP->>Atmos: Need auth
Atmos->>MCP: atmos auth exec -i <id> -- <cmd>
MCP-->>CLITool: Tool result
end
CLITool-->>Atmos: stdout JSON / JSONL
Atmos->>Atmos: Parse response, cleanup temp files
Atmos-->>User: Formatted response
sequenceDiagram
participant Atmos
participant APIProvider as API Provider
participant MCP as MCP Server
participant CLITool as CLI Provider
rect rgba(200, 150, 100, 0.5)
Note over Atmos,APIProvider: API Provider Flow (Smart Routing)
end
Atmos->>Atmos: Multiple MCP servers configured
Atmos->>APIProvider: Lightweight routing call
APIProvider-->>Atmos: Recommended server
Atmos->>Atmos: Start only selected MCP server
Atmos->>APIProvider: Send prompt + tool schemas
APIProvider->>MCP: tool_use call
MCP-->>APIProvider: Tool result
APIProvider-->>Atmos: Final response
rect rgba(100, 150, 200, 0.5)
Note over Atmos,CLITool: CLI Provider Flow (Pass-Through)
end
Atmos->>Atmos: Multiple MCP servers configured
Atmos->>Atmos: Write MCP config and pass ALL servers to CLI
Atmos->>Atmos: Skip smart routing
Atmos->>CLITool: Invoke CLI with MCP config
CLITool->>MCP: CLI chooses server(s) internally
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
NOTICE (1)
1-1809:⚠️ Potential issue | 🟠 MajorRegenerate NOTICE to fix CI drift.
Dependency Review is failing because this file is not in sync with the generator output. Please run
./scripts/generate-notice.shand commit the regenerated NOTICE as-is.Based on learnings, “In the cloudposse/atmos repository, the NOTICE file is programmatically generated and should not be manually edited.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@NOTICE` around lines 1 - 1809, The NOTICE file is out of sync with the generator and causing CI drift; run the generator script and commit the result: execute ./scripts/generate-notice.sh to regenerate the NOTICE file, verify the output replaces the existing NOTICE (do not manually edit NOTICE), then add/commit the regenerated NOTICE and push the change so Dependency Review passes.
🧹 Nitpick comments (13)
cmd/ai/init_test.go (1)
530-549: Solid table-driven test.Covers the primary classification cases well. Consider adding edge cases for input normalization robustness (e.g.,
"Claude-Code"," claude-code ") if config loading doesn't already normalize provider names upstream.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/ai/init_test.go` around lines 530 - 549, Add edge-case inputs to TestIsCLIProvider to verify normalization: include variations like "Claude-Code" (different casing), " claude-code " (leading/trailing whitespace), and other whitespace/case permutations to ensure isCLIProvider handles normalization consistently; update the tests slice in TestIsCLIProvider to add these cases with expected true (and any negative variants as needed) so the test exercises isCLIProvider's robustness.pkg/schema/ai.go (1)
32-38: Comment missing terminal period.Line 33 comment should end with a period per the
godotlinter requirement.- // CLI provider fields (for claude-code, codex-cli, gemini-cli). + // CLI provider fields (for claude-code, codex-cli, gemini-cli providers).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/schema/ai.go` around lines 32 - 38, The comment "CLI provider fields (for claude-code, codex-cli, gemini-cli)" above the struct fields in pkg/schema/ai.go is missing a terminal period; update that top-line comment so it ends with a period to satisfy the godot linter (edit the comment that precedes the Binary, MaxTurns, MaxBudgetUSD, AllowedTools, and FullAuto fields).pkg/ai/factory_test.go (1)
13-16: Consider adding test cases for CLI providers.The blank imports register the new providers, but
TestNewClientlacks test cases forclaude-code,codex-cli, andgemini-cli. These would exercise the factory routing for CLI providers.CLI providers may need binary detection or special skip logic similar to the existing API key handling on lines 163-169.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/factory_test.go` around lines 13 - 16, Add test cases in TestNewClient to cover the CLI providers "claude-code", "codex-cli", and "gemini-cli" so the factory routing for CLI agents is exercised; for each new test case, follow the pattern used for existing providers in TestNewClient (create the client via NewClient and assert the expected provider type) and include binary-detection or skip logic similar to the existing API-key checks—i.e., probe for the required CLI binary (or environment) and call t.Skipf when the binary is not present so the test suite remains stable on systems without the CLI installed.cmd/mcp/client/export.go (1)
114-125: MakeuppercaseEnvKeysconsistently return a copy.Right now empty maps are returned as-is, which contradicts the function contract and creates inconsistent aliasing behavior.
Suggested patch
func uppercaseEnvKeys(env map[string]string) map[string]string { - if len(env) == 0 { - return env - } + if env == nil { + return nil + } result := make(map[string]string, len(env)) for k, v := range env { result[strings.ToUpper(k)] = v } return result }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/mcp/client/export.go` around lines 114 - 125, The function uppercaseEnvKeys currently returns the original env map when it's empty, causing inconsistent aliasing; change it so it always returns a new map copy: allocate result := make(map[string]string, len(env)) unconditionally, copy each key/value with result[strings.ToUpper(k)] = v (the loop will be skipped for len==0) and return result; update the function uppercaseEnvKeys to never return the input map directly so callers always receive a fresh map.pkg/mcp/client/mcpconfig_test.go (1)
76-85: Consider adding an empty servers edge case.
GenerateMCPConfigwith an empty map is a valid input. A quick test ensures it returns an emptyMCPServersmap without panicking.Optional test case
func TestGenerateMCPConfig_EmptyServers(t *testing.T) { servers := map[string]schema.MCPServerConfig{} config := GenerateMCPConfig(servers, "") assert.NotNil(t, config.MCPServers) assert.Empty(t, config.MCPServers) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/mcp/client/mcpconfig_test.go` around lines 76 - 85, Add a unit test covering the empty-servers edge case for GenerateMCPConfig: create an empty map[string]schema.MCPServerConfig, call GenerateMCPConfig with it, and assert that the returned config.MCPServers is non-nil and empty (no panic). Place the new test (e.g. TestGenerateMCPConfig_EmptyServers) alongside TestGenerateMCPConfig to ensure GenerateMCPConfig handles empty input gracefully.website/docs/cli/configuration/ai/providers.mdx (1)
104-119: Consider simplifying thebinarydescription.The reference to
exec.LookPathis Go implementation detail. Users just need to know it finds the binary on PATH.Suggested wording
<dt>`binary`</dt> - <dd>Path to the CLI binary. Optional — defaults to `exec.LookPath` (finds it on PATH).</dd> + <dd>Path to the CLI binary. Optional — defaults to finding it on PATH.</dd>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/docs/cli/configuration/ai/providers.mdx` around lines 104 - 119, The `binary` field description includes an implementation detail (`exec.LookPath`) that should be removed; update the `<dd>` text for `binary` to a simpler user-facing sentence like "Path to the CLI binary. Optional — defaults to locating the binary on the PATH." Replace the existing phrase that mentions `exec.LookPath` with this simpler wording and keep the rest of the list unchanged; target the `binary` entry in the providers.mdx content (currently mentioning `exec.LookPath`) when making the edit.pkg/ai/agent/codexcli/client.go (1)
331-340: Consider logging restore failures.
restoreGlobalConfigsilently ignores write/remove errors. While this is acceptable for cleanup code, logging at debug level could help troubleshoot issues where user config remains corrupted.Optional: add debug logging for restore failures
func (c *Client) restoreGlobalConfig() { configPath := codexConfigPath() if c.configBackedUp { - _ = os.WriteFile(configPath, c.originalConfig, configFilePerms) + if err := os.WriteFile(configPath, c.originalConfig, configFilePerms); err != nil { + // Log at debug level — cleanup failures shouldn't crash the command. + ui.Debug(fmt.Sprintf("Failed to restore %s: %s", configPath, err)) + } } else { // No original config existed — remove the file we created. - _ = os.Remove(configPath) + if err := os.Remove(configPath); err != nil && !os.IsNotExist(err) { + ui.Debug(fmt.Sprintf("Failed to remove %s: %s", configPath, err)) + } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/codexcli/client.go` around lines 331 - 340, The restoreGlobalConfig method currently ignores errors from os.WriteFile and os.Remove; update restoreGlobalConfig (in Client.restoreGlobalConfig) to capture the error returned by os.WriteFile and os.Remove and emit a debug-level log when those operations fail (e.g., use the client logger on c if available, otherwise the standard log package) including configPath and the error; preserve the existing behavior (do not return the error) so this remains cleanup code but adds diagnostic logging to help troubleshoot corrupted user configs.pkg/ai/agent/geminicli/client.go (4)
246-250: Path construction: redundant".".
filepath.Join(".", ".gemini")returns.gemini— the leading"."is unnecessary noise.- geminiDir := filepath.Join(".", ".gemini") + geminiDir := ".gemini"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/geminicli/client.go` around lines 246 - 250, The code constructs geminiDir using filepath.Join(".", ".gemini") which is redundant; change the construction to simply use ".gemini" (e.g., set geminiDir := ".gemini") and keep the existing os.MkdirAll(geminiDir, settingsDirPerms) and error wrapping (ErrMCPConfigWriteFailed) so the behavior and error handling in this block (filepath.Join usage, geminiDir variable, os.MkdirAll call, and the fmt.Errorf wrapping) remain the same but without the unnecessary "." join.
119-126: Non-deterministic MCP server ordering.Iterating over
c.mcpServersmap produces non-deterministic order of server names joined into--allowed-mcp-server-names. This isn't a functional bug, but it can make debugging harder and causes non-reproducible CLI invocations.♻️ Sort server names for deterministic output
+import "slices" + // Explicitly allow configured MCP servers by name. if len(c.mcpServers) > 0 { var serverNames []string for name := range c.mcpServers { serverNames = append(serverNames, name) } + slices.Sort(serverNames) args = append(args, "--allowed-mcp-server-names", strings.Join(serverNames, ",")) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/geminicli/client.go` around lines 119 - 126, Iterating the map c.mcpServers to build serverNames yields non-deterministic ordering; sort the collected names before joining so the args slice gets a stable value for "--allowed-mcp-server-names". In the code that gathers names from c.mcpServers (the block that appends to args), collect names into serverNames as now, then sort.Strings(serverNames) and finally use strings.Join(serverNames, ",") when appending to args (refer to c.mcpServers, serverNames, args).
279-302: Consider filtering more stderr noise patterns.The filter is thoughtful, but Gemini CLI may emit other warning patterns (e.g.,
ExperimentalWarning,punycode). You might want to make this extensible or add a catch-all for common Node.js warnings.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/geminicli/client.go` around lines 279 - 302, The filterStderr function currently skips only a few hardcoded patterns; update it to cover additional common Node/CLI noise by introducing a reusable list or regex slice of warning patterns (e.g., include "ExperimentalWarning", "punycode", "Warning", "deprecated" and "--trace-warnings") and use that list to skip lines, or make the patterns configurable/extendable so future patterns can be added without changing filterStderr; locate the function filterStderr in pkg/ai/agent/geminicli/client.go and replace the individual if checks with a loop over the pattern list (or compiled regexes) to filter out matches and keep the rest.
36-44: Dead field:mcpSettingsDiris never read.The
mcpSettingsDirfield is assigned at line 96 but never used elsewhere in the code. If it's not needed (since settings are written to cwd), remove it from the struct to avoid confusion.type Client struct { binaryPath string model string mcpServers map[string]schema.MCPServerConfig toolchainPATH string - mcpSettingsDir string // Temp dir containing .gemini/settings.json for MCP config. }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/geminicli/client.go` around lines 36 - 44, The Client struct contains a dead field mcpSettingsDir that is assigned but never read; remove the mcpSettingsDir field from the Client struct declaration and also remove its assignment in the client constructor/initializer (wherever mcpSettingsDir is set) and any associated comment; ensure no other code references mcpSettingsDir and update related comments to reflect that MCP settings are written to the current working directory.pkg/ai/agent/claudecode/client.go (2)
278-289: Duplicate code:formatMessagesis identical in both providers.This function is also duplicated from
geminicli/client.go. Consider extracting to a shared location.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/claudecode/client.go` around lines 278 - 289, The formatMessages function is duplicated across providers (found in this file as formatMessages and also in geminicli/client.go); extract it into a shared package (e.g., pkg/ai/agent/shared or pkg/ai/agent/util) and replace both local implementations with a single exported helper like FormatMessages(messages []types.Message) that returns the joined prompt; update callers in claudecode/client.go and geminicli/client.go to import and use the shared helper and remove the duplicate function definitions.
100-117: ExtractresolveToolchainPATHtopkg/ai/agent/base/to eliminate triplication across providers.The function is duplicated across three providers:
claudecode,geminicli, andcodexcli. Moving it topkg/ai/agent/base/keeps shared toolchain logic in one place and prevents drift. The base/ package already exists for common agent functionality.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/ai/agent/claudecode/client.go` around lines 100 - 117, Extract the duplicated resolveToolchainPATH function into the shared package pkg/ai/agent/base by moving the implementation (the logic that calls dependencies.LoadToolVersionsDependencies, dependencies.NewEnvironmentFromDeps and scans tenv.EnvVars() for "PATH=") into a new function base.ResolveToolchainPATH, update callers in claudecode, geminicli, and codexcli to call base.ResolveToolchainPATH(atmosConfig) instead of their local copies, and remove the duplicated implementations so there is a single canonical implementation in base.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/ai/init.go`:
- Around line 51-52: The comment above the mcpMgr declaration is inaccurate
about how MCP is passed; update the comment in cmd/ai/init.go (the comment that
currently mentions “--mcp-config”) to say that CLI providers skip MCP handling
because MCP is passed through by provider-specific mechanisms (e.g., different
flags or delivery methods for Codex/Gemini), and make the same wording change
for the other instance referenced around the mcp-related block at lines 300-302
so both comments accurately state “provider-specific pass-through” rather than
the concrete “--mcp-config”.
In `@pkg/ai/agent/claudecode/client.go`:
- Around line 83-95: NewClient calls mcpclient.WriteMCPConfigToTempFile and
stores the resulting path in client.mcpConfigPath but neither documents nor
cleans up the temp file; implement a Close() method on the client (e.g., func (c
*Client) Close() error) that checks c.mcpConfigPath and removes the file if
present, update NewClient/Client docs to mention caller must call Close(), and
ensure tests (client_test.go) can call client.Close() to remove the generated
MCP config; reference WriteMCPConfigToTempFile, NewClient, client.mcpConfigPath,
and Close().
In `@pkg/ai/agent/codexcli/client_test.go`:
- Around line 155-179: TestWriteAndRestoreGlobalConfig currently writes to the
real user config via writeMCPToGlobalConfig/restoreGlobalConfig; fix it by
making the test operate on a temporary config location: create a temp dir
(os.MkdirTemp), set the HOME (or other env used by codexConfigPath) for the test
using t.Setenv so codexConfigPath resolves inside that temp dir, call
writeMCPToGlobalConfig and defer restoreGlobalConfig immediately after creating
the client so restore runs even on failure, and remove the temp dir at the end;
this keeps all operations (writeMCPToGlobalConfig, restoreGlobalConfig, and the
configBackedUp checks) confined to the temp environment.
- Around line 74-98: The test is writing to the real Codex config
(~/.codex/config.toml); modify NewClient (or codexConfigPath) to honor an
override (e.g., ATMOS_CODEX_CONFIG_PATH env var) or inject a configPath
parameter so tests can point to a temp file, update
TestNewClient_MCPServers_Captured_WhenConfigured to set that env var (or pass
the temp path) and assert against the temp file, and fix restoreGlobalConfig to
return or log errors instead of silently discarding them (reference NewClient,
codexConfigPath, restoreGlobalConfig, and the
TestNewClient_MCPServers_Captured_WhenConfigured test to locate the code to
change).
In `@pkg/ai/agent/geminicli/client_test.go`:
- Around line 67-69: Remove the duplicate assertion in the unit test: in the
test in client_test.go where the variable client is asserted, there are two
consecutive identical lines calling assert.Nil(t, client.mcpServers); delete one
of them so only a single assert.Nil(t, client.mcpServers) remains (locate the
duplicate near the test that constructs the client and checks
client.mcpServers).
In `@pkg/ai/agent/geminicli/client.go`:
- Around line 138-141: The two error returns in client.go are inconsistent: the
branch that uses errMsg currently formats the underlying error as plain text
(losing the original error type), so change both returns to consistently wrap
the underlying error using %w; specifically update the return that references
ProviderName and errMsg to include errMsg as context but still wrap the original
error variable (err) with %w, and ensure the other return (which already wraps
err) uses the same ordering/formatting around errUtils.ErrCLIProviderExecFailed,
ProviderName, errMsg and err so callers can use errors.Is/errors.As reliably.
- Around line 89-99: The code currently calls writeMCPSettingsInCwd(...) and
silently overwrites .gemini/settings.json; update writeMCPSettingsInCwd (or the
call site in the block that sets client.mcpServers and client.toolchainPATH) to
detect an existing .gemini/settings.json in cwd and either (a) create a backup
(e.g., rename to settings.json.bak with a timestamp) before writing the new
file, or (b) if backup fails, log a clear warning via ui.Warn or log.Debug
including the existing file path and skip overwriting; ensure any error from the
backup or write is returned and surfaced so the caller can log it (preserve
current behavior of setting client.mcpSettingsDir when appropriate) and
reference writeMCPSettingsInCwd, resolveToolchainPATH, client.mcpSettingsDir,
and atmosConfig.MCP.Servers when making the change.
In `@website/docs/ai/ai.mdx`:
- Around line 54-65: Update the Gemini CLI authentication command in the
Terminal block (the line currently using "gemini auth login") to the official
flow: replace that invocation with a direct "gemini" call so the
install-and-auth sequence uses "npm install -g `@google/gemini-cli` && gemini";
locate the Terminal section in ai.mdx that contains the three tool install/auth
lines (Claude, OpenAI Codex, Gemini) and change the Gemini portion accordingly.
In `@website/docs/cli/commands/ai/ask.mdx`:
- Line 74: The help text describing routing for MCP servers omits `gemini-cli`;
update the sentence that lists CLI providers (currently mentioning `claude-code`
and `codex-cli`) to include `gemini-cli` as well so it reads that `claude-code`,
`codex-cli`, and `gemini-cli` skip routing and pass all servers to the CLI tool
for internal selection.
In `@website/docs/cli/commands/ai/exec.mdx`:
- Line 92: Update the sentence that lists CLI providers to also include
`gemini-cli` so the routing note matches the provider list and implementation;
specifically, modify the sentence mentioning "CLI providers (`claude-code`,
`codex-cli`) skip routing" to read something like "CLI providers (`claude-code`,
`codex-cli`, `gemini-cli`) skip routing" ensuring the documentation text in
exec.mdx reflects that `gemini-cli` is passed to the CLI tool and handled
internally.
In `@website/src/data/roadmap.js`:
- Around line 524-527: The four shipped milestone objects for 'Claude Code CLI
provider', 'OpenAI Codex CLI provider', 'Gemini CLI provider', and 'MCP
pass-through for CLI providers' are missing the required pr metadata; update
each object in website/src/data/roadmap.js to include a pr property (e.g., pr:
'https://github.com/your-repo/...') alongside the existing changelog property so
they follow the repo rule that shipped milestones with changelog must also
include pr links; ensure you add the pr field to the objects where label matches
those four entries.
---
Outside diff comments:
In `@NOTICE`:
- Around line 1-1809: The NOTICE file is out of sync with the generator and
causing CI drift; run the generator script and commit the result: execute
./scripts/generate-notice.sh to regenerate the NOTICE file, verify the output
replaces the existing NOTICE (do not manually edit NOTICE), then add/commit the
regenerated NOTICE and push the change so Dependency Review passes.
---
Nitpick comments:
In `@cmd/ai/init_test.go`:
- Around line 530-549: Add edge-case inputs to TestIsCLIProvider to verify
normalization: include variations like "Claude-Code" (different casing), "
claude-code " (leading/trailing whitespace), and other whitespace/case
permutations to ensure isCLIProvider handles normalization consistently; update
the tests slice in TestIsCLIProvider to add these cases with expected true (and
any negative variants as needed) so the test exercises isCLIProvider's
robustness.
In `@cmd/mcp/client/export.go`:
- Around line 114-125: The function uppercaseEnvKeys currently returns the
original env map when it's empty, causing inconsistent aliasing; change it so it
always returns a new map copy: allocate result := make(map[string]string,
len(env)) unconditionally, copy each key/value with result[strings.ToUpper(k)] =
v (the loop will be skipped for len==0) and return result; update the function
uppercaseEnvKeys to never return the input map directly so callers always
receive a fresh map.
In `@pkg/ai/agent/claudecode/client.go`:
- Around line 278-289: The formatMessages function is duplicated across
providers (found in this file as formatMessages and also in
geminicli/client.go); extract it into a shared package (e.g.,
pkg/ai/agent/shared or pkg/ai/agent/util) and replace both local implementations
with a single exported helper like FormatMessages(messages []types.Message) that
returns the joined prompt; update callers in claudecode/client.go and
geminicli/client.go to import and use the shared helper and remove the duplicate
function definitions.
- Around line 100-117: Extract the duplicated resolveToolchainPATH function into
the shared package pkg/ai/agent/base by moving the implementation (the logic
that calls dependencies.LoadToolVersionsDependencies,
dependencies.NewEnvironmentFromDeps and scans tenv.EnvVars() for "PATH=") into a
new function base.ResolveToolchainPATH, update callers in claudecode, geminicli,
and codexcli to call base.ResolveToolchainPATH(atmosConfig) instead of their
local copies, and remove the duplicated implementations so there is a single
canonical implementation in base.
In `@pkg/ai/agent/codexcli/client.go`:
- Around line 331-340: The restoreGlobalConfig method currently ignores errors
from os.WriteFile and os.Remove; update restoreGlobalConfig (in
Client.restoreGlobalConfig) to capture the error returned by os.WriteFile and
os.Remove and emit a debug-level log when those operations fail (e.g., use the
client logger on c if available, otherwise the standard log package) including
configPath and the error; preserve the existing behavior (do not return the
error) so this remains cleanup code but adds diagnostic logging to help
troubleshoot corrupted user configs.
In `@pkg/ai/agent/geminicli/client.go`:
- Around line 246-250: The code constructs geminiDir using filepath.Join(".",
".gemini") which is redundant; change the construction to simply use ".gemini"
(e.g., set geminiDir := ".gemini") and keep the existing os.MkdirAll(geminiDir,
settingsDirPerms) and error wrapping (ErrMCPConfigWriteFailed) so the behavior
and error handling in this block (filepath.Join usage, geminiDir variable,
os.MkdirAll call, and the fmt.Errorf wrapping) remain the same but without the
unnecessary "." join.
- Around line 119-126: Iterating the map c.mcpServers to build serverNames
yields non-deterministic ordering; sort the collected names before joining so
the args slice gets a stable value for "--allowed-mcp-server-names". In the code
that gathers names from c.mcpServers (the block that appends to args), collect
names into serverNames as now, then sort.Strings(serverNames) and finally use
strings.Join(serverNames, ",") when appending to args (refer to c.mcpServers,
serverNames, args).
- Around line 279-302: The filterStderr function currently skips only a few
hardcoded patterns; update it to cover additional common Node/CLI noise by
introducing a reusable list or regex slice of warning patterns (e.g., include
"ExperimentalWarning", "punycode", "Warning", "deprecated" and
"--trace-warnings") and use that list to skip lines, or make the patterns
configurable/extendable so future patterns can be added without changing
filterStderr; locate the function filterStderr in
pkg/ai/agent/geminicli/client.go and replace the individual if checks with a
loop over the pattern list (or compiled regexes) to filter out matches and keep
the rest.
- Around line 36-44: The Client struct contains a dead field mcpSettingsDir that
is assigned but never read; remove the mcpSettingsDir field from the Client
struct declaration and also remove its assignment in the client
constructor/initializer (wherever mcpSettingsDir is set) and any associated
comment; ensure no other code references mcpSettingsDir and update related
comments to reflect that MCP settings are written to the current working
directory.
In `@pkg/ai/factory_test.go`:
- Around line 13-16: Add test cases in TestNewClient to cover the CLI providers
"claude-code", "codex-cli", and "gemini-cli" so the factory routing for CLI
agents is exercised; for each new test case, follow the pattern used for
existing providers in TestNewClient (create the client via NewClient and assert
the expected provider type) and include binary-detection or skip logic similar
to the existing API-key checks—i.e., probe for the required CLI binary (or
environment) and call t.Skipf when the binary is not present so the test suite
remains stable on systems without the CLI installed.
In `@pkg/mcp/client/mcpconfig_test.go`:
- Around line 76-85: Add a unit test covering the empty-servers edge case for
GenerateMCPConfig: create an empty map[string]schema.MCPServerConfig, call
GenerateMCPConfig with it, and assert that the returned config.MCPServers is
non-nil and empty (no panic). Place the new test (e.g.
TestGenerateMCPConfig_EmptyServers) alongside TestGenerateMCPConfig to ensure
GenerateMCPConfig handles empty input gracefully.
In `@pkg/schema/ai.go`:
- Around line 32-38: The comment "CLI provider fields (for claude-code,
codex-cli, gemini-cli)" above the struct fields in pkg/schema/ai.go is missing a
terminal period; update that top-line comment so it ends with a period to
satisfy the godot linter (edit the comment that precedes the Binary, MaxTurns,
MaxBudgetUSD, AllowedTools, and FullAuto fields).
In `@website/docs/cli/configuration/ai/providers.mdx`:
- Around line 104-119: The `binary` field description includes an implementation
detail (`exec.LookPath`) that should be removed; update the `<dd>` text for
`binary` to a simpler user-facing sentence like "Path to the CLI binary.
Optional — defaults to locating the binary on the PATH." Replace the existing
phrase that mentions `exec.LookPath` with this simpler wording and keep the rest
of the list unchanged; target the `binary` entry in the providers.mdx content
(currently mentioning `exec.LookPath`) when making the edit.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c1bb2fc1-e4e4-4c99-a288-c4ed088a3e03
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (39)
NOTICEcmd/ai/init.gocmd/ai/init_test.gocmd/mcp/client/export.godocs/prd/atmos-ai-global-flag.mddocs/prd/atmos-ai-local-providers.mderrors/errors.goexamples/ai-claude-code/README.mdexamples/ai-claude-code/atmos.yamlexamples/ai-claude-code/components/terraform/vpc/main.tfexamples/ai-claude-code/components/terraform/vpc/variables.tfexamples/ai-claude-code/stacks/example.yamlexamples/ai/README.mdexamples/mcp/README.mdgo.modpkg/ai/agent/claudecode/client.gopkg/ai/agent/claudecode/client_test.gopkg/ai/agent/claudecode/register.gopkg/ai/agent/codexcli/client.gopkg/ai/agent/codexcli/client_test.gopkg/ai/agent/codexcli/register.gopkg/ai/agent/geminicli/client.gopkg/ai/agent/geminicli/client_test.gopkg/ai/agent/geminicli/register.gopkg/ai/analyze/providers.gopkg/ai/factory_test.gopkg/mcp/client/mcpconfig.gopkg/mcp/client/mcpconfig_test.gopkg/schema/ai.gowebsite/blog/2026-04-01-ai-cli-providers.mdxwebsite/docs/ai/ai.mdxwebsite/docs/ai/troubleshooting.mdxwebsite/docs/cli/commands/ai/ask.mdxwebsite/docs/cli/commands/ai/exec.mdxwebsite/docs/cli/commands/ai/usage.mdxwebsite/docs/cli/configuration/ai/index.mdxwebsite/docs/cli/configuration/ai/providers.mdxwebsite/docs/cli/configuration/mcp/index.mdxwebsite/src/data/roadmap.js
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2280 +/- ##
==========================================
- Coverage 77.21% 77.18% -0.03%
==========================================
Files 1038 1045 +7
Lines 97833 98367 +534
==========================================
+ Hits 75541 75929 +388
- Misses 18069 18187 +118
- Partials 4223 4251 +28
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
CodeRabbit fixes: - Add gemini-cli to routing skip notes (ask.mdx, exec.mdx) - Fix Gemini CLI auth command (gemini, not gemini auth login) - Wrap original error in stderr error paths (all 3 providers) - Add .gemini/settings.json backup/restore (like Codex) - Fix uppercaseEnvKeys nil vs empty (export.go) - Simplify exec.LookPath wording in docs - Add debug logging to restore failures - Sort MCP server names for deterministic output - Remove dead mcpSettingsDir field - Fix install hint: brew install --cask claude-code - Fix MCP pass-through comment wording (init.go) - Add pr: 2280 to roadmap milestones - Isolate codexcli tests with temp HOME Code deduplication: - Extract formatMessages to base.FormatMessagesAsPrompt - Extract resolveToolchainPATH to base.ResolveToolchainPATH - Extract buildArgs from execClaude/SendMessage for testability Test improvements: - Add buildArgs tests for all 3 providers (arg construction logic) - Add FormatMessagesAsPrompt tests in base package - Add ResolveToolchainPATH test in base package - Add GenerateMCPConfig_EmptyServers test - Fix Windows CI: use os.PathListSeparator, skip Unix permission checks - Coverage: claudecode 53->63%, codexcli 68->72%, geminicli 57->66% Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cmd/mcp/client/export.go (1)
114-125: Consider consolidatinguppercaseEnvKeyswith the identicalcopyEnvfunction.
uppercaseEnvKeysandcopyEnvinpkg/mcp/client/mcpconfig.godo the same work but differ in nil handling:uppercaseEnvKeysreturnsnil, whilecopyEnvreturns an empty map. With thejson:"env,omitempty"tag on the struct field, this creates inconsistent JSON output (nilomits the field, empty map includes"env": {}). Both are private functions serving identical purposes — extract the shared logic into a single helper to reduce duplication and ensure consistent behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/mcp/client/export.go` around lines 114 - 125, There are two duplicate helpers (uppercaseEnvKeys and copyEnv) with inconsistent nil/empty-map behavior causing different JSON outputs; replace them with a single private helper (e.g., normalizeEnv or copyEnv) used by both call sites, implement it to canonicalize keys to UPPERCASE and choose a consistent nil/empty behavior (pick one and apply everywhere — e.g., return nil when input is nil to keep json:"env,omitempty" omitting the field, or return an empty map if you want the field present), and update all references to use that single function (replace uppercaseEnvKeys and the previous copyEnv usage in pkg/mcp/client/mcpconfig.go and cmd/mcp/client/export.go).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@cmd/mcp/client/export.go`:
- Around line 114-125: There are two duplicate helpers (uppercaseEnvKeys and
copyEnv) with inconsistent nil/empty-map behavior causing different JSON
outputs; replace them with a single private helper (e.g., normalizeEnv or
copyEnv) used by both call sites, implement it to canonicalize keys to UPPERCASE
and choose a consistent nil/empty behavior (pick one and apply everywhere —
e.g., return nil when input is nil to keep json:"env,omitempty" omitting the
field, or return an empty map if you want the field present), and update all
references to use that single function (replace uppercaseEnvKeys and the
previous copyEnv usage in pkg/mcp/client/mcpconfig.go and
cmd/mcp/client/export.go).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: cf2d76bd-781f-456c-8c14-a9922e65a552
📒 Files selected for processing (21)
cmd/ai/init.gocmd/mcp/client/export.godocs/prd/atmos-ai-local-providers.mdpkg/ai/agent/base/config.gopkg/ai/agent/base/config_test.gopkg/ai/agent/base/messages.gopkg/ai/agent/base/messages_tools_test.gopkg/ai/agent/claudecode/client.gopkg/ai/agent/claudecode/client_test.gopkg/ai/agent/codexcli/client.gopkg/ai/agent/codexcli/client_test.gopkg/ai/agent/geminicli/client.gopkg/ai/agent/geminicli/client_test.gopkg/mcp/client/mcpconfig_test.gowebsite/docs/ai/ai.mdxwebsite/docs/ai/troubleshooting.mdxwebsite/docs/cli/commands/ai/ask.mdxwebsite/docs/cli/commands/ai/exec.mdxwebsite/docs/cli/configuration/ai/providers.mdxwebsite/docs/cli/configuration/mcp/index.mdxwebsite/src/data/roadmap.js
✅ Files skipped from review due to trivial changes (8)
- pkg/ai/agent/base/config_test.go
- website/docs/cli/commands/ai/ask.mdx
- pkg/ai/agent/base/messages_tools_test.go
- website/docs/cli/commands/ai/exec.mdx
- cmd/ai/init.go
- website/docs/cli/configuration/mcp/index.mdx
- pkg/ai/agent/geminicli/client_test.go
- pkg/ai/agent/codexcli/client_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
- pkg/mcp/client/mcpconfig_test.go
- website/src/data/roadmap.js
- website/docs/cli/configuration/ai/providers.mdx
- pkg/ai/agent/claudecode/client.go
Examples simplified per team feedback: - ai/README.md: 66 → 46 lines, focus on AI functionality not mock details - ai-claude-code/README.md: 390 → 56 lines, follows quick-start pattern - ai/atmos.yaml: remove auto-compact, workflows, excess providers/comments - ai-claude-code/atmos.yaml: reduce from 8 MCP servers to 2 (aws-docs, aws-billing) - Remove examples/ai/workflows/ (not relevant to AI concept) - Add Atmos Auth prerequisite note with setup link Fix brew install claude → brew install --cask claude-code everywhere: - Blog post, ai.mdx, troubleshooting.mdx, config/ai/index.mdx, PRD (6 files) PRD: add detailed execution flow diagrams for both CLI and API providers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove CLI command reference, config reference, YAML functions, auth/toolchain sections, individual server descriptions, and flow diagram (all in docs). Keep: server table, prerequisites with doc links, Try It, smart routing, IDE integration, and 4 best See It in Action examples. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@examples/mcp/README.md`:
- Line 6: The README references documentation pages that are missing from the
website and causing broken-link checks; add the missing docs under website/docs
with the exact paths mentioned in the README: create cli/configuration/mcp.md
(include the smart-routing section and an anchor matching the README anchor),
cli/configuration/auth.md, and cli/configuration/ai/providers.md with content
that covers the referenced configuration details, or alternatively update the
README links to point to existing docs if these topics are intentionally located
elsewhere; ensure filenames and the smart-routing anchor exactly match the
README references so website builds no longer report broken links.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9ef8ebe4-a129-4628-8a48-a278bd035c85
📒 Files selected for processing (1)
examples/mcp/README.md
|
These changes were released in v1.214.0. |
what
claude-code,codex-cli,gemini-cliAvailable CLI Providers
claude-codeclaudecodex-clicodexgemini-cligeminiMCP Pass-Through
Each provider uses its native config format:
--mcp-config <temp-file>--dangerously-skip-permissions~/.codex/config.toml(backup/restore)--dangerously-bypass-approvals-and-sandbox.gemini/settings.jsonin cwd--approval-mode auto_editQuick Start
See It in Action
Claude Code — Security Posture
Codex CLI — EC2 Billing
Both providers automatically selected the right MCP server and returned answers from real AWS data — no manual server selection needed.
why
Why run Claude Code through Atmos instead of the other way around?
Both directions work — you can start a Claude Code session and call Atmos inside it, or use Atmos to invoke Claude Code. Here's when each approach makes sense:
Starting Claude Code → calling Atmos (via MCP server)
claude # Then inside Claude Code: @atmos-expert "list all stacks"How it works: Claude Code connects to the Atmos MCP server (
atmos mcp start) and uses Atmos tools directly from the IDE.Best for:
Limitations:
.claude/mcp.json)Atmos → starting Claude Code (this PR)
atmos ai ask "What did we spend on EC2 last month?"How it works: Atmos invokes
claude -pas a subprocess, passing MCP servers with auth credentials pre-configured.Best for:
atmos ai ask)atmos.yaml— one config, every developer gets the same toolsKey advantage — centralized MCP + auth orchestration:
When you run
atmos ai ask, Atmos:atmos auth exec -i readonly --)uvxis available--mcp-configWith the "Claude Code first" approach, each developer would need to manually configure AWS credentials, MCP server paths, and toolchain binaries in their personal IDE config.
Summary
atmos.yaml(shared)atmos.yamluvxgloballyatmos ai execwith JSON outputThey're complementary, not competing. Use Claude Code directly for coding sessions in your IDE. Use
atmos ai ask/chatfor quick infrastructure queries with centralized MCP + auth. Both can be configured in the same project.Additional motivation
Key Findings During Implementation
Codex CLI
-cflag overrides do NOT register MCP servers as tools — must write to~/.codex/config.toml--full-autoonly auto-approves file writes, not MCP tool calls — need--dangerously-bypass-approvals-and-sandboxitem.type="agent_message"withitem.textdirectly (not documented"message"with nestedcontent[])ATMOS_*vars must be explicitly injectedGemini CLI
oauth-personalauth) regardless of subscription tiercloudcode-pa.googleapis.comhas MCP feature flag disabled)geminiAPI provider)New Files
Code
pkg/ai/agent/claudecode/— Claude Code CLI provider with MCP pass-throughpkg/ai/agent/codexcli/— OpenAI Codex CLI provider with~/.codex/config.tomlbackup/restore and ATMOS_* injectionpkg/ai/agent/geminicli/— Gemini CLI provider with.gemini/settings.jsonin cwdpkg/mcp/client/mcpconfig.go— Shared MCP config generation (env uppercasing, PATH dedup, toolchain injection)Documentation
website/blog/2026-04-01-ai-cli-providers.mdxexamples/ai-claude-code/— Complete example with AWS MCP servers and automatic authdocs/prd/atmos-ai-local-providers.md(v1.6)ai/ai.mdx,ai/troubleshooting.mdx,cli/configuration/ai/index.mdx,cli/configuration/ai/providers.mdx,cli/configuration/mcp/index.mdx,cli/commands/ai/ask.mdx,cli/commands/ai/exec.mdx,cli/commands/ai/usage.mdxai-assistantinitiativeTests
references
docs/prd/atmos-ai-local-providers.mdwebsite/blog/2026-04-01-ai-cli-providers.mdxexamples/ai-claude-code/Summary by CodeRabbit
New Features
Documentation