#
tokens: 3457/50000 9/9 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── deploy.sh
├── Dockerfile
├── LICENSE
├── publish.sh
├── pyproject.toml
├── README.md
├── registry.json
├── smithery.yaml
├── src
│   └── github_chat_mcp
│       ├── __init__.py
│       ├── __pycache__
│       │   ├── server.cpython-310.pyc
│       │   ├── server.cpython-311.pyc
│       │   └── server.cpython-312.pyc
│       └── server.py
└── uv.lock
```

# Files

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# GitHub Chat MCP

A Model Context Protocol (MCP) for analyzing and querying GitHub repositories using the GitHub Chat API. Official Site: https://github-chat.com

## Installation

```bash
# Install with pip
pip install github-chat-mcp

# Or install with the newer uv package manager
uv install github-chat-mcp
```



3. Start using it with Claude!

Example prompts:
- "Use github-chat-mcp to analyze the React repository"
- "Index the TypeScript repository with github-chat-mcp and ask about its architecture"

# GitHub Chat MCP server

[![smithery badge](https://smithery.ai/badge/github-chat-mcp)](https://smithery.ai/server/github-chat-mcp)

## Setup Instructions
> Before anything, ensure you have a GitHub Chat API key. This is required to use the service.

Install uv first.

MacOS/Linux:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Windows:
```
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

### Setup with Cursor (Recommended)
In mcp.json:

```json
{
  "mcpServers": {
    "github-chat": {
      "command": "uvx",
      "args": [
        "github-chat-mcp"
      ]
    }
  }
}
```

With above, no envs required since it's a freemium release.

### Setup with Claude Desktop
```json
# claude_desktop_config.json
# Can find location through:
# Hamburger Menu -> File -> Settings -> Developer -> Edit Config
# Must perform: brew install uv
{
  "mcpServers": {
    "github-chat": {
      "command": "uvx",
      "args": ["github-chat-mcp"],
      "env": {
      }
    }
  }
}
```

### Installing via Smithery

You can install GitHub Chat for Claude Desktop automatically via Smithery:

```bash
npx -y @smithery/cli install github-chat-mcp --client claude
```

### Using GitHub Chat with Claude
1. Index a GitHub repository first:
   "Index the GitHub repository at https://github.com/username/repo"

2. Then ask questions about the repository:
   "What is the core tech stack used in this repository?"

### Debugging
Run:
```bash
npx @modelcontextprotocol/inspector uvx github-chat-mcp
```

## Local/Dev Setup Instructions

### Clone repo
`git clone https://github.com/yourusername/github-chat-mcp.git`

### Install dependencies
Install uv first.

MacOS/Linux:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Windows:
```
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

Then install MCP server dependencies:
```bash
cd github-chat-mcp

# Create virtual environment and activate it
uv venv

source .venv/bin/activate # MacOS/Linux
# OR
.venv/Scripts/activate # Windows

# Install dependencies
uv sync
```
### Setup with Claude Desktop

#### Using MCP CLI SDK
```bash
# `pip install mcp[cli]` if you haven't
mcp install /ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp/src/github_chat_mcp/server.py -v "GITHUB_API_KEY=API_KEY_HERE"
```

#### Manually
```json
# claude_desktop_config.json
# Can find location through:
# Hamburger Menu -> File -> Settings -> Developer -> Edit Config
{
  "mcpServers": {
    "github-chat": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp",
        "run",
        "github-chat-mcp"
      ],
      "env": {
      }
    }
  }
}
```

### Using GitHub Chat with Claude
1. Index a GitHub repository first:
   "Index the GitHub repository at https://github.com/username/repo"

2. Then ask questions about the repository:
   "What is the core tech stack used in this repository?"

### Debugging
Run:
```bash
# If mcp cli installed (`pip install mcp[cli]`)
mcp dev /ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp/src/github_chat_mcp/server.py

# If not
npx @modelcontextprotocol/inspector \
      uv \
      --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp \
      run \
      github-chat-mcp
```
Then access MCP Inspector at `http://localhost:5173`. You may need to add your GitHub API key in the environment variables in the inspector under `GITHUB_API_KEY`.

# Notes
- Level of logging is adjustable through the `FASTMCP_LOG_LEVEL` environment variable (e.g. `FASTMCP_LOG_LEVEL="ERROR"`)
- This MCP server provides two main tools:
  1. Repository Indexing - Index and analyze a GitHub repository
  2. Repository Querying - Ask questions about the indexed repository
```

--------------------------------------------------------------------------------
/src/github_chat_mcp/__init__.py:
--------------------------------------------------------------------------------

```python
from . import server


def main():
    """Main entry point for the package."""
    server.main()


# Optionally expose other important items at package level
__all__ = ["main", "server"] 
```

--------------------------------------------------------------------------------
/publish.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/bash
set -e

# Clean up any previous builds
rm -rf dist/

# Build the package
python -m pip install --upgrade build
python -m build

# Upload to PyPI
python -m pip install --upgrade twine
python -m twine upload dist/*

echo "Package published to PyPI successfully!" 
```

--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------

```yaml
# Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml

startCommand:
  type: stdio
  configSchema:
    # JSON Schema defining the configuration options for the MCP.
    type: object
    required:
      - githubApiKey
    properties:
      githubApiKey:
        type: string
        description: The API key for the GitHub Chat MCP server.
  commandFunction:
    # A function that produces the CLI command to start the MCP on stdio.
    |-
    (config) => ({command:'uv',args:['run','github-chat-mcp'],env:{GITHUB_API_KEY:config.githubApiKey}})

```

--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------

```toml
[project]
name = "github-chat-mcp"
version = "0.1.0"
authors = [
    {name="Sheing Ng", email="[email protected]"},
]
description = "GitHub Chat MCP server for analyzing GitHub repositories"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "requests~=2.31.0",
    "mcp[cli]~=1.6.0",
    "pydantic~=2.10.3",
]

[project.urls]
Homepage = "https://github.com/AsyncFuncAI/github-chat-mcp"
Issues = "https://github.com/AsyncFuncAI/github-chat-mcp/issues"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project.scripts]
github-chat-mcp = "github_chat_mcp:main"

```

--------------------------------------------------------------------------------
/registry.json:
--------------------------------------------------------------------------------

```json
{
  "name": "github-chat-mcp",
  "description": "GitHub Chat MCP server for analyzing and querying GitHub repositories",
  "version": "0.1.0",
  "repositoryUrl": "https://github.com/yourusername/github-chat-mcp",
  "installCommand": "pip install github-chat-mcp",
  "tools": [
    {
      "name": "index_repository",
      "description": "Index a GitHub repository to analyze its codebase. This must be done before asking questions about the repository."
    },
    {
      "name": "query_repository",
      "description": "Ask questions about a GitHub repository and receive detailed AI responses. The repository must be indexed first."
    }
  ],
  "configuration": {
    "githubApiKey": {
      "type": "string",
      "description": "API key for GitHub Chat API",
      "required": true
    }
  }
} 
```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
# Use a Python image with uv pre-installed
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv

# Install the project into /app
WORKDIR /app

# Enable bytecode compilation
ENV UV_COMPILE_BYTECODE=1

# Copy the lock file and pyproject.toml for dependency management
COPY uv.lock pyproject.toml /app/

# Install the project's dependencies using the lockfile and settings
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-install-project --no-dev --no-editable

# Then, add the rest of the project source code and install it
ADD . /app
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-dev --no-editable

# Create the final image
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim

WORKDIR /app

# Copy the virtual environment directly
COPY --from=uv --chown=app:app /app/.venv /app/.venv

# Create app user
RUN useradd -m app

# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH"

# Environment variable for the GitHub API key
ENV GITHUB_API_KEY=YOUR_API_KEY_HERE

# Switch to non-root user
USER app

# Run the MCP server
ENTRYPOINT ["github-chat-mcp"]

```

--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/bash
set -e

# Build the Docker image
docker build -t github-chat-mcp .

# Optional: Push to a container registry like Docker Hub or GitHub Container Registry
# docker tag github-chat-mcp yourusername/github-chat-mcp:latest
# docker push yourusername/github-chat-mcp:latest

# Run locally for testing
echo "Starting GitHub Chat MCP server locally for testing..."
docker run -e GITHUB_API_KEY=$GITHUB_API_KEY -p 8000:8000 github-chat-mcp

# Instructions for deploying to production environments
cat << EOF

------------------------------------
Production Deployment Instructions:
------------------------------------

1. Push the Docker image to a container registry:
   docker tag github-chat-mcp yourusername/github-chat-mcp:latest
   docker push yourusername/github-chat-mcp:latest

2. Deploy to your preferred hosting service:
   
   - For AWS ECS:
     aws ecs create-service --service-name github-chat-mcp --task-definition github-chat-mcp --desired-count 1
     
   - For Kubernetes:
     kubectl apply -f kubernetes-deployment.yaml
     
   - For Google Cloud Run:
     gcloud run deploy github-chat-mcp --image yourusername/github-chat-mcp:latest --platform managed
     
3. Configure the environment variable GITHUB_API_KEY in your production environment.

4. Register your MCP with the MCP registry by following the MCP documentation.

EOF 
```

--------------------------------------------------------------------------------
/src/github_chat_mcp/server.py:
--------------------------------------------------------------------------------

```python
import json
import os
import requests
from typing import List, Dict, Any, Optional

from mcp.server.fastmcp import FastMCP
from pydantic import Field


GITHUB_CHAT_API_BASE = "https://api.github-chat.com"
API_KEY = os.environ.get("GITHUB_API_KEY", "")

mcp = FastMCP("github-chat-mcp", dependencies=["requests", "mcp[cli]"])


@mcp.tool()
def index_repository(
    repo_url: str = Field(
        description="The GitHub repository URL to index (format: https://github.com/username/repo)."
    ),
) -> str:
    """Index a GitHub repository to analyze its codebase. This must be done before asking questions about the repository."""
    try:
        if not repo_url:
            raise ValueError("Repository URL cannot be empty.")
        
        if not repo_url.startswith("https://github.com/"):
            raise ValueError("Repository URL must be in the format: https://github.com/username/repo")
        
        # Call the verify API endpoint
        response = requests.post(
            f"{GITHUB_CHAT_API_BASE}/verify",
            headers={"Content-Type": "application/json"},
            json={"repo_url": repo_url}
        )
        
        if response.status_code != 200:
            return f"Error indexing repository: {response.text}"
        
        return f"Successfully indexed repository: {repo_url}. You can now ask questions about this repository."
    
    except Exception as e:
        return f"Error: {str(e) or repr(e)}"


@mcp.tool()
def query_repository(
    repo_url: str = Field(
        description="The GitHub repository URL to query (format: https://github.com/username/repo)."
    ),
    question: str = Field(
        description="The question to ask about the repository."
    ),
    conversation_history: Optional[List[Dict[str, str]]] = Field(
        description="Previous conversation history for multi-turn conversations.", default=None
    ),
) -> str:
    """Ask questions about a GitHub repository and receive detailed AI responses. The repository must be indexed first."""
    try:
        if not repo_url or not question:
            raise ValueError("Repository URL and question cannot be empty.")
        
        if not repo_url.startswith("https://github.com/"):
            raise ValueError("Repository URL must be in the format: https://github.com/username/repo")
        
        # Prepare messages array
        messages = conversation_history or []
        messages.append({"role": "user", "content": question})
        
        # Call the chat completions API endpoint
        response = requests.post(
            f"{GITHUB_CHAT_API_BASE}/chat/completions/sync",
            headers={"Content-Type": "application/json"},
            json={
                "repo_url": repo_url,
                "messages": messages
            }
        )
        
        if response.status_code != 200:
            return f"Error querying repository: {response.text}"
        
        # Format the response
        result = response.json()
        formatted_response = format_chat_response(result)
        
        return formatted_response
    
    except Exception as e:
        return f"Error: {str(e) or repr(e)}"


def format_chat_response(response: Dict[str, Any]) -> str:
    """Format the chat response in a readable way."""
    formatted = ""
    
    if "answer" in response:
        formatted += response["answer"] + "\n\n"
    
    if "contexts" in response and response["contexts"]:
        formatted += "Sources:\n"
        for i, context in enumerate(response["contexts"], 1):
            if "meta_data" in context and "file_path" in context["meta_data"]:
                formatted += f"{i}. {context['meta_data']['file_path']}\n"
    
    return formatted.strip()


def main():
    mcp.run()


if __name__ == "__main__":
    main() 
```