diff --git a/.env.example b/.env.example index 502aa0d..935ccb8 100644 --- a/.env.example +++ b/.env.example @@ -25,3 +25,17 @@ # Required for ./claude.sh web # WEBUI_USER=claude # WEBUI_PASSWORD=changeme + +# ─── MCP servers (all optional) ─────────────────────────────────────────────── + +# GitHub — PAT with repo scope +# GITHUB_TOKEN=ghp_... + +# GitLab — PAT with api scope; GITLAB_URL defaults to https://gitlab.com +# GITLAB_TOKEN=glpat_... +# GITLAB_URL=https://gitlab.com + +# Jira + Confluence — shared Atlassian credentials +# ATLASSIAN_SITE_NAME=your-company # subdomain of .atlassian.net +# ATLASSIAN_USER_EMAIL=you@example.com +# ATLASSIAN_API_TOKEN=... # https://id.atlassian.com/manage-profile/security/api-tokens diff --git a/claude/Dockerfile b/claude/Dockerfile index e00159d..b48ae3a 100644 --- a/claude/Dockerfile +++ b/claude/Dockerfile @@ -18,6 +18,13 @@ COPY settings.json /etc/claude-code/managed-settings.json # Install Claude Code globally RUN npm install -g @anthropic-ai/claude-code +# Install MCP servers globally — entry points land in /usr/local/lib/node_modules/ +RUN npm install -g \ + @modelcontextprotocol/server-github \ + @yoda.digital/gitlab-mcp-server \ + @aashari/mcp-server-atlassian-jira \ + @aashari/mcp-server-atlassian-confluence + # Workspace and Claude config dir — owned by the built-in node user (uid 1000). # Pre-creating ~/.claude ensures the named volume is initialised with the # correct ownership when first mounted (Docker copies image content into diff --git a/claude/settings.json b/claude/settings.json index 9dfc165..4e2033e 100644 --- a/claude/settings.json +++ b/claude/settings.json @@ -1,10 +1,41 @@ { "availableModels": ["sonnet", "opus", "haiku"], "permissions": { - "allow": [ - "Bash(*)", - "Edit(*)", - "Write(*)" - ] + "allow": ["Bash(*)", "Edit(*)", "Write(*)"], + "deny": ["Bash(curl *)", "Read(.*env*)"], + "env": { + "CLAUDE_CODE_ENABLE_TELEMETRY": "0" + } + }, + "mcpServers": { + "github": { + "command": "mcp-server-github", + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" + } + }, + "gitlab": { + "command": "gitlab-mcp-server", + "env": { + "GITLAB_PERSONAL_ACCESS_TOKEN": "${GITLAB_TOKEN}", + "GITLAB_URL": "${GITLAB_URL}" + } + }, + "jira": { + "command": "mcp-atlassian-jira", + "env": { + "ATLASSIAN_SITE_NAME": "${ATLASSIAN_SITE_NAME}", + "ATLASSIAN_USER_EMAIL": "${ATLASSIAN_USER_EMAIL}", + "ATLASSIAN_API_TOKEN": "${ATLASSIAN_API_TOKEN}" + } + }, + "confluence": { + "command": "mcp-atlassian-confluence", + "env": { + "ATLASSIAN_SITE_NAME": "${ATLASSIAN_SITE_NAME}", + "ATLASSIAN_USER_EMAIL": "${ATLASSIAN_USER_EMAIL}", + "ATLASSIAN_API_TOKEN": "${ATLASSIAN_API_TOKEN}" + } + } } } diff --git a/docker-compose.yml b/docker-compose.yml index bc7df0d..753b2c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,6 +39,13 @@ services: - HTTPS_PROXY=http://proxy:3128 - ALL_PROXY=http://proxy:3128 - NO_PROXY=localhost,127.0.0.1 + # MCP server credentials — all optional; servers are skipped if unset + - GITHUB_TOKEN=${GITHUB_TOKEN:-} + - GITLAB_TOKEN=${GITLAB_TOKEN:-} + - GITLAB_URL=${GITLAB_URL:-https://gitlab.com} + - ATLASSIAN_SITE_NAME=${ATLASSIAN_SITE_NAME:-} + - ATLASSIAN_USER_EMAIL=${ATLASSIAN_USER_EMAIL:-} + - ATLASSIAN_API_TOKEN=${ATLASSIAN_API_TOKEN:-} ports: # OAuth callback — required for browser-based login (claude login) - "0.0.0.0:54545:54545" @@ -74,6 +81,13 @@ services: - HTTPS_PROXY=http://proxy:3128 - ALL_PROXY=http://proxy:3128 - NO_PROXY=localhost,127.0.0.1 + # MCP server credentials — all optional; servers are skipped if unset + - GITHUB_TOKEN=${GITHUB_TOKEN:-} + - GITLAB_TOKEN=${GITLAB_TOKEN:-} + - GITLAB_URL=${GITLAB_URL:-https://gitlab.com} + - ATLASSIAN_SITE_NAME=${ATLASSIAN_SITE_NAME:-} + - ATLASSIAN_USER_EMAIL=${ATLASSIAN_USER_EMAIL:-} + - ATLASSIAN_API_TOKEN=${ATLASSIAN_API_TOKEN:-} - WEBUI_USER=${WEBUI_USER:-claude} - WEBUI_PASSWORD=${WEBUI_PASSWORD:-} - WEBUI_PORT=7681 diff --git a/proxy/squid.conf b/proxy/squid.conf index 9482ad1..cac6ff8 100644 --- a/proxy/squid.conf +++ b/proxy/squid.conf @@ -28,6 +28,10 @@ acl allowed_sites dstdomain api.anthropic.com acl allowed_sites dstdomain statsig.anthropic.com acl allowed_sites dstdomain localhost acl allowed_sites dstdomain .local +# MCP servers +acl allowed_sites dstdomain api.github.com +acl allowed_sites dstdomain .gitlab.com +acl allowed_sites dstdomain .atlassian.net # ─── Access rules ───────────────────────────────────────────────────────────── # Block requests to non-standard ports