This file guides Claude Code when working with this Ansible-based deployment system for setting up development environments on remote Debian VMs.
This project automates the deployment of Claude Code and associated development tools to remote Debian VMs. It creates fully-configured development environments with Git, Docker, Kubernetes, and AI-enhanced capabilities through MCP servers.
Key Point: This runs on your LOCAL machine to deploy TO remote VMs. It does NOT run on the target VMs themselves.
claude-code-vm/
├── config/ # Default configuration templates
│ ├── env.example # Template for credentials and API keys
│ ├── mcp-servers.template.json # MCP server definitions
│ ├── git-repos.env.example # Git repository management template
│ ├── CLAUDE.common.md # Base CLAUDE.md template (shared by all)
│ ├── CLAUDE.minimal.md # Minimal deployment template
│ ├── CLAUDE.enhanced.md # Enhanced deployment with MCP/Docker
│ ├── CLAUDE.containerized.md # Containerized with Docker Compose
│ └── CLAUDE.full.md # Full deployment with Kubernetes
├── ansible/
│ ├── playbooks/ # Main orchestration
│ │ ├── site.yml # Primary deployment playbook
│ │ └── validate.yml # Validation playbook
│ └── roles/ # Modular components
│ ├── common/ # System preparation
│ ├── git/ # Git + credential management
│ ├── docker/ # Docker CE installation
│ ├── nodejs/ # Node.js 22 LTS
│ ├── claude-code/ # Claude Code CLI
│ ├── kubernetes/ # k8s tools (kubectl, k3s/kind)
│ ├── mcp/ # MCP server configuration
│ └── claude-config/ # CLAUDE.md deployment and inheritance
└── Makefile # User interface for all operations
- ENV_FILE:
config/.env(Git credentials, API keys) - MCP_FILE:
config/mcp-servers.json(MCP server definitions) - GIT_CONFIG_FILE: Same as ENV_FILE (repository definitions)
make setup # Create config files from templates
make check-config # Validate configuration
make test-connection VM_HOST=<ip> TARGET_USER=<user> # Test SSH# Tier 1: Minimal (Git + Node.js + Claude Code)
make deploy-baseline VM_HOST=<ip> TARGET_USER=<user>
# Tier 2: Enhanced (+ MCP servers + Docker)
make deploy-enhanced VM_HOST=<ip> TARGET_USER=<user>
# Tier 3: Containerized (+ Docker Compose + shell enhancements)
make deploy-containerized VM_HOST=<ip> TARGET_USER=<user>
# Tier 4: Full (+ Kubernetes with k3s/KIND)
make deploy-full VM_HOST=<ip> TARGET_USER=<user># Validate deployment
make validate VM_HOST=<ip> TARGET_USER=<user>
# Deploy CLAUDE.md and settings.json configuration
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user>
# Deploy only MCP servers
make deploy-mcp VM_HOST=<ip> TARGET_USER=<user>
# Deploy Git repositories
make deploy-git-repos VM_HOST=<ip> TARGET_USER=<user>
# Clean temporary files
make clean# Use configs from another location
make deploy-enhanced VM_HOST=<ip> TARGET_USER=<user> \
ENV_FILE=/path/to/.env \
MCP_FILE=/path/to/mcp-servers.json# Deploy with auto-detected template
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user>
# Deploy with specific template
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user> \
CLAUDE_CONFIG_TEMPLATE=config/CLAUDE.full.md
# Force override existing CLAUDE.md
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user> \
CLAUDE_CONFIG_FORCE_OVERRIDE=true# Simple format in .env or git config file
GITHUB_URL=https://github.com/user/repo.git
# OR
GIT_REPO_1_URL=https://github.com/user/repo.git
GIT_REPO_1_BRANCH=main
# Deploy with repository cloning
make deploy-enhanced VM_HOST=<ip> TARGET_USER=<user> \
MANAGE_GIT_REPOSITORIES=trueWhen modifying this project:
- Use Make targets - Don't run ansible-playbook directly unless necessary
- Test changes - Always run
make check-configbefore deployment - Configuration priority:
- Command-line parameters override everything
- config/ directory contains defaults
- Never hardcode sensitive information
- Error handling - Check the colored output from Make commands
- Validation - Always run
make validateafter deployments
Adding a new MCP server:
- Edit the MCP template:
config/mcp-servers.template.json - Add any required API keys to
config/env.example - Update documentation in README.md
Debugging deployment issues:
# Use verbose mode
make deploy-enhanced VM_HOST=<ip> TARGET_USER=<user> VERBOSE=vv
# Check logs
tail -f deployment.log
# Test specific components
ansible-playbook ansible/playbooks/site.yml --tags docker --checkUpdating components:
- Node.js version: Edit
ansible/inventories/production/group_vars/all.yml - MCP servers: Edit MCP configuration and run
make deploy-mcp - Git repos: Update config file and run
make deploy-git-repos
The system uses config/mcp-servers.template.json as the default configuration:
- No API keys needed: memory, sequential-thinking, puppeteer, doc-forge (4 servers)
- Require API keys: brave-search, context7, omnisearch (3 servers)
- Fully customizable: Edit the template or provide your own
config/mcp-servers.json
The project automatically deploys a CLAUDE.md file to target VMs that provides Claude Code with deployment-specific context:
- Auto-detection: Automatically selects configuration based on deployment tier
- Modular templates: Uses inheritance chain (common → minimal → enhanced → containerized → full)
- Custom templates: Support for project-specific configurations
- Include processing: Templates can include other templates for modularity
config/CLAUDE.common.md # Base configuration (all deployments)
config/CLAUDE.minimal.md # Tier 1: Minimal deployment
config/CLAUDE.enhanced.md # Tier 2: Enhanced with MCP/Docker
config/CLAUDE.containerized.md # Tier 3: With Docker Compose
config/CLAUDE.full.md # Tier 4: Full with Kubernetes
# Auto-detection (default behavior)
make deploy-enhanced VM_HOST=<ip> TARGET_USER=<user>
# Automatically uses config/CLAUDE.enhanced.md
# Custom template
make deploy VM_HOST=<ip> TARGET_USER=<user> \
EXTRA_VARS="claude_config_template=config/CLAUDE.custom.md"
# Force override existing CLAUDE.md
make deploy VM_HOST=<ip> TARGET_USER=<user> \
EXTRA_VARS="claude_config_force_override=true"
# Disable auto-detection
make deploy VM_HOST=<ip> TARGET_USER=<user> \
EXTRA_VARS="claude_config_auto_detect=false claude_config_template=config/CLAUDE.minimal.md"- Create your template in
config/ - Use includes for common content:
<!-- INCLUDE: config/CLAUDE.common.md --> - Add deployment-specific sections
- Deploy with
claude_config_templateparameter
See docs/claude-config.md for detailed documentation.
The system also deploys a settings.json file alongside CLAUDE.md to define allow/deny rules for Claude Code operations:
- Comprehensive allow rules: Safe operations for development tasks
- Security-focused deny rules: Blocks destructive and dangerous operations
- Default template:
config/claude-settings.template.jsonwith pre-configured rules - Customizable: Use your own settings template
# Deploy with default settings
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user>
# Use custom settings template
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user> \
CLAUDE_SETTINGS_TEMPLATE=config/custom-settings.json
# Force override existing settings.json
make deploy-claude-config VM_HOST=<ip> TARGET_USER=<user> \
CLAUDE_SETTINGS_FORCE_OVERRIDE=true- ✅ Allowed: Docker, Kubernetes, Git (branch/merge, no basic push), Make, npm, find, file operations, SSH to private networks (10.0.0., 192.168.), project-safe rm -rf
- ❌ Denied: Destructive operations, privilege escalation, credential exposure, system shutdown, force git push to main/master
- ❓ Not included: Basic git push (neither allowed nor denied - requires explicit permission)
- Dynamic Inventory: The Makefile creates temporary inventories - don't edit
hosts.ymldirectly - External Dependencies: Automatically downloaded to
.external-tools/and.external-roles/ - Sensitive Data: Keep credentials in external files, never commit them
- Validation: The MCP management tool's validation is used, not custom implementations
If deployment fails:
- Run
make test-connectionto verify SSH access - Check
deployment.logfor detailed errors - Ensure target VM is Debian 12+ with sudo access
- Verify all required API keys are in your .env file
- For MCP issues, check with
make list-remote SSH_HOST=<ip> SSH_USER=<user>
Remember: This project follows Ansible best practices and uses Make as the primary interface to ensure consistent, reliable deployments.