Skip to main content
Glama
ompatelz

RepoPilot MCP

by ompatelz
README.md
# RepoPilot MCP

RepoPilot MCP is a small Python Model Context Protocol server for safe,
 GitHub repository inspection with deliberately limited write actions.

RepoPilot is an educational, intentionally smaller implementation for learning
how AI agents, MCP, and GitHub's REST API fit together. GitHub maintains an
official production GitHub MCP server; RepoPilot does not replace it.

## Why I Built This

To build and evaluate an MCP server incrementally: typed GitHub integration,
LLM-friendly tool contracts, bounded context, deliberate write safety, and
deterministic tests rather than a single opaque agent integration.

## Architecture

```mermaid
flowchart LR
  Host[AI host] --> Client[MCP client]
  Client --> Server[RepoPilot MCP server]
  Server --> API[Typed GitHub client]
  API --> GitHub[GitHub REST API]
```

Requests flow from an AI host through MCP tool selection into normalized client
responses; raw GitHub payloads and tokens are not returned to the model.

## Included

- `src/` package layout
- `pyproject.toml` with uv-compatible dependencies
- typed environment configuration
- isolated GitHub REST API client with mocked unit tests
- process logging configuration
- bounded directory and UTF-8 text-file inspection MCP tools
- normalized, read-only GitHub issue inspection MCP tools
- bounded, read-only pull-request and changed-file inspection MCP tools
- pytest coverage for configuration and MCP bootstrap behavior
- `.env.example`, `.gitignore`, GitHub Actions CI, and MIT license

## Requirements

- Python 3.11+
- [uv](https://docs.astral.sh/uv/)

## Setup

```powershell
uv sync --dev
```

For local configuration, copy `.env.example` to `.env` and edit values locally.
Never commit `.env` or real credentials. `GITHUB_TOKEN` is optional for public
repositories, and supports private-repository access and higher API limits.

## Development

CI runs locked dependency installation, Ruff formatting/linting, and the
isolated pytest suite on Python 3.11 and 3.12. It has read-only repository
permissions and never requires GitHub or LLM credentials.

Run tests:

```powershell
uv run pytest
```

Run the local check suite:

```powershell
.\scripts\check.ps1
```

Start the MCP Inspector:

```powershell
.\scripts\dev-inspector.ps1
```

Run the server directly over stdio:

```powershell
uv run repopilot-mcp
```

See [INTEGRATION.md](INTEGRATION.md) for a client configuration example and the
separation between automated MCP checks and an optional manual live smoke test.

## Project Structure

```text
src/repopilot/
  __init__.py
  config.py
  github_client.py
  server.py
tests/
  test_github_client.py
  test_server.py
```

## Current Scope

## MCP Tools

| Category | Tools |
| --- | --- |
| Repository content | `list_directory`, `get_file` |
| Issues | `list_issues`, `get_issue` |
| Pull requests | `list_pull_requests`, `get_pull_request`, `get_pull_request_files` |
| Explicit writes | `create_issue`, `comment_on_issue` |

Read tools inspect only. Write tools have immediate side effects, require a
token, reject empty input, and are never retried automatically.

Implemented, read-only tools:

- `list_directory(owner, repo, path="", ref=None, limit=50)`: start here to
  inspect a repository tree. Results are normalized, sorted with directories
  first, and capped at 100 entries. If a directory is larger than the requested
  limit, the response explicitly reports `truncated: true` and its total count.
- `get_file(owner, repo, path, ref=None)`: use after a file path is known.
  Returns complete UTF-8 text only; it rejects directories, binary/non-UTF-8
  content, unavailable encodings, and files over 100,000 bytes. It never
  silently truncates file content.

The server uses GitHub's Contents API only. It does not clone repositories and
does not provide editing or other write-capable GitHub operations.

Issue inspection uses GitHub's Issues API and remains read-only:

- `list_issues(owner, repo, state="open", labels=None, assignee=None, page=1, limit=30)`
  browses a bounded, filterable page of issues when the issue number is unknown.
  GitHub includes pull requests in this endpoint, so RepoPilot excludes them and
  reports how many were excluded.
- `get_issue(owner, repo, issue_number)` retrieves one known issue. It rejects a
  pull request number rather than presenting it as an issue; pull-request tools
  will be added separately.

Pull-request inspection is also read-only:

- `list_pull_requests(owner, repo, ...)` browses bounded PR summaries when an
  exact pull-request number is unknown.
- `get_pull_request(owner, repo, pull_number)` returns a known PR's branches,
  draft/mergeability state, and change totals.
- `get_pull_request_files(owner, repo, pull_number, ...)` returns changed-file
  metadata and available patches. Patches over 12,000 characters are explicitly
  truncated; unavailable patches remain `null`.

## Write Safety

The only write tools are `create_issue` and `comment_on_issue`. Both require a
`GITHUB_TOKEN`, validate their inputs before contacting GitHub, and are never
automatically retried. They should be used only with explicit user instruction.
GitHub's issue-comment endpoint also supports pull-request conversation comments;
this does not add review, approval, merge, or other pull-request write support.

## Reliability and Security

- Secrets are read only from `GITHUB_TOKEN`; RepoPilot neither logs nor returns it.
- Requests use the configured timeout and distinguish authentication, permission,
  rate-limit, not-found, validation, server, timeout, and network failures.
- RepoPilot does not retry requests automatically. This deliberately prevents
  duplicate issue or comment creation when a write response is uncertain.
- Unit tests use mocked HTTP only; CI never needs GitHub or LLM credentials.

## Evaluation

`evaluation_cases.json` contains 15 provider-neutral cases covering discovery,
files, issues, PRs, tool choice, unknown information, and permitted writes.
Record outcomes from a baseline model and the same model with RepoPilot, then
score them with `repopilot.evaluation.score`. The harness reports accuracy,
completion, hallucination, tool selection, calls, latency, and errors; it does
not call an LLM or fabricate benchmark results.

## Limitations and Future Work

RepoPilot does not support OAuth, GraphQL, remote transport, file mutation,
branch creation, PR creation/merging, workflow execution, or permission edits.
Potential extensions remain deliberately out of scope until explicitly chosen.

## Demo

See [DEMO.md](DEMO.md) for a concise portfolio/demo sequence. See
[INTEGRATION.md](INTEGRATION.md) for client setup and the manual smoke test.

TDQS

B3.4/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of ambiguity or overlap between tools.

Naming Consistency5/5

With a single tool named 'health', the naming is unambiguous and internally consistent.

Tool Count1/5

The server provides only one trivial health-check tool, which is an extreme under-provisioning for a server presumably intended for repository management.

Completeness1/5

The sole tool only reports health status, leaving no functionality for actual repository operations, making the surface severely incomplete for the stated domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues