Git RAG MCP Server
# Git RAG MCP Server
A practical MCP (Model Context Protocol) project that connects an LLM to multiple custom MCP servers.
The project demonstrates how an MCP client can communicate with specialized servers for:
* GitHub operations
* Employee document RAG
* QA and test-case generation
The goal of this project is to understand and demonstrate MCP architecture, tool calling, resources, prompts, RAG retrieval, and multi-server communication.
---
## Architecture
```text
┌──────────────────┐
│ UI │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ MCP Client │
│ │
│ Tool discovery │
│ Tool calling │
│ LLM interaction │
└────────┬─────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌──────────────┐ ┌──────────────┐
│ GitHub Server │ │ RAG Server │ │ QA Server │
└───────┬────────┘ └──────┬───────┘ └──────────────┘
│ │
▼ ▼
GitHub REST API Employee PDF
TF-IDF Search
```
---
# Project Structure
```text
git-mcp-server/
│
├── client/
│ └── client.py
│
├── servers/
│ ├── git_server.py
│ ├── rag_server.py
│ └── qa_server.py
│
├── data/
│ └── Employee_Details.pdf
│
├── .env
├── pyproject.toml
├── uv.lock
└── README.md
```
---
# MCP Servers
## 1. GitHub Server
File:
```text
servers/git_server.py
```
The GitHub server communicates with the GitHub REST API using an authenticated GitHub token.
It provides tools for:
* Getting the authenticated GitHub user
* Listing repositories
* Getting repository information
* Searching issues
* Reading file content
* Listing repository files
* Searching repository code
### Available Tools
```text
get_github_user()
list_repositories()
get_repository(owner, repo)
search_issues(query, top_k)
get_file_content(owner, repo, path, ref)
list_files(owner, repo, path, ref)
search_code(owner, repo, query, top_k)
```
---
# 2. RAG Server
File:
```text
servers/rag_server.py
```
The RAG server searches employee information stored in:
```text
data/Employee_Details.pdf
```
The server:
1. Extracts text from the PDF
2. Identifies employee records
3. Creates employee chunks
4. Builds a TF-IDF vector index
5. Uses cosine similarity for retrieval
6. Combines TF-IDF similarity with keyword matching
7. Returns the most relevant employee records
### Available Tools
```text
search_employees(query, top_k)
show_chunks(start, count)
get_chunk_count()
```
### Example
```text
User:
Find information about Ravi Rao
```
The MCP client can call:
```text
search_employees(
query="Ravi Rao",
top_k=5
)
```
The RAG server returns the most relevant employee records with relevance scores.
---
# 3. QA Server
File:
```text
servers/qa_server.py
```
The QA server provides testing capabilities for the MCP project.
It is designed to help test the GitHub and RAG servers rather than duplicate their functionality.
## MCP Tools
### create_test_case()
Creates a standardized test case.
Example:
```text
create_test_case(
name="Search code for a known term",
tool_name="search_code",
input_data="...",
expected_result="..."
)
```
Example output:
```text
TEST CASE
Name: Search code for a known term
Tool: search_code
Input:
...
Expected Result:
...
Status: Not Executed
```
### validate_github_result()
Performs basic validation of results returned by GitHub tools.
Supported operations include:
```text
get_github_user
list_repositories
get_repository
search_issues
get_file_content
list_files
search_code
```
The validator checks whether expected fields are present and returns:
```text
PASS
```
or:
```text
FAIL
```
### validate_rag_result()
Performs basic validation of results returned by RAG tools.
Supported operations include:
```text
search_employees
show_chunks
get_chunk_count
```
---
# QA Resource
The QA server exposes:
```text
qa://mcp-test-checklist
```
The resource contains a reusable checklist covering:
* GitHub server testing
* RAG server testing
* MCP integration testing
* Invalid inputs
* Empty results
* Authentication errors
* Tool discovery
* Tool argument handling
---
# QA Prompt
The QA server exposes:
```text
generate_mcp_test_plan(component)
```
It generates a reusable prompt for creating test plans.
The generated test plan includes:
* Positive test cases
* Negative test cases
* Boundary cases
* Invalid input cases
* Empty-result cases
* Error cases
* MCP integration cases
* Expected results
---
# MCP Primitives Demonstrated
This project demonstrates the three major MCP server primitives.
```text
Tool
↓
Performs an action
Resource
↓
Provides read-only context
Prompt
↓
Provides reusable prompt templates
```
The project therefore demonstrates:
```text
GitHub Server
└── Tools
RAG Server
└── Tools
QA Server
├── Tools
├── Resource
└── Prompt
```
---
# Environment Variables
Create a `.env` file in the project root.
Example:
```env
GITHUB_TOKEN=your_github_token
```
The GitHub server reads the token from the environment and uses it for authenticated GitHub API requests.
Do not commit `.env` to Git.
Add:
```text
.env
```
to `.gitignore`.
---
# Installation
This project uses `uv` for Python environment and dependency management.
Create/sync the environment:
```bash
uv sync
```
Run Python through the project environment:
```bash
uv run python ...
```
---
# Running the Servers
The MCP servers use stdio communication.
For example:
```bash
uv run python servers/qa_server.py
```
The server will wait for an MCP client.
This is expected behavior.
The server should normally be launched by the MCP client rather than manually interacted with from the terminal.
---
# Running the MCP Client
Run:
```bash
uv run python client/client.py
```
The client connects to the configured MCP servers and discovers their available capabilities.
The general flow is:
```text
Client starts
↓
Connect to MCP servers
↓
Discover tools/resources/prompts
↓
Send available capabilities to LLM
↓
User asks a question
↓
LLM decides whether a tool is required
↓
MCP client executes the requested tool
↓
Tool result returned
↓
LLM generates final response
```
---
# Example: QA Test Case
User:
```text
Create a test case for the search_code tool.
```
The LLM can select:
```text
create_test_case
```
with arguments such as:
```json
{
"name": "Search code for a known term",
"tool_name": "search_code",
"input_data": "...",
"expected_result": "..."
}
```
The QA server returns the formatted test case.
---
# Example: Employee Search
User:
```text
Find Ravi Rao
```
The client can select:
```text
search_employees
```
The RAG server performs retrieval against the employee PDF.
```text
Question
↓
search_employees
↓
TF-IDF retrieval
+
keyword matching
↓
Relevant employee records
↓
MCP client
↓
LLM response
```
---
# Example: GitHub Search
User:
```text
Search for MCPServer in my repository.
```
The client can call:
```text
search_code(
owner="...",
repo="...",
query="MCPServer",
top_k=10
)
```
The GitHub server communicates with the GitHub API and returns matching code results.
---
# Example: QA Validation
A GitHub operation can be followed by QA validation:
```text
search_code
↓
GitHub result
↓
validate_github_result
↓
PASS / FAIL
```
Similarly:
```text
search_employees
↓
RAG result
↓
validate_rag_result
↓
PASS / FAIL
```
This demonstrates the concept of using multiple MCP capabilities together.
---
# Technologies Used
* Python
* Model Context Protocol (MCP)
* MCP Python SDK
* uv
* GitHub REST API
* httpx
* python-dotenv
* PyPDF
* scikit-learn
* TF-IDF
* Cosine similarity
---
# What This Project Demonstrates
This project is intended as a practical MCP learning project.
It demonstrates:
### MCP
* MCP client
* MCP servers
* Tool discovery
* Tool calling
* Resources
* Prompts
* stdio transport
* Multiple MCP servers
### GitHub Integration
* Authentication
* GitHub REST API requests
* Repository operations
* Issue search
* File operations
* Code search
### RAG
* PDF ingestion
* Document chunking
* TF-IDF indexing
* Similarity search
* Keyword matching
* Retrieval results
### QA
* Test-case generation
* Result validation
* QA checklists
* Reusable test-plan prompts
---
# Current Limitation
The QA server's `create_test_case()` tool currently **creates a test definition but does not execute the test automatically**.
For example:
```text
create_test_case()
↓
Test case created
↓
Status: Not Executed
```
Automatic execution would require the MCP client to orchestrate multiple tool calls:
```text
create test
↓
execute target tool
↓
capture result
↓
validate result
↓
PASS / FAIL
```
This can be implemented as a future enhancement.
---
# Future Improvements
Possible next improvements include:
1. Automatic multi-tool QA workflows
2. Automatic test execution
3. PASS/FAIL test reports
4. Test history
5. ChatGPT-style UI
6. More GitHub operations
7. Better RAG retrieval
8. Source/chunk citations
9. Automated regression testing
10. More MCP servers
---
# Learning Objective
The main objective of this project is not to build a production GitHub client or production RAG system.
The objective is to understand how an LLM application can use MCP to connect to multiple specialized capabilities.
The core architecture is:
```text
LLM
│
▼
MCP Client
│
┌──────────┼──────────┐
▼ ▼ ▼
GitHub RAG QA
Server Server Server
│ │ │
▼ ▼ ▼
GitHub API PDF/RAG Testing
```
Each server has a clear responsibility, while the MCP client acts as the central communication layer.
TDQS
Scored across 3 tools
Create_test_case is distinct in purpose from the two validate_* tools. The two validators are parallel and could be momentarily confused, but their names clearly indicate the GitHub vs RAG domain, so boundaries are mostly clear.
All tool names follow a consistent snake_case verb_noun pattern: create_test_case, validate_github_result, validate_rag_result. The convention is predictable and uniform.
Three tools is a small but reasonable set for a focused testing utility. It is slightly on the low side, but each tool has a clear role and the count does not feel excessive or arbitrarily inflated.
The domain is a testing harness for MCP tools, yet there is no tool to run a test case, list/retrieve existing test cases, or update/delete them. Validation covers only GitHub and RAG results, leaving other potential MCP results unsupported, which creates significant gaps for realistic workflows.