Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Virtual environments
venv/
env/
ENV/
.venv

# Environment files
.env
.env.local
.env.*.local

# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/
.hypothesis/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# Git
.git/
.gitignore
.gitattributes

# Documentation (not needed in image)
*.md
LICENSE
CODEOWNERS

# CI/CD
.github/

# Docker
Dockerfile*
docker-compose*.yml
.dockerignore

# Logs
*.log
67 changes: 67 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Docker Build and Publish

on:
push:
branches:
- main
tags:
- 'v*.*.*'
pull_request:
branches:
- main
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
36 changes: 36 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Multi-stage build for GitHub MCP Server
# Stage 1: Builder - Install dependencies
FROM python:3.10-alpine AS builder

# Install build dependencies
RUN apk add --no-cache gcc musl-dev libffi-dev

WORKDIR /app

# Copy requirements and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# Stage 2: Runtime - Minimal image
FROM python:3.10-alpine

# Create a non-root user 'app'
RUN adduser -D -h /home/app -s /bin/sh app

WORKDIR /app

# Copy installed packages from builder
COPY --from=builder --chown=app:app /root/.local /home/app/.local

# Copy application code
COPY --chown=app:app main.py .

# Switch to non-root user
USER app

# Add local packages to PATH
ENV PATH="/home/app/.local/bin:$PATH"
ENV PYTHONUNBUFFERED=1

# Run the MCP server
ENTRYPOINT ["python", "main.py"]
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The ENTRYPOINT uses python but documentation consistently references python3. For consistency and clarity, consider using python3 in the ENTRYPOINT to match the documentation and make the Python version explicit, even though they point to the same binary in this Alpine image.

Suggested change
ENTRYPOINT ["python", "main.py"]
ENTRYPOINT ["python3", "main.py"]

Copilot uses AI. Check for mistakes.
87 changes: 83 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,54 @@ Get file content directly via URI.
content://anthropics/anthropic-sdk-python/doc/README.md
```

## Claude Desktop Integration
## Docker Deployment

Add to your `claude_desktop_config.json`:
### Using Pre-built Docker Image

Pull the latest image from GitHub Container Registry:

```bash
docker pull ghcr.io/sperekrestova/github-mcp-server:latest
```

### Building Docker Image Locally

```bash
# Build the image
docker build -t github-mcp-server .

# Or use docker-compose
docker-compose build
```

### Running with Docker

```bash
# Run interactively
docker run -i --rm \
-e GITHUB_TOKEN=ghp_your_token_here \
ghcr.io/sperekrestova/github-mcp-server:latest

# Or use docker-compose
GITHUB_TOKEN=ghp_your_token_here docker-compose up
```

### Claude Desktop Integration with Docker

Add this configuration to your `claude_desktop_config.json`:

```json
{
"mcpServers": {
"github-docs": {
"command": "python",
"args": ["/path/to/GitHub_MCP_Server/main.py"],
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e", "GITHUB_TOKEN",
"ghcr.io/sperekrestova/github-mcp-server:latest"
],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here"
}
Expand All @@ -125,6 +163,47 @@ Add to your `claude_desktop_config.json`:
}
```

**Benefits of Docker deployment:**
- No Python installation required
- Consistent environment across platforms
- Easy updates (`docker pull`)
- Isolated dependencies

## Claude Desktop Integration (Python)

Add to your `claude_desktop_config.json`:

```json
{
"mcpServers": {
"github-docs": {
"command": "python3",
"args": ["/absolute/path/to/GitHub_MCP_Server/main.py"],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here"
},
"autoapprove": [
"get_org_repos_tool",
"get_repo_docs_tool",
"get_file_content_tool",
"search_documentation_tool"
]
}
}
}
```

**Configuration file location:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

**Important notes:**
- Replace `/absolute/path/to/GitHub_MCP_Server/main.py` with the actual path on your system
- Replace `ghp_your_token_here` with your GitHub personal access token
- The `autoapprove` field allows Claude to use these tools without prompting for permission
- Use `python3` or `python` depending on your system configuration

Then restart Claude Desktop and ask:
- "What documentation exists in the anthropics organization?"
- "Show me authentication docs from the SDK"
Expand Down
Loading