Repository navigation
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>
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. |
1 similar comment
|
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