Skip to main content
Glama
README.md
# GitHub MCP Server

## Overview

GitHub MCP Server is a Model Context Protocol (MCP) server that exposes GitHub API functionality to MCP-compatible clients like Claude Desktop, GPT, and other AI applications. It provides both MCP tools and a REST API interface for managing repositories, issues, and triggering repository dispatch events.

## Features

| MCP Tool | Description |
|---|---|
| `trigger_repository_dispatch` | Trigger a repository_dispatch webhook event |
| `create_issue` | Create a new issue in a repository |
| `get_repository_info` | Get detailed information about a repository |

## REST API Endpoints

- `POST /dispatch` - Trigger repository_dispatch event
- `POST /issue` - Create an issue
- `GET /health` - Health check endpoint

## Prerequisites

- Python 3.11+
- GitHub Personal Access Token (PAT) with appropriate scopes
- pip or poetry for dependency management

## Setup

### 1. Clone the Repository

```bash
git clone https://github.com/sasakiryuki/github-mcp.git
cd github-mcp
```

### 2. Install Dependencies

Using Poetry (recommended):
```bash
poetry install
```

Or using pip:
```bash
pip install -e .
```

### 3. Configure Environment Variables

Copy `.env.example` to `.env` and add your GitHub PAT:

```bash
cp .env.example .env
```

Edit `.env`:
```
GITHUB_PAT=ghp_xxxxxxxxxxxxxxxxxxxx
MCP_TRANSPORT=stdio
MCP_HOST=127.0.0.1
MCP_PORT=8000
LOG_LEVEL=INFO
```

**Important**: The `.env` file contains secrets and should never be committed to version control.

### 4. Verify Installation

```bash
poetry run python -c "from github_mcp import __version__; print(__version__)"
```

## Usage

### MCP Mode (Default)

Run the MCP server for use with MCP-compatible clients:

```bash
poetry run github-mcp
```

Or via stdio for Claude Desktop / GPT:
```bash
poetry run python -m github_mcp.core.server
```

### REST API Mode

Run the FastAPI server on http://localhost:8000:

```bash
poetry run python -m github_mcp.api.rest_server
```

Access the interactive API documentation at http://localhost:8000/docs

### MCP Inspector (Testing)

```bash
npx @modelcontextprotocol/inspector poetry run python -m github_mcp.core.server
```

## Integration with AI Clients

### Claude Desktop

1. Locate your Claude Desktop config file:
   - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

2. Add the GitHub MCP server to `mcpServers`:

```json
{
  "mcpServers": {
    "github": {
      "command": "poetry",
      "args": ["run", "python", "-m", "github_mcp.core.server"],
      "cwd": "/absolute/path/to/github-mcp",
      "env": {
        "GITHUB_PAT": "your_github_pat_here"
      }
    }
  }
}
```

3. Restart Claude Desktop

### GPT Custom GPT

1. Deploy the REST API server to a cloud service (e.g., Vercel, AWS Lambda, Google Cloud Run)
2. Create a Custom GPT in ChatGPT
3. Add the OpenAPI schema to your Custom GPT's actions configuration
4. Configure your GitHub PAT as a required header or authentication method

Example OpenAPI schema:

```yaml
openapi: 3.0.0
info:
  title: GitHub MCP API
  version: 1.0.0
servers:
  - url: https://your-deployment-url.com
paths:
  /dispatch:
    post:
      operationId: triggerDispatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner:
                  type: string
                repo:
                  type: string
                event_type:
                  type: string
                payload_json:
                  type: string
```

## API Examples

### Create an Issue

**MCP Tool Call:**
```python
call_tool("create_issue", {
    "owner": "sasakiryuki",
    "repo": "github-mcp",
    "title": "Fix broken link in docs",
    "body": "The setup link on line 42 is broken.\n\nExpected: https://...\nActual: https://..."
})
```

**REST API:**
```bash
curl -X POST http://localhost:8000/issue \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_GITHUB_PAT" \
  -d '{
    "owner": "sasakiryuki",
    "repo": "github-mcp",
    "title": "Fix broken link in docs",
    "body": "The setup link on line 42 is broken."
  }'
```

### Trigger Repository Dispatch

**MCP Tool Call:**
```python
call_tool("trigger_repository_dispatch", {
    "owner": "sasakiryuki",
    "repo": "github-mcp",
    "event_type": "deploy-production",
    "payload_json": '{"version": "1.0.0", "environment": "production"}'
})
```

**REST API:**
```bash
curl -X POST http://localhost:8000/dispatch \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_GITHUB_PAT" \
  -d '{
    "owner": "sasakiryuki",
    "repo": "github-mcp",
    "event_type": "deploy-production",
    "payload_json": "{\"version\": \"1.0.0\", \"environment\": \"production\"}"
  }'
```

### Get Repository Info

**MCP Tool Call:**
```python
call_tool("get_repository_info", {
    "owner": "sasakiryuki",
    "repo": "github-mcp"
})
```

## Security Considerations

### Token Management

- **Never hardcode tokens**: Always use environment variables or secret managers
- **Use Personal Access Tokens (PAT)**: For user impersonation, PATs are safer than passwords
- **Minimal scopes**: Create PATs with only required permissions (typically: `repo`, `workflow`)
- **Token rotation**: Regularly rotate your tokens
- **Secret masking**: The server automatically masks tokens in logs

### Production Deployment

1. Use a Secret Manager (AWS Secrets Manager, Google Secret Manager, etc.)
2. Enable token encryption in transit (HTTPS)
3. Implement rate limiting
4. Add request authentication/authorization
5. Monitor and audit all API calls
6. Use temporary credentials when possible

Example with AWS Secrets Manager:

```python
import boto3

def get_github_pat():
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId='github-mcp-pat')
    return response['SecretString']
```

## Development

### Run Tests

```bash
# All tests
poetry run pytest

# With coverage
poetry run pytest --cov=src/github_mcp

# Specific test file
poetry run pytest tests/unit/test_config.py -v
```

### Code Quality

```bash
# Format code
poetry run black src/ tests/

# Lint
poetry run flake8 src/ tests/

# Type checking
poetry run mypy src/
```

## Architecture

### Project Structure

```
github-mcp/
├── src/github_mcp/
│   ├── __init__.py
│   ├── core/
│   │   ├── server.py      # MCP server implementation
│   │   ├── tools.py       # MCP tools definitions
│   │   └── cli.py         # CLI entry point
│   ├── api/
│   │   ├── rest_server.py # FastAPI server
│   │   └── schemas.py     # Request/response schemas
│   ├── services/
│   │   └── github_service.py  # GitHub API wrapper
│   ├── config.py          # Configuration management
│   └── utils/
│       ├── encryption.py  # Token encryption utilities
│       └── logging.py     # Logging with masking
├── tests/
│   ├── unit/
│   ├── integration/
│   └── fixtures/
├── .env.example
├── README.md
├── pyproject.toml
└── LICENSE
```

### Component Interaction

```
MCP Client (Claude Desktop/GPT)
    ↓
MCP Server (FastMCP)
    ↓
Tools Layer (trigger_repository_dispatch, create_issue, etc.)
    ↓
GitHub Service (PyGithub wrapper)
    ↓
GitHub REST API
```

For REST API mode:
```
REST Client (Custom GPT, etc.)
    ↓
FastAPI Server
    ↓
GitHub Service
    ↓
GitHub REST API
```

## Troubleshooting

### "Invalid GitHub PAT" Error

1. Verify the token is correctly set in `.env`
2. Check token hasn't expired
3. Confirm token has required scopes: `repo`, `workflow`
4. Test token manually: `curl -H "Authorization: token YOUR_PAT" https://api.github.com/user`

### "Repository Not Found" Error

1. Verify owner and repo name are correct
2. Check the repository is public or you have access
3. Verify your PAT has appropriate permissions

### MCP Connection Issues

1. Ensure the server is running in MCP mode
2. Check the transport type matches your client configuration
3. Verify environment variables are set correctly
4. Check logs for detailed error messages

### REST API Port Already in Use

```bash
# Find process using port 8000
lsof -i :8000

# Use a different port
MCP_PORT=8001 poetry run python -m github_mcp.api.rest_server
```

## Performance & Rate Limiting

GitHub API has rate limits:
- **Authenticated requests**: 5,000 per hour
- **Unauthenticated requests**: 60 per hour

The server does not implement local rate limiting. For high-volume usage, consider:
1. Implementing request queuing
2. Using GitHub's conditional requests (ETags)
3. Batching API calls where possible

## Testing

### Live Testing Against GitHub

```bash
# Set this flag to enable tests that modify your GitHub account
RUN_LIVE_TESTS=1 poetry run pytest tests/integration/
```

### Mock Testing

```bash
# Default: uses mock data, safe to run
poetry run pytest tests/unit/
```

## Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

## License

MIT License - see LICENSE file for details

## Support

For issues, questions, or suggestions:
- Open a GitHub issue
- Check existing issues for solutions
- See DEVELOPMENT.md for technical details

## Changelog

### v0.1.0 (Initial Release)
- MCP server with tools: trigger_repository_dispatch, create_issue, get_repository_info
- FastAPI REST server
- Configuration management with environment variables
- Token encryption utilities
- Comprehensive logging with token masking
- Unit and integration tests
- Claude Desktop integration guide