AI Agents Integration Guide¶
Pre-installed AI agents in Docker development environment - Complete guide to using Claude Code and Gemini CLI.
Table of Contents¶
- Overview
- Architecture
- Pre-Installed Agents
- How Agents Access Secrets
- Multiple Identity Management
- Integration with dev()
- Usage Examples
- The .ai-context.md Standard
- Troubleshooting
Overview¶
What Are AI Agents?¶
AI Agents are command-line tools that provide AI assistance directly in your development environment:
- Claude Code: Anthropic's AI coding assistant (version 2.0.76)
- Gemini CLI: Google's AI assistant (version 0.22.2)
Both are pre-installed in the my-dev-env:latest Docker image, so you don't need to install them every time.
Key Benefits¶
- ✅ Pre-installed: No installation time, ready immediately
- ✅ Secure: API keys loaded from Infisical at runtime
- ✅ Multiple Identities: Switch between personal/edu/work accounts
- ✅ Isolated: Agents run in container, can't access host secrets
- ✅ Consistent: Same tools, same versions across all machines
Architecture¶
The Three-Layer Model¶
┌─────────────────────────────────────────────────────┐
│ HOST (Server) │
│ ┌────────────────────────────────────────────────┐ │
│ │ Infisical (secrets.kua.cl) │ │
│ │ - ANTHROPIC_API_KEY │ │
│ │ - GOOGLE_API_KEY │ │
│ │ │ │
│ │ dev() fetches → /tmp/env-$$.list │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ AI Account Files (Host Storage) │ │
│ │ ~/.gemini/oauth-edu1.json │ │
│ │ ~/.claude/session-personal.json │ │
│ │ ~/.openai/session-chatgpt.json │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────┬───────────────────────────────────┘
│ Docker run --env-file + -v mounts
▼
┌─────────────────────────────────────────────────────┐
│ CONTAINER (my-dev-env:latest) │
│ ┌────────────────────────────────────────────────┐ │
│ │ Pre-installed Tools (Baked into Image) │ │
│ │ ✅ Claude Code 2.0.76 │ │
│ │ ✅ Gemini CLI 0.22.2 │ │
│ │ ❌ NO secrets baked in │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Runtime-Injected (via dev()) │ │
│ │ Environment Variables: │ │
│ │ ANTHROPIC_API_KEY=sk-ant-... │ │
│ │ GOOGLE_API_KEY=AIza... │ │
│ │ │ │
│ │ Mounted Files (read-only): │ │
│ │ /root/.gemini/oauth_creds.json │ │
│ │ /root/.config/claude/config.json │ │
│ │ /root/.openai/session.json │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Usage │ │
│ │ $ claude │ │
│ │ → Uses ANTHROPIC_API_KEY from env │ │
│ │ → Uses session from config.json │ │
│ │ │ │
│ │ $ gemini │ │
│ │ → Uses GOOGLE_API_KEY from env │ │
│ │ → Uses OAuth from oauth_creds.json │ │
│ └────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Why This Architecture?¶
Tools in Image, Credentials on Host
- Security: No secrets baked into Docker image
- Flexibility: Switch identities without rebuilding image
- Portability: Same image works across all machines
- Updates: Update secrets without touching Docker image
Pre-Installed Agents¶
Claude Code 2.0.76¶
What it does: AI-powered code assistant from Anthropic
Installation in image:
Version pinned: Yes (2.0.76) - ensures consistency
Command: claude
Requires:
- ANTHROPIC_API_KEY environment variable
- Optional: Session file at /root/.config/claude/config.json
Features: - Code generation and editing - Multi-file operations - Git integration - Terminal access - File system operations
Gemini CLI 0.22.2¶
What it does: AI assistant from Google
Installation in image:
Version pinned: Yes (0.22.2) - ensures consistency
Command: gemini
Requires:
- GOOGLE_API_KEY environment variable
- OAuth credentials file at /root/.gemini/oauth_creds.json
Features: - Conversational AI assistance - Code analysis and generation - Multi-turn conversations - File operations
Why Pre-Install?¶
Without pre-installation (old approach):
# Inside container every time
npm install -g @anthropic-ai/claude-code # 30-60 seconds
npm install -g @google/gemini-cli # 30-60 seconds
# Total: 1-2 minutes wasted every session
With pre-installation (current approach):
# Tools already there, ready immediately
claude --version # Works instantly
gemini --version # Works instantly
Benefits:
- ⚡ Instant startup
- 🔒 Version consistency (no unexpected updates)
- 📦 Smaller node_modules in projects (global install)
- 🚀 Faster iteration cycles
How Agents Access Secrets¶
Environment Variables (API Keys)¶
AI agents read API keys from environment variables, injected at runtime by dev():
Flow:
# On host
dev my-project
# dev() function does:
infisical export --env=dev --projectId=personal-vault > /tmp/env-$$.list
# File contains:
# ANTHROPIC_API_KEY=sk-ant-api03-...
# GOOGLE_API_KEY=AIza...
# Docker launch:
docker run --env-file /tmp/env-$$.list ...
# Inside container:
$ env | grep API_KEY
ANTHROPIC_API_KEY=sk-ant-api03-...
GOOGLE_API_KEY=AIza...
$ claude
# Claude reads ANTHROPIC_API_KEY automatically
$ gemini
# Gemini reads GOOGLE_API_KEY automatically
Key insight: Agents NEVER ask for API keys - they expect them in the environment.
Session Files (OAuth/State)¶
Some agents need additional session/OAuth files for authentication:
Gemini OAuth:
# Host: ~/.gemini/oauth-edu1.json
# Container: /root/.gemini/oauth_creds.json (read-only mount)
docker run -v ~/.gemini/oauth-edu1.json:/root/.gemini/oauth_creds.json:ro ...
Claude Session:
# Host: ~/.claude/session-personal.json
# Container: /root/.config/claude/config.json (read-only mount)
docker run -v ~/.claude/session-personal.json:/root/.config/claude/config.json:ro ...
OpenAI Session:
# Host: ~/.openai/session-chatgpt.json
# Container: /root/.openai/session.json (read-only mount)
docker run -v ~/.openai/session-chatgpt.json:/root/.openai/session.json:ro ...
Why read-only (:ro)?
- Agents can't modify host credentials
- Prevents accidental corruption
- Security best practice
Multiple Identity Management¶
The Problem¶
You may have multiple AI accounts: - Personal: Your own accounts - Educational: University/school accounts (edu1, edu2, edu3, edu4) - Work: Employer-provided accounts
Challenge: How to switch between them?
The Solution: File-Based Identity Switching¶
Strategy: Store each identity's credentials in separate files on the host, mount the desired one at runtime.
Directory Structure¶
~/.gemini/
├── oauth-edu1.json # Education account 1
├── oauth-edu2.json # Education account 2
├── oauth-edu3.json # Education account 3
└── oauth-edu4.json # Education account 4
~/.claude/
├── session-personal.json # Personal account
├── session-edu1.json # Education account 1
├── session-edu2.json # Education account 2
└── session-work.json # Work account
~/.openai/
├── session-chatgpt.json # Personal ChatGPT
├── session-edu1.json # Education account 1
├── session-edu2.json # Education account 2
└── session-work.json # Work account
How dev() Handles Selection¶
The dev() function prompts you to select which identity to use:
Gemini Account Prompt:
Claude Account Prompt:
🧠 Select Claude Account:
[1] personal (default)
[2] edu1
[3] edu2
[4] work
[0] Skip (no Claude session)
👉 Choose (0-4):
OpenAI Account Prompt:
🔮 Select OpenAI/ChatGPT Account:
[1] chatgpt (default)
[2] edu1
[3] edu2
[4] work
[0] Skip (no OpenAI session)
👉 Choose (0-4):
What happens:
1. You select an identity (e.g., 2 for edu1)
2. dev() sets OAUTH_FILE="$HOME/.gemini/oauth-edu2.json"
3. Docker mounts that specific file: -v "$OAUTH_FILE":/root/.gemini/oauth_creds.json:ro
4. Inside container, Gemini uses that identity
Benefits¶
- ✅ No rebuilding: Switch identities without rebuilding Docker image
- ✅ Isolated: Each account's credentials stored separately
- ✅ Flexible: Mix and match (Gemini edu1 + Claude personal)
- ✅ Auditable: Know which identity was used for which session
Integration with dev()¶
Complete Flow¶
Here's how dev() integrates AI agent selection:
Step-by-step:
-
Project Selection:
-
Infisical Selection:
-
AI Account Selection (Sequential prompts):
-
Secrets Fetch:
-
Docker Launch:
-
Inside Container:
Code Reference¶
See the complete dev() function implementation in dev-function.md:3
Usage Examples¶
Example 1: Using Claude for Code Review¶
# On server
dev my-app
# Prompts:
# Project: my-app
# Infisical: personal-vault / dev
# Gemini: edu1
# Claude: personal
# OpenAI: skip
# Inside container
cd /app/my-app
# Start Claude
claude
# Claude prompt
> Review the authentication logic in src/auth.js and suggest security improvements
What happens:
- Claude reads ANTHROPIC_API_KEY from environment
- Uses session from /root/.config/claude/config.json
- Analyzes src/auth.js
- Provides security recommendations
Example 2: Using Gemini for Documentation¶
# Inside container
gemini
# Gemini prompt
> Generate API documentation for the functions in src/api.js
What happens:
- Gemini reads GOOGLE_API_KEY from environment
- Uses OAuth from /root/.gemini/oauth_creds.json
- Analyzes src/api.js
- Generates documentation
Example 3: Switching Identities Mid-Work¶
Scenario: You started with personal Claude, but need to switch to work account.
Solution: Exit and re-launch with different identity:
# Inside container
exit
# Back on host
dev my-app
# This time select:
# Claude: work (instead of personal)
# Inside new container
claude
# Now using work account
The .ai-context.md Standard¶
What Is It?¶
.ai-context.md is a "Constitution" file for AI agents in your project. It defines:
- Environment constraints
- Security protocols
- Tech stack preferences
- Coding standards
Location: /app/<project>/.ai-context.md (inside container)
Why It Exists¶
Without .ai-context.md: - AI agents don't know project constraints - May ask for API keys (violating security protocol) - May use wrong tools or patterns - Inconsistent behavior across sessions
With .ai-context.md: - AI agents self-configure - Follow project standards - Respect security boundaries - Consistent behavior
Template¶
Every project should have this file:
# AI Development Environment Context
## 1. Environment & Architecture
- **Runtime:** Docker Container (Ubuntu/Debian based).
- **Filesystem:**
- The host's `~/Coding` directory is mounted to `/app`.
- Current Project Root: `/app/<project-name>`
- **Identity:**
- Host `~/.gitconfig` is mounted read-only (Git identity is preserved).
- Host `~/.ssh` is mounted read-only (SSH keys are available).
## 2. Security & Secrets Protocol
- **Secrets Manager:** Infisical is the Single Source of Truth.
- **Access Method:** Environment Variables (injected at runtime).
- **Rule:** **NEVER** ask the user for API keys, passwords, or secrets.
- **Missing Secrets:** If a required secret (e.g., `DB_PASSWORD`, `OPENAI_API_KEY`) is missing,
instruct the user to add it to Infisical:
```bash
infisical secrets set KEY_NAME="value" --env=dev --projectId=personal-vault
```
## 3. Tooling & Workflow
- **Node.js:** Available (version: detect with `node --version`).
- **Python:** Available (version: detect with `python --version`).
- **Docker:** Container cannot spawn sibling containers unless socket is mounted.
- **Editor:** User edits on Host (VS Code/Cursor), Agent edits inside Container (CLI).
## 4. Coding Standards
- **Style:** Adhere to existing `.eslintrc`, `.prettierrc`, or `flake8` configurations.
- **Tests:** Always run tests after modification if a test script exists.
- **Commits:** Use conventional commit format: `type(scope): message`
## 5. Project-Specific Settings
- **Language:** [Auto-detect or specify: Python, Node.js, Go, etc.]
- **Start Command:** `npm start` / `python main.py` / etc.
- **Test Command:** `npm test` / `pytest` / etc.
- **Build Command:** `npm run build` / `go build` / etc.
How to Use¶
Creating for new project:
# Inside container
cd /app/my-new-project
cat > .ai-context.md << 'EOF'
# AI Development Environment Context
[... paste template above ...]
EOF
AI agents will read it automatically when they: - Analyze project structure - Need to understand constraints - Make decisions about tools or patterns
Real Example¶
From /Users/kavi/Coding/.ai-context.md:
# AI Development Environment Context
## 1. Environment & Architecture
- **Runtime:** Docker Container (Ubuntu/Debian based).
- **Filesystem:**
- The host's `~/Coding` directory is mounted to `/app`.
- Current Project Root: Determined by the working directory inside `/app`.
- **Identity:**
- Host `~/.gitconfig` is mounted read-only (Git identity is preserved).
- Host `~/.ssh` is mounted read-only (SSH keys are available).
## 2. Security & Secrets Protocol
- **Secrets Manager:** Infisical is the Single Source of Truth.
- **Access Method:** Environment Variables (injected at runtime).
- **Rule:** **NEVER** ask the user for API keys, passwords, or secrets.
This ensures AI agents:
- Know they're in a Docker container
- Understand /app is the project root
- NEVER ask for API keys (they're already in environment)
- Know to use Infisical for missing secrets
Troubleshooting¶
"ANTHROPIC_API_KEY not found"¶
Symptom: Claude says API key is missing
Causes: 1. Secret not in Infisical 2. Wrong Infisical project/environment selected 3. dev() didn't fetch secrets properly
Solution:
# Exit container
exit
# Check Infisical has the key
infisical secrets --env=dev --projectId=personal-vault | grep ANTHROPIC_API_KEY
# If missing, add it:
infisical secrets set ANTHROPIC_API_KEY="sk-ant-..." --env=dev --projectId=personal-vault
# Re-launch
dev my-project
"OAuth file not found" (Gemini)¶
Symptom: Gemini fails with "oauth_creds.json not found"
Causes: 1. OAuth file doesn't exist on host 2. dev() didn't mount the file 3. Wrong account selected
Solution:
# Check file exists on host
ls -la ~/.gemini/oauth-edu1.json
# If missing, you need to authenticate that account first
# (See Multi-Identity Guide for OAuth setup)
# If file exists, re-run dev() and ensure you select the correct account
"Session expired" (Claude)¶
Symptom: Claude says session is invalid/expired
Cause: Session file is outdated
Solution:
# Exit container
exit
# On host, re-authenticate Claude
# (This updates the session file)
# Re-launch dev()
dev my-project
Agent installed but won't run¶
Symptom: claude: command not found or gemini: command not found
Cause: Docker image is outdated (doesn't have agents pre-installed)
Solution:
# Exit container
exit
# Rebuild Docker image with latest version
docker build -t my-dev-env:latest /path/to/dockerfile
# Verify agents are installed
docker run --rm my-dev-env:latest claude --version
docker run --rm my-dev-env:latest gemini --version
# Re-launch
dev my-project
Multiple identities not working¶
Symptom: Selected edu1 but using personal account
Cause: dev() didn't mount the correct file
Debug:
# Inside container, check which file is mounted
ls -la /root/.gemini/oauth_creds.json
ls -la /root/.config/claude/config.json
# Exit and check dev() function
exit
# Verify dev() script has correct mount logic
grep -A5 "OAUTH_FILE" ~/.zshrc # or ~/.bashrc
Summary¶
AI Agents Integration: - ✅ Claude Code and Gemini CLI pre-installed in Docker image - ✅ API keys loaded from Infisical at runtime (environment variables) - ✅ Multiple identities via file-based switching (OAuth/session files) - ✅ Seamless integration with dev() function - ✅ Security via read-only mounts and no secrets in image - ✅ Consistency via .ai-context.md standard
Key Principles: 1. Tools in image, credentials on host - separation of concerns 2. Never ask for secrets - agents expect them in environment 3. Identity files on host - mount at runtime for flexibility 4. Version pinning - consistent behavior across machines 5. .ai-context.md - project-specific rules and constraints
What's Next: - Learn about Multi-Identity Management - detailed OAuth/session setup - Learn about .ai-context.md Standard - complete guide - Learn about dev() Function - how orchestration works - Learn about Docker Environment - image architecture