Skip to main content
Glama
decuma02

GitHub MCP Server

by decuma02
README.md
# Kage — GitHub MCP Server

> **Kage** (影, *shadow*) acts as the invisible layer between an LLM and GitHub — an AI agent can command it without ever touching a UI.

[![Python](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python)](https://python.org)
[![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.28%2B-blueviolet)](https://github.com/modelcontextprotocol/python-sdk)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

---

## What is this?

**Kage** is a custom [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that exposes GitHub repository operations as structured, schema-validated tools that any MCP-compatible LLM agent (Claude Desktop, Claude Code, etc.) can call autonomously.

Instead of writing hardcoded scripts that chain GitHub API calls, an agent connected to Kage can **think, plan, and act** — searching for issues, reading their context, and creating new ones — all in one natural language conversation.

### Why MCP instead of a plain REST API?

A REST API requires a human (or hardcoded client) to know *exactly* what endpoints to call. MCP is different: the server **advertises its capabilities at runtime** via JSON-RPC. An LLM can query the server for what tools exist, read their schemas, and decide autonomously how to use them. No hardcoding, no predefined flows.

---

## Architecture

```
┌─────────────────────────┐         JSON-RPC 2.0 over stdio
│   LLM Agent             │◄────────────────────────────────►│ Kage MCP Server (Python) │
│ (Claude Desktop / Code) │                                   │                          │
└─────────────────────────┘                                   │  FastMCP Framework       │
                                                              │  ↓                       │
                                                              │  Pydantic Validation     │
                                                              │  ↓                       │
                                                              │  PyGithub Client         │
                                                              │  ↓                       │
                                                              │  GitHub REST API         │
                                                              └──────────────────────────┘
```

```mermaid
sequenceDiagram
    participant Agent as LLM Agent (Claude)
    participant Kage as Kage MCP Server
    participant GH as GitHub API

    Agent->>Kage: tools/list → "What can you do?"
    Kage-->>Agent: Returns tool names + JSON Schemas

    Agent->>Kage: tools/call → search_issues(repo, query)
    Note over Kage: Pydantic validates inputs
    Kage->>GH: Authenticated search request
    GH-->>Kage: Raw issue data
    Note over Kage: Formats + limits to top 10 results
    Kage-->>Agent: Structured JSON result

    Agent->>Kage: tools/call → create_issue(repo, title, body)
    Note over Kage: Validates min_length constraints
    Kage->>GH: POST /repos/{owner}/{repo}/issues
    GH-->>Kage: Created issue data
    Kage-->>Agent: { "html_url": "..." }
```

---

## Available Tools

| Tool | Description | Type |
|:---|:---|:---|
| `test_connection` | Verifies the server is alive and reachable | Read |
| `search_issues` | Search for issues/PRs in a repo using GitHub search syntax | Read |
| `get_issue_details` | Fetch title, body, author, state, and last 5 comments of an issue | Read |
| `create_issue` | Create a new issue with a validated title and body | Write |

### Tool Schemas

#### `search_issues`
```json
{
  "repo": "owner/repo",
  "query": "is:issue is:open label:bug"
}
```

#### `get_issue_details`
```json
{
  "repo": "owner/repo",
  "issue_number": 42
}
```

#### `create_issue`
```json
{
  "repo": "owner/repo",
  "title": "Min 5 characters required",
  "body": "Min 10 characters required"
}
```

---

## Security Design

- **Least-Privilege Tokens:** Uses GitHub Fine-Grained Personal Access Tokens (PAT) scoped to a *single* repository with *only* Issues read/write permission. A compromised token cannot touch any other repo or perform any other action.
- **Pydantic Input Validation:** Every tool input is validated against a strict schema *before* any API call is made. If an LLM hallucinates a bad payload (e.g., an empty issue title), the server rejects it locally with a clear error — no wasted API call, no garbage data in your repo.
- **Additive-Only Writes:** The only write tool (`create_issue`) is additive. Destructive operations (delete, close, edit) are deliberately not exposed — preventing an LLM hallucination from causing irreversible damage.
- **Secret Management:** The GitHub token is loaded from a `.env` file (never hardcoded) and the `.env` is in `.gitignore`.

---

## Project Structure

```
Kage-The-MCP/
├── server.py           # MCP server: all tool definitions and GitHub integration
├── requirements.txt    # Python dependencies
├── .env.example        # Template for environment variables (copy to .env)
├── .gitignore          # Ensures .env and venv are never committed
├── start_inspector.bat # One-click script to launch MCP Inspector for local testing
└── LICENSE             # MIT License
```

---

## Setup & Local Testing

### Prerequisites
- Python 3.10+
- Node.js (for MCP Inspector)
- A GitHub account and a test repository

### 1. Clone & Install
```powershell
git clone https://github.com/YourUsername/Kage-The-MCP.git
cd Kage-The-MCP
python -m venv venv
.\venv\Scripts\activate
pip install -r requirements.txt
```

### 2. Configure Your Token
Create a GitHub Fine-Grained PAT with:
- **Repository access:** Your test repo only
- **Permissions:** Issues → Read and write, Metadata → Read-only

Then create a `.env` file:
```env
GITHUB_TOKEN=github_pat_your_token_here
```

### 3. Run the MCP Inspector
```powershell
.\start_inspector.bat
```
Open the URL shown in your terminal (e.g., `http://localhost:6274`), set Command to `python` and Arguments to `server.py`, then click **Connect**.

---

## Stack

`Python` · `FastMCP (MCP SDK 1.28)` · `PyGithub` · `Pydantic v2` · `python-dotenv` · `MCP Inspector`