Repository: devcontainer-for-claude-yolo-and-flow-next
A layered devcontainer for Claude Code with browser automation, workflow tooling, and Python/Node development.
The devcontainer adapts the Anthropic Devcontainer reference implementation to allow the use of the Claude Code flow-next-Plugin in combination with Repo Prompt over an MCP-Server (by mcp-proxy).
The aim is to use Claude Code with --dangerously-skip-permissions (aka YOLO-mode) and the awesome flow-next plugin in a docker environment with firewall.
IMPORTANT: The docker container mounts the hosts claude-config and updates the plugins on build. If this is not wanted, please change the script accordingly.
| Component | Purpose |
|---|---|
| Claude Code CLI | Anthropic's AI coding assistant |
| Repo Prompt MCP | Context building via Mac host bridge |
| agent-browser | Browser automation CLI (Vercel, via flow-next) |
| flow-next | Planning/execution workflow (Gordon Mickel) |
| Playwright | E2E testing (pytest-playwright) |
| Python 3.14 + uv | Python development |
| Node 20 | JavaScript/TypeScript development |
┌─────────────────────────────────────────────────────────────────────────┐
│ LAYER 1: mcr.microsoft.com/playwright:v1.57.0-noble │
│ Ubuntu 24.04 · Node 20 · Chromium · Firefox · WebKit │
├─────────────────────────────────────────────────────────────────────────┤
│ LAYER 2: Anthropic Claude Code essentials │
│ Claude Code CLI · iptables/ipset · firewall script │
├─────────────────────────────────────────────────────────────────────────┤
│ LAYER 3: Common dev tools │
│ zsh · fzf · git-delta · gh · jq · ripgrep · fd │
│ Python 3.14 (via uv) · ruff · agent-browser │
├─────────────────────────────────────────────────────────────────────────┤
│ LAYER 4: postCreateCommand (always fresh) │
│ flow-next plugin · Repo Prompt MCP config │
└─────────────────────────────────────────────────────────────────────────┘
▲
│ MCP bridge (port 8096)
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ MAC HOST │
│ mcp-proxy :8096 ◄── ~/RepoPrompt/repoprompt_cli │
└─────────────────────────────────────────────────────────────────────────┘
git clone https://github.com/Ranudar/devcontainer-for-claude-yolo-and-flow-next.git
cd devcontainer-for-claude-yolo-and-flow-next.devcontainer/
├── devcontainer.json
├── Dockerfile
├── init-firewall.sh
└── setup-plugins.sh
# Install
uv tool install mcp-proxy # or: pipx install mcp-proxy
# Copy script
mkdir -p ~/bin
cp mac-host/start-repoprompt-bridge.sh ~/bin/
chmod +x ~/bin/start-repoprompt-bridge.sh
# Run (keep open)
~/bin/start-repoprompt-bridge.shOptional: manage the bridge with a LaunchAgent (manual start/stop, no auto-run on login):
# Install agent (does not start yet)
cp mac-host/com.repoprompt.mcp-bridge.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.repoprompt.mcp-bridge.plist
# Start when needed (e.g., before opening the devcontainer)
launchctl kickstart -k gui/$(id -u)/com.repoprompt.mcp-bridge
# Stop when done (stays stopped)
launchctl stop gui/$(id -u)/com.repoprompt.mcp-bridge
# Uninstall
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.repoprompt.mcp-bridge.plist
rm ~/Library/LaunchAgents/com.repoprompt.mcp-bridge.plistFor convenience, add these shell functions to your ~/.zshrc:
# MCP Bridge control (RepoPrompt SSE bridge for devcontainers)
mcp-bridge() {
if lsof -i :8096 &>/dev/null; then
local pid=$(lsof -t -i :8096)
echo "ℹ mcp-bridge already running (PID $pid, port 8096)"
echo " Container URL: http://host.docker.internal:8096/sse"
echo ""
echo " Commands:"
echo " mcp-bridge-stop Stop the bridge"
echo " mcp-bridge-status Check if running"
echo " mcp-bridge-log Tail the log file"
return 0
fi
launchctl kickstart -k gui/$(id -u)/com.repoprompt.mcp-bridge 2>/dev/null
sleep 1
if lsof -i :8096 &>/dev/null; then
echo "✓ mcp-bridge started (listening on port 8096)"
echo " Container URL: http://host.docker.internal:8096/sse"
echo ""
echo " Commands:"
echo " mcp-bridge-stop Stop the bridge"
echo " mcp-bridge-status Check if running"
echo " mcp-bridge-log Tail the log file"
else
echo "✗ mcp-bridge failed to start"
echo " Check errors: cat /tmp/repoprompt-bridge.err"
return 1
fi
}
mcp-bridge-stop() {
launchctl kill SIGTERM gui/$(id -u)/com.repoprompt.mcp-bridge 2>/dev/null
echo "✓ mcp-bridge stopped"
}
mcp-bridge-status() {
if lsof -i :8096 &>/dev/null; then
local pid=$(lsof -t -i :8096)
echo "✓ mcp-bridge running (PID $pid, port 8096)"
else
echo "✗ mcp-bridge not running"
return 1
fi
}
alias mcp-bridge-log='tail -f /tmp/repoprompt-bridge.log'Then use: mcp-bridge to start, mcp-bridge-stop to stop, mcp-bridge-status to check, mcp-bridge-log to tail logs.
Command Palette → Reopen in Container
claude --dangerously-skip-permissions
/mcp # Verify connections
/flow-next:setup # One-time setupAfter opening the container, run these tests to verify all components work:
# Check versions
node --version # Should show v20.x
python3.14 --version # Should show Python 3.14.x
uv --version # Should show uv 0.x
ruff --version # Should show ruff 0.x
agent-browser --version # Should show 0.x
playwright --version # Should show Version 1.57.x
# Check shell
echo $SHELL # Should show /bin/zsh# First, ensure the bridge is running on Mac:
# ~/bin/start-repoprompt-bridge.sh
# Test SSE endpoint (legacy transport)
curl -s http://host.docker.internal:8096/sse | head -1
# Should show: event: endpoint
# Test Streamable HTTP endpoint (preferred)
curl -s -X POST http://host.docker.internal:8096/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
# Should return JSON with serverInfo.name: "Repo Prompt"
# In Claude Code, verify MCP is connected
/mcp
# Should list RepoPrompt as connectedMCP Transport Endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/mcp |
POST | Streamable HTTP transport (preferred) |
/sse |
GET | SSE event stream (returns session endpoint) |
/messages/?session_id=... |
POST | Send messages via SSE transport |
Note:
POST /ssereturns 405 Method Not Allowed - this is expected. Use/mcpfor Streamable HTTP or follow the SSE protocol (GET/sse→ POST to returned endpoint).
# In Claude Code terminal
claude --dangerously-skip-permissions
# Run setup (first time only)
/flow-next:setup
# Test planning (creates .flow/ directory)
/flow-next:plan Create a hello world script
# Verify .flow/ was created
ls -la .flow/# Start a simple test server
echo '<html><body><h1>Test Page</h1><button id="btn">Click me</button></body></html>' > /tmp/test.html
cd /tmp && python3.14 -m http.server 8080 &
# Test agent-browser directly
agent-browser open http://localhost:8080
agent-browser snapshot -i # Get interactive elements with refs
agent-browser screenshot # Take a screenshot
agent-browser close
# Or in Claude Code, use the flow-next browser skill:
/flow-next:browser
"Check if localhost:8080 has a button"
# Clean up
pkill -f "python3.14 -m http.server"# Create a simple test
mkdir -p /tmp/playwright-test && cd /tmp/playwright-test
cat > test_example.py << 'EOF'
from playwright.sync_api import sync_playwright
def test_playwright_works():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
assert "Example Domain" in page.title()
browser.close()
print("Playwright test passed!")
if __name__ == "__main__":
test_playwright_works()
EOF
# Run with Python directly
python3.14 test_example.py
# Or with pytest (if in a project with pytest-playwright)
# pytest test_example.py -v# Should work (allowed domains)
curl -s https://api.anthropic.com -o /dev/null && echo "Anthropic API: OK"
curl -s https://registry.npmjs.org -o /dev/null && echo "npm registry: OK"
# Should fail (blocked)
curl -s --max-time 3 https://example.com || echo "example.com: Blocked (expected)"| Component | Test Command | Expected Result |
|---|---|---|
| Node.js | node --version |
v20.x |
| Python | python3.14 --version |
3.14.x |
| uv | uv --version |
0.x |
| agent-browser | agent-browser --version |
0.x |
| Playwright | playwright --version |
1.57.x |
| MCP Bridge (SSE) | curl http://host.docker.internal:8096/sse |
event: endpoint |
| MCP Bridge (HTTP) | curl -X POST http://host.docker.internal:8096/mcp -H "Content-Type: application/json" -H "Accept: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' |
"name":"Repo Prompt" |
| Firewall | curl https://api.anthropic.com |
Success |
/flow-next:plan Add OAuth login # Creates .flow/ with tasks
/flow-next:work fn-1 # Execute task
/flow-next:interview fn-1 # Refine spec with 40+ questionsUse the /flow-next:browser skill or run commands directly:
# Direct CLI usage
agent-browser open https://localhost:3000
agent-browser snapshot -i # Get interactive elements
agent-browser click @e1 # Click element by ref
agent-browser fill @e2 "test@email.com"
agent-browser screenshot
# Or via flow-next skill in Claude Code
/flow-next:browser
"Test the signup flow on localhost:3000"RepoPrompt is accessed via MCP server, NOT via CLI. Claude Code has access to these tools:
mcp__RepoPrompt__manage_selection - Select files for context
mcp__RepoPrompt__chat_send - Chat with GPT-5.2 High, etc.
mcp__RepoPrompt__workspace_context - Get current context
mcp__RepoPrompt__file_search - Search files
mcp__RepoPrompt__apply_edits - Apply code changes
Example workflow for code review:
1. Select files: mcp__RepoPrompt__manage_selection(op="set", paths=[...])
2. Set prompt: mcp__RepoPrompt__prompt(op="set", text="Review...")
3. Send to chat: mcp__RepoPrompt__chat_send(new_chat=True, mode="review", ...)
4. Get response: mcp__RepoPrompt__chats(action="log", chat_id="...")
Note:
rp-cliis NOT installed in the container. Use MCP tools instead.
# Run E2E tests
pytest tests/e2e/
# Run with headed browser
pytest tests/e2e/ --headed| File | Description |
|---|---|
Dockerfile |
4-layer build: Playwright → Claude Code → Dev tools |
devcontainer.json |
Mounts, env vars, VS Code extensions, postCreateCommand |
init-firewall.sh |
Whitelists domains, opens MCP port 8096 |
setup-plugins.sh |
Installs flow-next plugin, configures MCP |
mcr.microsoft.com/playwright:v1.57.0-noble- Pre-built browsers (Chromium, Firefox, WebKit)
- Node 20, npm
- Ubuntu 24.04 LTS
@anthropic-ai/claude-codeCLI- Firewall tools (iptables, ipset, iproute2, dnsutils)
- Sudoers config for firewall script
- Shell: zsh, oh-my-zsh, powerlevel10k, fzf
- Git: git-delta, gh
- CLI: jq, ripgrep, fd, unzip
- Python: uv, Python 3.14, ruff
- Browser: agent-browser CLI (Vercel)
Installed fresh on every container start:
- flow-next plugin (Gordon Mickel's marketplace, includes browser skill)
- Repo Prompt MCP configuration
Repo Prompt not connecting:
# Test SSE endpoint
curl http://host.docker.internal:8096/sse
# Test Streamable HTTP endpoint (preferred)
curl -X POST http://host.docker.internal:8096/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
# Mac - ensure bridge running
~/bin/start-repoprompt-bridge.shPOST /sse returns 405 Method Not Allowed:
This is expected. The /sse endpoint only accepts GET requests. Use /mcp for Streamable HTTP transport instead.
flow-next not found:
/plugin marketplace add https://github.com/gmickel/gmickel-claude-marketplace
/plugin install flow-next
/flow-next:setupagent-browser not working:
# Check if installed
agent-browser --version
# Reinstall if missing
npm install -g agent-browser
# Kill stuck daemon and retry
pkill -f agent-browser && agent-browser open <url>Python version:
# Check Python version
uv python list
# Use Python 3.14 in project
uv venv --python 3.14
uv sync- Microsoft Playwright - Base image & browser automation
- Anthropic - Claude Code CLI
- Vercel Labs - agent-browser CLI
- Gordon Mickel - flow-next plugin
- Astral - uv package manager