Skip to content
20 changes: 20 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "thv + Claude Code",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "lts"
},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
},
"postCreateCommand": "bash .devcontainer/setup.sh",
"postStartCommand": "bash .devcontainer/start-servers.sh",
"customizations": {
"vscode": {
"extensions": [
"GitHub.copilot",
"GitHub.copilot-chat"
]
}
}
}
35 changes: 35 additions & 0 deletions .devcontainer/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail

# Install Claude Code (Node.js provided via devcontainer feature)
npm install -g @anthropic-ai/claude-code

# Install thv (ToolHive) to ~/.local/bin
mkdir -p "$HOME/.local/bin"
curl -fsSL "https://github.com/stacklok/toolhive/releases/download/v0.11.0/toolhive_0.11.0_linux_amd64.tar.gz" \
| tar -xz -C "$HOME/.local/bin" thv

export PATH="$HOME/.local/bin:$PATH"

# Ensure Claude Code config exists and onboarding is marked complete
if [ ! -f "$HOME/.claude.json" ]; then
echo '{}' > "$HOME/.claude.json"
fi
node -e "
const fs = require('fs');
const path = '$HOME/.claude.json';
const config = JSON.parse(fs.readFileSync(path, 'utf8'));
config.hasCompletedOnboarding = true;
config.lastOnboardingVersion = '99.99.99';
fs.writeFileSync(path, JSON.stringify(config));
"

# Ensure VS Code Server MCP config exists so thv can register itself
mkdir -p "$HOME/.vscode-server/data/User"
if [ ! -f "$HOME/.vscode-server/data/User/mcp.json" ]; then
echo '{}' > "$HOME/.vscode-server/data/User/mcp.json"
fi

# Register clients (Docker not needed for registration)
thv client register claude-code
thv client register vscode-server
10 changes: 10 additions & 0 deletions .devcontainer/start-servers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail

export PATH="$HOME/.local/bin:$PATH"

# Start MCP servers (requires Docker, runs on every Codespace start)
thv run mermaid 2>/dev/null || true
thv run fetch 2>/dev/null || true
thv run osv 2>/dev/null || true
thv run semgrep 2>/dev/null || true