From 23524659e83a6e71eda97ff015cd00849f31e1bb Mon Sep 17 00:00:00 2001 From: Vishal Jain Date: Wed, 11 Jun 2025 10:29:15 +0100 Subject: [PATCH] Initial commit: Claude Docker setup - Dockerfile with Claude Code and Twilio MCP integration - Wrapper script for easy invocation from anywhere - Auto-setup of .claude directory in projects - SMS notifications via Twilio when tasks complete - Installation script for zshrc alias - Full autonomous permissions with --dangerously-skip-permissions - Context persistence via scratchpad.md --- .env.example | 11 ++++++++ .gitignore | 28 +++++++++++++++++++++ Dockerfile | 40 +++++++++++++++++++++++++++++ LICENSE | 21 ++++++++++++++++ README.md | Bin 0 -> 1889 bytes config/mcp-config.json | 14 +++++++++++ scratchpad.md | 26 +++++++++++++++++++ scripts/claude-docker.sh | 49 ++++++++++++++++++++++++++++++++++++ scripts/install.sh | 40 +++++++++++++++++++++++++++++ scripts/startup.sh | 23 +++++++++++++++++ templates/.claude/CLAUDE.md | 28 +++++++++++++++++++++ templates/scratchpad.md | 16 ++++++++++++ 12 files changed, 296 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 config/mcp-config.json create mode 100644 scratchpad.md create mode 100755 scripts/claude-docker.sh create mode 100755 scripts/install.sh create mode 100755 scripts/startup.sh create mode 100644 templates/.claude/CLAUDE.md create mode 100644 templates/scratchpad.md diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..993fbef --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# ABOUTME: Environment variables for Claude Docker +# ABOUTME: Copy this to ~/.claude-docker/.env and fill in your values + +# Anthropic API key for Claude Code +ANTHROPIC_API_KEY=your_anthropic_api_key_here + +# Twilio credentials for SMS notifications +TWILIO_ACCOUNT_SID=your_twilio_account_sid +TWILIO_AUTH_TOKEN=your_twilio_auth_token +TWILIO_PHONE_NUMBER=+1234567890 # Your Twilio phone number +YOUR_PHONE_NUMBER=+1234567890 # Your personal phone to receive SMS \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a8795d --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Environment variables +.env +.env.local + +# OS files +.DS_Store +Thumbs.db + +# IDE files +.idea/ +.vscode/ +*.swp +*.swo + +# Logs +*.log +logs/ + +# Node modules (if any local testing) +node_modules/ + +# Docker volumes +data/ + +# Temporary files +*.tmp +*.temp +~* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9a4f66e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +# ABOUTME: Docker image for Claude Code with Twilio MCP server +# ABOUTME: Provides autonomous Claude Code environment with SMS notifications + +FROM node:20-slim + +# Install required system dependencies +RUN apt-get update && apt-get install -y \ + git \ + curl \ + python3 \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +# Create app directory +WORKDIR /app + +# Install Claude Code globally +RUN npm install -g @anthropic-ai/claude-code + +# Install Twilio MCP server +RUN npm install -g @twilioalpha/mcp-server-twilio + +# Create directories for configuration +RUN mkdir -p /app/config /app/.claude + +# Copy MCP configuration +COPY config/mcp-config.json /app/config/ + +# Copy startup script +COPY scripts/startup.sh /app/ +RUN chmod +x /app/startup.sh + +# Set working directory to mounted volume +WORKDIR /workspace + +# Environment variables will be passed from host +ENV NODE_ENV=production + +# Start both MCP server and Claude Code +ENTRYPOINT ["/app/startup.sh"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..211a4da --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Vishal Jain + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..64b86e0d7dfada6d5c3c5a4239aa75928578e9a2 GIT binary patch literal 1889 zcmZ`)%WfMt6b-uMvM9Rh;sV+vDrVF?`mg~PP-O*HZ9Qs94T7SOXbz=eG$K`!BU@P% z{n36z|DcDQkv(o)uWa+a&b{ZHX;H7>WhUv|h>f(2b?e_q811>z($dOUvZdBauaD6^ zgOpq4b6S-}LA>-vo2@Aw?WEl*=akWoxXx&Hs|sakI-HU=UageiK0Kz3wOaI6a$j2M z7)$8KFX=6c9h%kZ;bJ?f_sSZ*mD(fv?4M6-(q8dn!`obH^4x74kZgB_^fF|9PE)>; z58%{CnUTDcq6|}oh`(s6LOdBQ6Qphf3Z?g^8a#yjO+73}-uZymDd(jYl5V8Gm1yc@ z1wR7(rBq@=Q_rmrf4AsmiXEbKT+To{&x?Yw<#Kt$UC!3ZlZel`_d9pm>EJ(kd6Qz0 z&acYly!iR#q$A?Zk}TdVMFnOf3mdWgjGB5I;v`tqP#Pu#iW0B(vL2;BDAfh zdWETsUa2*XLEXuKF69A7>1UW{iSS3YJ1I`Ftj>QxMG{tKxQgP1JAJ^?9nCJT$CE*C zfr5+6{`<2Kyx7RYB9~UO*}K8jV7%z|dgJ+MwwMmis{p66#{u)%#bP$T?2oEMus~;ZObRv#(#idj00x@4o-xgV;kE?9b6MNiwe2(!vdjL*h1Smo#96MZi)T zu5n;keY-vEO@PPlr46M9(AV0cxjPCvq_Bji=t0A{bI+F$;%E>O*zdSI?eNea#O2_oqc&cwho0goUxs@E+ow^d7e9 z(gOBTq#vBoL@f$f;jd9|(GFw67f9$`b?4`O4BTkYqT_r)%3;D_pe%$x!uTlV35Pn$ z9a4|37F~B)v3N;G^3^l|14L;pWKEf}5P-1 zA34WBLcoT@G*L58Ah{Pn{N5y(&+NfAzVcA1yo0AEG=c@(7s`$EcdjJ3c literal 0 HcmV?d00001 diff --git a/config/mcp-config.json b/config/mcp-config.json new file mode 100644 index 0000000..03e6875 --- /dev/null +++ b/config/mcp-config.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "twilio": { + "command": "node", + "args": ["/usr/lib/node_modules/@twilioalpha/mcp-server-twilio/build/index.js"], + "env": { + "TWILIO_ACCOUNT_SID": "${TWILIO_ACCOUNT_SID}", + "TWILIO_AUTH_TOKEN": "${TWILIO_AUTH_TOKEN}", + "TWILIO_PHONE_NUMBER": "${TWILIO_PHONE_NUMBER}", + "YOUR_PHONE_NUMBER": "${YOUR_PHONE_NUMBER}" + } + } + } +} \ No newline at end of file diff --git a/scratchpad.md b/scratchpad.md new file mode 100644 index 0000000..b633f88 --- /dev/null +++ b/scratchpad.md @@ -0,0 +1,26 @@ +# Claude Docker Project Scratchpad + +## Project Overview +Building a Docker container that runs Claude Code with full autonomous permissions and Twilio SMS notifications upon task completion. + +## Current Tasks +- Setting up GitHub repository ✓ +- Creating project structure +- Building Docker environment with Claude Code + Twilio MCP +- Creating helper scripts for easy invocation + +## Decisions Log +- Using MCP (Model Context Protocol) for Twilio integration instead of direct API +- Single container approach (no Docker Compose needed) +- API keys via .env file +- Context persistence via scratchpad.md files + +## Notes & Context +- Repository created at: https://github.com/VishalJ99/claude-docker +- Using --dangerously-skip-permissions flag for full autonomy +- Twilio MCP server will run alongside Claude Code in container + +## Quick References +- Claude Code docs: https://docs.anthropic.com/en/docs/claude-code +- MCP docs: https://modelcontextprotocol.io/ +- Twilio MCP: https://twilioalpha.com/mcp \ No newline at end of file diff --git a/scripts/claude-docker.sh b/scripts/claude-docker.sh new file mode 100755 index 0000000..6ee6c93 --- /dev/null +++ b/scripts/claude-docker.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# ABOUTME: Wrapper script to run Claude Code in Docker container +# ABOUTME: Handles project mounting, .claude setup, and environment variables + +# Get the absolute path of the current directory +CURRENT_DIR=$(pwd) +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Check if .claude directory exists in current project, create if not +if [ ! -d "$CURRENT_DIR/.claude" ]; then + echo "Creating .claude directory for this project..." + mkdir -p "$CURRENT_DIR/.claude" + + # Copy template files + cp "$PROJECT_ROOT/templates/.claude/settings.local.json" "$CURRENT_DIR/.claude/" + cp "$PROJECT_ROOT/templates/.claude/CLAUDE.md" "$CURRENT_DIR/.claude/" + + # Create scratchpad.md if it doesn't exist + if [ ! -f "$CURRENT_DIR/scratchpad.md" ]; then + cp "$PROJECT_ROOT/templates/scratchpad.md" "$CURRENT_DIR/" + fi + + echo "✓ Claude configuration created" +fi + +# Check if .env file exists in user's home claude-docker directory +ENV_FILE="$HOME/.claude-docker/.env" +if [ ! -f "$ENV_FILE" ]; then + echo "⚠️ No .env file found at $ENV_FILE" + echo "Please create it with your API keys. See .env.example for reference." + exit 1 +fi + +# Build the Docker image if it doesn't exist +if ! docker images | grep -q "claude-docker"; then + echo "Building Claude Docker image..." + docker build -t claude-docker:latest "$PROJECT_ROOT" +fi + +# Run Claude Code in Docker +echo "Starting Claude Code in Docker..." +docker run -it --rm \ + -v "$CURRENT_DIR:/workspace" \ + -v "$ENV_FILE:/app/.env:ro" \ + -v "$HOME/.claude-docker/config:/app/.claude:rw" \ + --workdir /workspace \ + --name claude-docker-session \ + claude-docker:latest "$@" \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..07cdbc5 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# ABOUTME: Installation script for claude-docker +# ABOUTME: Sets up alias and creates config directory + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Create config directory +mkdir -p "$HOME/.claude-docker/config" + +# Copy example env file if doesn't exist +if [ ! -f "$HOME/.claude-docker/.env" ]; then + cp "$PROJECT_ROOT/.env.example" "$HOME/.claude-docker/.env" + echo "⚠️ Created .env file at $HOME/.claude-docker/.env" + echo " Please edit it with your API keys!" +fi + +# Add alias to .zshrc +ALIAS_LINE="alias claude='$PROJECT_ROOT/scripts/claude-docker.sh'" + +if ! grep -q "alias claude=" "$HOME/.zshrc"; then + echo "" >> "$HOME/.zshrc" + echo "# Claude Docker alias" >> "$HOME/.zshrc" + echo "$ALIAS_LINE" >> "$HOME/.zshrc" + echo "✓ Added 'claude' alias to .zshrc" +else + echo "✓ Claude alias already exists in .zshrc" +fi + +# Make scripts executable +chmod +x "$PROJECT_ROOT/scripts/claude-docker.sh" +chmod +x "$PROJECT_ROOT/scripts/startup.sh" + +echo "" +echo "Installation complete! 🎉" +echo "" +echo "Next steps:" +echo "1. Edit $HOME/.claude-docker/.env with your API keys" +echo "2. Run 'source ~/.zshrc' or start a new terminal" +echo "3. Navigate to any project and run 'claude' to start" \ No newline at end of file diff --git a/scripts/startup.sh b/scripts/startup.sh new file mode 100755 index 0000000..09daec9 --- /dev/null +++ b/scripts/startup.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# ABOUTME: Startup script for Claude Code container with MCP server +# ABOUTME: Launches Twilio MCP server then starts Claude Code with permissions bypass + +# Load environment variables from .env if it exists +if [ -f /app/.env ]; then + export $(cat /app/.env | grep -v '^#' | xargs) +fi + +# Start Twilio MCP server in the background +echo "Starting Twilio MCP server..." +npx @twilioalpha/mcp-server-twilio & +MCP_PID=$! + +# Give MCP server time to start +sleep 2 + +# Configure Claude Code to use the MCP server +export CLAUDE_MCP_CONFIG=/app/config/mcp-config.json + +# Start Claude Code with permissions bypass +echo "Starting Claude Code..." +exec claude-code --dangerously-skip-permissions "$@" \ No newline at end of file diff --git a/templates/.claude/CLAUDE.md b/templates/.claude/CLAUDE.md new file mode 100644 index 0000000..2cb0542 --- /dev/null +++ b/templates/.claude/CLAUDE.md @@ -0,0 +1,28 @@ +# Claude Docker Project Context + +This is a containerized Claude Code environment with full autonomous permissions. + +## Important Instructions + +1. **Context Persistence**: Always check for and use `scratchpad.md` in the project root: + - Read it at the start of each session to understand project state + - Update it throughout your work to track progress + - Use it to maintain context between sessions + +2. **Task Completion Notifications**: When you complete a major task: + - Send an SMS notification using the Twilio MCP server + - Format: "✅ Task complete | Task: [brief description] | Done: [what was accomplished]" + - Keep it concise - just the essentials + +3. **Working Environment**: You have full permissions to: + - Execute any bash commands + - Edit/create/delete any files + - Access web resources + - Manage the project autonomously + +## MCP Server Available +- Twilio MCP server is running and available for SMS notifications +- Use natural language to send SMS messages +- Example: "Send SMS to notify that the task is complete" + +Remember: You're working in a safe containerized environment, so you can operate with full autonomy. \ No newline at end of file diff --git a/templates/scratchpad.md b/templates/scratchpad.md new file mode 100644 index 0000000..39e590d --- /dev/null +++ b/templates/scratchpad.md @@ -0,0 +1,16 @@ +# Project Scratchpad + +## Project Overview +[Project description will be added here by Claude] + +## Current Tasks +[Active tasks being worked on] + +## Decisions Log +[Important decisions and their rationale] + +## Notes & Context +[Key insights, findings, and context] + +## Quick References +[Useful commands, paths, or references] \ No newline at end of file