#
tokens: 4782/50000 9/9 files
lines: on (toggle) GitHub
raw markdown copy reset
# 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
  1 | # GitHub Chat MCP
  2 | 
  3 | A Model Context Protocol (MCP) for analyzing and querying GitHub repositories using the GitHub Chat API. Official Site: https://github-chat.com
  4 | 
  5 | ## Installation
  6 | 
  7 | ```bash
  8 | # Install with pip
  9 | pip install github-chat-mcp
 10 | 
 11 | # Or install with the newer uv package manager
 12 | uv install github-chat-mcp
 13 | ```
 14 | 
 15 | 
 16 | 
 17 | 3. Start using it with Claude!
 18 | 
 19 | Example prompts:
 20 | - "Use github-chat-mcp to analyze the React repository"
 21 | - "Index the TypeScript repository with github-chat-mcp and ask about its architecture"
 22 | 
 23 | # GitHub Chat MCP server
 24 | 
 25 | [![smithery badge](https://smithery.ai/badge/github-chat-mcp)](https://smithery.ai/server/github-chat-mcp)
 26 | 
 27 | ## Setup Instructions
 28 | > Before anything, ensure you have a GitHub Chat API key. This is required to use the service.
 29 | 
 30 | Install uv first.
 31 | 
 32 | MacOS/Linux:
 33 | ```bash
 34 | curl -LsSf https://astral.sh/uv/install.sh | sh
 35 | ```
 36 | 
 37 | Windows:
 38 | ```
 39 | powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
 40 | ```
 41 | 
 42 | ### Setup with Cursor (Recommended)
 43 | In mcp.json:
 44 | 
 45 | ```json
 46 | {
 47 |   "mcpServers": {
 48 |     "github-chat": {
 49 |       "command": "uvx",
 50 |       "args": [
 51 |         "github-chat-mcp"
 52 |       ]
 53 |     }
 54 |   }
 55 | }
 56 | ```
 57 | 
 58 | With above, no envs required since it's a freemium release.
 59 | 
 60 | ### Setup with Claude Desktop
 61 | ```json
 62 | # claude_desktop_config.json
 63 | # Can find location through:
 64 | # Hamburger Menu -> File -> Settings -> Developer -> Edit Config
 65 | # Must perform: brew install uv
 66 | {
 67 |   "mcpServers": {
 68 |     "github-chat": {
 69 |       "command": "uvx",
 70 |       "args": ["github-chat-mcp"],
 71 |       "env": {
 72 |       }
 73 |     }
 74 |   }
 75 | }
 76 | ```
 77 | 
 78 | ### Installing via Smithery
 79 | 
 80 | You can install GitHub Chat for Claude Desktop automatically via Smithery:
 81 | 
 82 | ```bash
 83 | npx -y @smithery/cli install github-chat-mcp --client claude
 84 | ```
 85 | 
 86 | ### Using GitHub Chat with Claude
 87 | 1. Index a GitHub repository first:
 88 |    "Index the GitHub repository at https://github.com/username/repo"
 89 | 
 90 | 2. Then ask questions about the repository:
 91 |    "What is the core tech stack used in this repository?"
 92 | 
 93 | ### Debugging
 94 | Run:
 95 | ```bash
 96 | npx @modelcontextprotocol/inspector uvx github-chat-mcp
 97 | ```
 98 | 
 99 | ## Local/Dev Setup Instructions
100 | 
101 | ### Clone repo
102 | `git clone https://github.com/yourusername/github-chat-mcp.git`
103 | 
104 | ### Install dependencies
105 | Install uv first.
106 | 
107 | MacOS/Linux:
108 | ```bash
109 | curl -LsSf https://astral.sh/uv/install.sh | sh
110 | ```
111 | 
112 | Windows:
113 | ```
114 | powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
115 | ```
116 | 
117 | Then install MCP server dependencies:
118 | ```bash
119 | cd github-chat-mcp
120 | 
121 | # Create virtual environment and activate it
122 | uv venv
123 | 
124 | source .venv/bin/activate # MacOS/Linux
125 | # OR
126 | .venv/Scripts/activate # Windows
127 | 
128 | # Install dependencies
129 | uv sync
130 | ```
131 | ### Setup with Claude Desktop
132 | 
133 | #### Using MCP CLI SDK
134 | ```bash
135 | # `pip install mcp[cli]` if you haven't
136 | mcp install /ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp/src/github_chat_mcp/server.py -v "GITHUB_API_KEY=API_KEY_HERE"
137 | ```
138 | 
139 | #### Manually
140 | ```json
141 | # claude_desktop_config.json
142 | # Can find location through:
143 | # Hamburger Menu -> File -> Settings -> Developer -> Edit Config
144 | {
145 |   "mcpServers": {
146 |     "github-chat": {
147 |       "command": "uv",
148 |       "args": [
149 |         "--directory",
150 |         "/ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp",
151 |         "run",
152 |         "github-chat-mcp"
153 |       ],
154 |       "env": {
155 |       }
156 |     }
157 |   }
158 | }
159 | ```
160 | 
161 | ### Using GitHub Chat with Claude
162 | 1. Index a GitHub repository first:
163 |    "Index the GitHub repository at https://github.com/username/repo"
164 | 
165 | 2. Then ask questions about the repository:
166 |    "What is the core tech stack used in this repository?"
167 | 
168 | ### Debugging
169 | Run:
170 | ```bash
171 | # If mcp cli installed (`pip install mcp[cli]`)
172 | mcp dev /ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp/src/github_chat_mcp/server.py
173 | 
174 | # If not
175 | npx @modelcontextprotocol/inspector \
176 |       uv \
177 |       --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/github-chat-mcp \
178 |       run \
179 |       github-chat-mcp
180 | ```
181 | 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`.
182 | 
183 | # Notes
184 | - Level of logging is adjustable through the `FASTMCP_LOG_LEVEL` environment variable (e.g. `FASTMCP_LOG_LEVEL="ERROR"`)
185 | - This MCP server provides two main tools:
186 |   1. Repository Indexing - Index and analyze a GitHub repository
187 |   2. Repository Querying - Ask questions about the indexed repository
```

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

```python
 1 | from . import server
 2 | 
 3 | 
 4 | def main():
 5 |     """Main entry point for the package."""
 6 |     server.main()
 7 | 
 8 | 
 9 | # Optionally expose other important items at package level
10 | __all__ = ["main", "server"] 
```

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

```bash
 1 | #!/bin/bash
 2 | set -e
 3 | 
 4 | # Clean up any previous builds
 5 | rm -rf dist/
 6 | 
 7 | # Build the package
 8 | python -m pip install --upgrade build
 9 | python -m build
10 | 
11 | # Upload to PyPI
12 | python -m pip install --upgrade twine
13 | python -m twine upload dist/*
14 | 
15 | echo "Package published to PyPI successfully!" 
```

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

```yaml
 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
 2 | 
 3 | startCommand:
 4 |   type: stdio
 5 |   configSchema:
 6 |     # JSON Schema defining the configuration options for the MCP.
 7 |     type: object
 8 |     required:
 9 |       - githubApiKey
10 |     properties:
11 |       githubApiKey:
12 |         type: string
13 |         description: The API key for the GitHub Chat MCP server.
14 |   commandFunction:
15 |     # A function that produces the CLI command to start the MCP on stdio.
16 |     |-
17 |     (config) => ({command:'uv',args:['run','github-chat-mcp'],env:{GITHUB_API_KEY:config.githubApiKey}})
18 | 
```

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

```toml
 1 | [project]
 2 | name = "github-chat-mcp"
 3 | version = "0.1.0"
 4 | authors = [
 5 |     {name="Sheing Ng", email="[email protected]"},
 6 | ]
 7 | description = "GitHub Chat MCP server for analyzing GitHub repositories"
 8 | readme = "README.md"
 9 | requires-python = ">=3.12"
10 | dependencies = [
11 |     "requests~=2.31.0",
12 |     "mcp[cli]~=1.6.0",
13 |     "pydantic~=2.10.3",
14 | ]
15 | 
16 | [project.urls]
17 | Homepage = "https://github.com/AsyncFuncAI/github-chat-mcp"
18 | Issues = "https://github.com/AsyncFuncAI/github-chat-mcp/issues"
19 | 
20 | [build-system]
21 | requires = ["hatchling"]
22 | build-backend = "hatchling.build"
23 | 
24 | [project.scripts]
25 | github-chat-mcp = "github_chat_mcp:main"
26 | 
```

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

```json
 1 | {
 2 |   "name": "github-chat-mcp",
 3 |   "description": "GitHub Chat MCP server for analyzing and querying GitHub repositories",
 4 |   "version": "0.1.0",
 5 |   "repositoryUrl": "https://github.com/yourusername/github-chat-mcp",
 6 |   "installCommand": "pip install github-chat-mcp",
 7 |   "tools": [
 8 |     {
 9 |       "name": "index_repository",
10 |       "description": "Index a GitHub repository to analyze its codebase. This must be done before asking questions about the repository."
11 |     },
12 |     {
13 |       "name": "query_repository",
14 |       "description": "Ask questions about a GitHub repository and receive detailed AI responses. The repository must be indexed first."
15 |     }
16 |   ],
17 |   "configuration": {
18 |     "githubApiKey": {
19 |       "type": "string",
20 |       "description": "API key for GitHub Chat API",
21 |       "required": true
22 |     }
23 |   }
24 | } 
```

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

```dockerfile
 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
 2 | # Use a Python image with uv pre-installed
 3 | FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv
 4 | 
 5 | # Install the project into /app
 6 | WORKDIR /app
 7 | 
 8 | # Enable bytecode compilation
 9 | ENV UV_COMPILE_BYTECODE=1
10 | 
11 | # Copy the lock file and pyproject.toml for dependency management
12 | COPY uv.lock pyproject.toml /app/
13 | 
14 | # Install the project's dependencies using the lockfile and settings
15 | RUN --mount=type=cache,target=/root/.cache/uv \
16 |     uv sync --frozen --no-install-project --no-dev --no-editable
17 | 
18 | # Then, add the rest of the project source code and install it
19 | ADD . /app
20 | RUN --mount=type=cache,target=/root/.cache/uv \
21 |     uv sync --frozen --no-dev --no-editable
22 | 
23 | # Create the final image
24 | FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
25 | 
26 | WORKDIR /app
27 | 
28 | # Copy the virtual environment directly
29 | COPY --from=uv --chown=app:app /app/.venv /app/.venv
30 | 
31 | # Create app user
32 | RUN useradd -m app
33 | 
34 | # Place executables in the environment at the front of the path
35 | ENV PATH="/app/.venv/bin:$PATH"
36 | 
37 | # Environment variable for the GitHub API key
38 | ENV GITHUB_API_KEY=YOUR_API_KEY_HERE
39 | 
40 | # Switch to non-root user
41 | USER app
42 | 
43 | # Run the MCP server
44 | ENTRYPOINT ["github-chat-mcp"]
45 | 
```

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

```bash
 1 | #!/bin/bash
 2 | set -e
 3 | 
 4 | # Build the Docker image
 5 | docker build -t github-chat-mcp .
 6 | 
 7 | # Optional: Push to a container registry like Docker Hub or GitHub Container Registry
 8 | # docker tag github-chat-mcp yourusername/github-chat-mcp:latest
 9 | # docker push yourusername/github-chat-mcp:latest
10 | 
11 | # Run locally for testing
12 | echo "Starting GitHub Chat MCP server locally for testing..."
13 | docker run -e GITHUB_API_KEY=$GITHUB_API_KEY -p 8000:8000 github-chat-mcp
14 | 
15 | # Instructions for deploying to production environments
16 | cat << EOF
17 | 
18 | ------------------------------------
19 | Production Deployment Instructions:
20 | ------------------------------------
21 | 
22 | 1. Push the Docker image to a container registry:
23 |    docker tag github-chat-mcp yourusername/github-chat-mcp:latest
24 |    docker push yourusername/github-chat-mcp:latest
25 | 
26 | 2. Deploy to your preferred hosting service:
27 |    
28 |    - For AWS ECS:
29 |      aws ecs create-service --service-name github-chat-mcp --task-definition github-chat-mcp --desired-count 1
30 |      
31 |    - For Kubernetes:
32 |      kubectl apply -f kubernetes-deployment.yaml
33 |      
34 |    - For Google Cloud Run:
35 |      gcloud run deploy github-chat-mcp --image yourusername/github-chat-mcp:latest --platform managed
36 |      
37 | 3. Configure the environment variable GITHUB_API_KEY in your production environment.
38 | 
39 | 4. Register your MCP with the MCP registry by following the MCP documentation.
40 | 
41 | EOF 
```

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

```python
  1 | import json
  2 | import os
  3 | import requests
  4 | from typing import List, Dict, Any, Optional
  5 | 
  6 | from mcp.server.fastmcp import FastMCP
  7 | from pydantic import Field
  8 | 
  9 | 
 10 | GITHUB_CHAT_API_BASE = "https://api.github-chat.com"
 11 | API_KEY = os.environ.get("GITHUB_API_KEY", "")
 12 | 
 13 | mcp = FastMCP("github-chat-mcp", dependencies=["requests", "mcp[cli]"])
 14 | 
 15 | 
 16 | @mcp.tool()
 17 | def index_repository(
 18 |     repo_url: str = Field(
 19 |         description="The GitHub repository URL to index (format: https://github.com/username/repo)."
 20 |     ),
 21 | ) -> str:
 22 |     """Index a GitHub repository to analyze its codebase. This must be done before asking questions about the repository."""
 23 |     try:
 24 |         if not repo_url:
 25 |             raise ValueError("Repository URL cannot be empty.")
 26 |         
 27 |         if not repo_url.startswith("https://github.com/"):
 28 |             raise ValueError("Repository URL must be in the format: https://github.com/username/repo")
 29 |         
 30 |         # Call the verify API endpoint
 31 |         response = requests.post(
 32 |             f"{GITHUB_CHAT_API_BASE}/verify",
 33 |             headers={"Content-Type": "application/json"},
 34 |             json={"repo_url": repo_url}
 35 |         )
 36 |         
 37 |         if response.status_code != 200:
 38 |             return f"Error indexing repository: {response.text}"
 39 |         
 40 |         return f"Successfully indexed repository: {repo_url}. You can now ask questions about this repository."
 41 |     
 42 |     except Exception as e:
 43 |         return f"Error: {str(e) or repr(e)}"
 44 | 
 45 | 
 46 | @mcp.tool()
 47 | def query_repository(
 48 |     repo_url: str = Field(
 49 |         description="The GitHub repository URL to query (format: https://github.com/username/repo)."
 50 |     ),
 51 |     question: str = Field(
 52 |         description="The question to ask about the repository."
 53 |     ),
 54 |     conversation_history: Optional[List[Dict[str, str]]] = Field(
 55 |         description="Previous conversation history for multi-turn conversations.", default=None
 56 |     ),
 57 | ) -> str:
 58 |     """Ask questions about a GitHub repository and receive detailed AI responses. The repository must be indexed first."""
 59 |     try:
 60 |         if not repo_url or not question:
 61 |             raise ValueError("Repository URL and question cannot be empty.")
 62 |         
 63 |         if not repo_url.startswith("https://github.com/"):
 64 |             raise ValueError("Repository URL must be in the format: https://github.com/username/repo")
 65 |         
 66 |         # Prepare messages array
 67 |         messages = conversation_history or []
 68 |         messages.append({"role": "user", "content": question})
 69 |         
 70 |         # Call the chat completions API endpoint
 71 |         response = requests.post(
 72 |             f"{GITHUB_CHAT_API_BASE}/chat/completions/sync",
 73 |             headers={"Content-Type": "application/json"},
 74 |             json={
 75 |                 "repo_url": repo_url,
 76 |                 "messages": messages
 77 |             }
 78 |         )
 79 |         
 80 |         if response.status_code != 200:
 81 |             return f"Error querying repository: {response.text}"
 82 |         
 83 |         # Format the response
 84 |         result = response.json()
 85 |         formatted_response = format_chat_response(result)
 86 |         
 87 |         return formatted_response
 88 |     
 89 |     except Exception as e:
 90 |         return f"Error: {str(e) or repr(e)}"
 91 | 
 92 | 
 93 | def format_chat_response(response: Dict[str, Any]) -> str:
 94 |     """Format the chat response in a readable way."""
 95 |     formatted = ""
 96 |     
 97 |     if "answer" in response:
 98 |         formatted += response["answer"] + "\n\n"
 99 |     
100 |     if "contexts" in response and response["contexts"]:
101 |         formatted += "Sources:\n"
102 |         for i, context in enumerate(response["contexts"], 1):
103 |             if "meta_data" in context and "file_path" in context["meta_data"]:
104 |                 formatted += f"{i}. {context['meta_data']['file_path']}\n"
105 |     
106 |     return formatted.strip()
107 | 
108 | 
109 | def main():
110 |     mcp.run()
111 | 
112 | 
113 | if __name__ == "__main__":
114 |     main() 
```