USAGE.mdâĸ32.7 kB
# Yellhorn MCP - Usage Guide
## Overview
Yellhorn MCP is a Model Context Protocol (MCP) server that allows Claude Code to interact with Gemini 2.5 Pro, OpenAI, and xAI Grok APIs for software development tasks. Version 0.7.0 introduces major improvements including unified LLM management, automatic chunking, and robust retry logic.
### What's New in v0.7.0
- **đ Unified LLM Manager**: Centralized management for both OpenAI and Gemini models with automatic retry logic
- **đ§Š Smart Chunking**: Automatic prompt chunking when content exceeds model context limits
- **đ Enhanced Token Counting**: Support for latest models with accurate token estimation
- **đ° Cost Tracking**: Real-time cost estimation and usage tracking
- **⥠Performance Optimizations**: Better handling of large codebases and rate limits
## Main Tools
1. **Create workplan**: Creates a GitHub issue with a detailed implementation plan based on your codebase and task description.
2. **Get workplan**: Retrieves the workplan content from a GitHub issue.
3. **Judge workplan**: Triggers an asynchronous code judgement for a Pull Request against its original workplan issue.
4. **Curate context**: Analyzes your codebase structure to build an optimized .yellhorncontext file with directory filtering rules.
5. **Revise workplan**: Updates an existing workplan based on revision instructions.
## Installation
### Project bootstrap (uv)
```bash
# Install from source
git clone https://github.com/msnidal/yellhorn-mcp.git
cd yellhorn-mcp
# Provision the environment and install dependencies
uv sync --group dev
# Optional: activate the environment for direct shell usage
source .venv/bin/activate
# Verify the CLI entrypoint
uv run yellhorn-mcp --help
```
### Install from PyPI
```bash
uv pip install yellhorn-mcp
```
## Configuration
The server requires the following environment variables:
- `GEMINI_API_KEY` (required for Gemini models): Your Gemini API key
- `OPENAI_API_KEY` (required for OpenAI models): Your OpenAI API key
- `XAI_API_KEY` (required for Grok models): Your xAI API key
- `REPO_PATH` (optional): Path to your Git repository (defaults to current directory)
- `YELLHORN_MCP_MODEL` (optional): Model to use (defaults to "gemini-2.5-pro"). Available options:
- **Gemini models**: "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"
- **OpenAI models**: "gpt-4o", "gpt-4o-mini", "o4-mini", "o3", "gpt-4.1"
- **GPT-5 models**: "gpt-5", "gpt-5-mini", "gpt-5-nano" (support reasoning mode for gpt-5 and gpt-5-mini)
- **xAI Grok models**: "grok-4" (256K context window) and "grok-4-fast" (2M context window)
- **Deep Research models**: "o3-deep-research", "o4-mini-deep-research"
- Note: Deep Research models (including GPT-5) automatically enable `web_search_preview` and `code_interpreter` tools for enhanced research capabilities
- `YELLHORN_MCP_REASONING_EFFORT` (optional): Set reasoning effort level for GPT-5 models. Options: "low", "medium", "high". This provides enhanced reasoning capabilities at higher cost for supported models (gpt-5, gpt-5-mini). The effort level determines the amount of compute used for reasoning, with higher levels providing more thorough reasoning at increased cost. When set, the server propagates the effort into all generation calls and cost metrics incorporate the corresponding reasoning rates.
- `YELLHORN_MCP_SEARCH` (optional): Enable/disable Google Search Grounding (defaults to "on" for Gemini models). Options:
- "on" - Search grounding enabled for Gemini models
- "off" - Search grounding disabled for all models
> **Note:** Grok models now use the official `xai-sdk`. Ensure the dependency is installed in the environment where the server runs (it's already listed in `pyproject.toml`).
### File Filtering with .yellhorncontext and .yellhornignore
You can control which files are included in the AI context using either a `.yellhorncontext` or `.yellhornignore` file in your repository root. The `.yellhorncontext` file takes precedence if both exist:
#### .yellhorncontext File (Recommended)
The `.yellhorncontext` file is the recommended approach as it provides more comprehensive control, with both directory-specific patterns and inherited patterns from `.yellhornignore`:
```
# Yellhorn Context File - AI context optimization
# Generated by yellhorn-mcp curate_context tool
# Based on task: Implementing a user authentication system
# Patterns from .yellhornignore file
# Files and directories to exclude (blacklist)
node_modules/
dist/
*.log
# Explicitly included patterns (whitelist)
!important.log
# Task-specific directories for AI context
# Important directories to specifically include
!./
!src/
!src/auth/
!src/models/
!tests/
!tests/auth/
# Recommended: blacklist everything else (uncomment to enable)
# **/*
```
#### .yellhornignore File (Legacy)
You can also use a `.yellhornignore` file which works similar to `.gitignore` but is specific to the Yellhorn MCP server:
```
# Example .yellhornignore file
# Blacklist patterns
*.log
node_modules/
dist/
*.min.js
credentials/
# Whitelist patterns (exceptions to blacklist)
!important.log
!node_modules/important-package.json
```
#### Pattern Syntax and Processing
Both files use the same pattern syntax as `.gitignore`:
- Lines starting with `#` are comments
- Empty lines are ignored
- Patterns use shell-style wildcards (e.g., `*.js`, `node_modules/`)
- Patterns ending with `/` will match directories
- Patterns containing `/` are relative to the repository root
- Patterns starting with `!` are whitelist patterns (exceptions to ignores)
**Blacklist and Whitelist Processing:**
- Standard patterns (without `!`) will ignore matching files
- Patterns starting with `!` will whitelist matching files, even if they match an ignore pattern
- Whitelist patterns are checked first, so they take precedence over blacklist patterns
- This allows you to have broad blacklist patterns with specific exceptions
**Priority Order:**
1. `.yellhorncontext` (if it exists) is used first
2. `.yellhornignore` (if `.yellhorncontext` doesn't exist) is used as fallback
3. `.gitignore` (already respected by Git commands used to list files)
This feature is useful for:
- Focusing AI on the most relevant directories for your specific task
- Excluding large folders that wouldn't provide useful context (e.g., `node_modules/`)
- Excluding sensitive or credential-related files
- Reducing noise in the AI's context to improve focus on relevant code
- Allowing specific important files through blacklist patterns (e.g., `!config/important.json`)
The server requires GitHub CLI (`gh`) to be installed and authenticated:
```bash
# Install GitHub CLI (if not already installed)
# For macOS:
brew install gh
# For Ubuntu/Debian:
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh
# Authenticate with GitHub
gh auth login
```
```bash
# Set environment variables for Gemini models
export GEMINI_API_KEY=your_gemini_api_key_here
export REPO_PATH=/path/to/your/repo
export YELLHORN_MCP_MODEL=gemini-2.5-pro
# OR for OpenAI models
export OPENAI_API_KEY=your_openai_api_key_here
export REPO_PATH=/path/to/your/repo
export YELLHORN_MCP_MODEL=gpt-4o
# OR for xAI Grok models
export XAI_API_KEY=your_xai_api_key_here
export REPO_PATH=/path/to/your/repo
export YELLHORN_MCP_MODEL=grok-4
```
### VSCode/Cursor Setup
To configure Yellhorn MCP in VSCode or Cursor, create a `.vscode/mcp.json` file in your workspace root with the following content:
```json
{
"inputs": [
{
"type": "promptString",
"id": "gemini-api-key",
"description": "Gemini API Key"
}
],
"servers": {
"yellhorn-mcp": {
"type": "stdio",
"command": "uv",
"args": ["run", "yellhorn-mcp"],
"env": {
"GEMINI_API_KEY": "${input:gemini-api-key}",
"REPO_PATH": "${workspaceFolder}",
"YELLHORN_MCP_SEARCH": "on"
}
}
}
}
```
If you plan to use Grok models in this setup, add `"XAI_API_KEY": "${input:xai-api-key}"` (and optionally an input prompt) to the `env` map so the CLI can authenticate with xAI.
### Claude Code Setup
To configure Yellhorn MCP with Claude Code directly, add a root-level `.mcp.json` file in your project with the following content:
```json
{
"mcpServers": {
"yellhorn-mcp": {
"type": "stdio",
"command": "uv",
"args": ["run","yellhorn-mcp","--model","o3"],
"env": {
"YELLHORN_MCP_SEARCH": "on"
}
}
}
}
```
When targeting Grok models via Claude Code, include `"XAI_API_KEY": "your_xai_api_key"` in the `env` section to enable the integration via the native xAI SDK.
## Getting Started
Once the server is running, Claude Code can utilize the tools it exposes. Here's a typical workflow:
### 1. Creating a workplan
```
Please generate a workplan for implementing a user authentication system in my application.
```
This will use the `create_workplan` tool to analyze your codebase, create a GitHub issue, and populate it with a detailed implementation plan. The tool will return the issue URL and number. The issue will initially show a placeholder message and will be updated asynchronously once the plan is generated.
### 2. View the workplan
To view a workplan, use the following command:
```
Please retrieve the workplan for issue #123.
```
This will use the `get_workplan` tool to fetch the latest content of the GitHub issue.
### 3. Make Changes and Create a PR
After making changes to implement the workplan, create a PR using your preferred method:
```bash
# Manual Git flow
git add .
git commit -m "Implement user authentication"
git push origin HEAD
# GitHub CLI
gh pr create --title "Implement User Authentication" --body "This PR adds JWT authentication with bcrypt password hashing."
```
### 4. Request a Judgement
Once your PR is created, you can request a judgement against the original workplan:
```
Please judge the PR comparing "main" and "feature-branch" against the workplan in issue #456.
```
This will use the `judge_workplan` tool to:
1. **Immediately create** a placeholder sub-issue with the judgement task details
2. **Return the sub-issue URL** so you can track progress
3. **Process the judgement asynchronously** by fetching the original workplan, generating a diff between the specified git references, and running AI analysis
4. **Update the placeholder sub-issue** with the complete judgement results, including detailed analysis, citations, and completion metrics
The placeholder sub-issue is labeled with `yellhorn-judgement-subissue` and linked to the original workplan issue for easy reference.
## MCP Tools
### create_workplan
Creates a GitHub issue with a detailed workplan based on the title and detailed description. The issue is labeled with 'yellhorn-mcp' and the plan is generated asynchronously (with `codebase_reasoning="full"`), with the issue being updated once it's ready. For faster creation without AI enhancement, use `codebase_reasoning="none"`.
**Input**:
- `title`: Title for the GitHub issue (will be used as issue title and header)
- `detailed_description`: Detailed description for the workplan. Any URLs provided here will be extracted and included in a References section in the workplan.
- `codebase_reasoning`: (optional) Control whether AI enhancement is performed:
- `"full"`: (default) Use AI to enhance the workplan with full codebase context
- `"lsp"`: Use AI with lightweight codebase context (function/method signatures, class attributes and struct fields for Python and Go)
- `"none"`: Skip AI enhancement, use the provided description as-is
- `debug`: (optional) If set to `true`, adds a comment to the issue with the full prompt used for generation
- `disable_search_grounding`: (optional) If set to `true`, disables Google Search Grounding for this request
**Output**:
- JSON string containing:
- `issue_url`: URL to the created GitHub issue
- `issue_number`: The GitHub issue number
**Error Handling**:
If AI enhancement fails when using `codebase_reasoning="full"`, a comment will be added to the issue with the error details, but the original issue body with title and description will be preserved.
### get_workplan
Retrieves the workplan content (GitHub issue body) associated with a specified GitHub issue.
**Input**:
- `issue_number`: The GitHub issue number for the workplan.
- `disable_search_grounding`: (optional) If set to `true`, disables Google Search Grounding for this request
**Output**:
- The content of the workplan issue as a string
### revise_workplan
Updates an existing workplan based on revision instructions. The tool fetches the current workplan from the specified GitHub issue and uses AI to revise it according to your instructions.
**Input**:
- `issue_number`: The GitHub issue number containing the workplan to revise
- `revision_instructions`: Instructions describing how to revise the workplan (e.g., "Add more detail about testing", "Include database migration steps", "Update to use React instead of Vue")
- `codebase_reasoning`: (optional) Control whether AI enhancement is performed:
- `"full"`: (default) Use AI to revise with full codebase context
- `"lsp"`: Use AI with lightweight codebase context (function/method signatures only)
- `"file_structure"`: Use AI with directory structure only (fastest)
- `"none"`: Minimal codebase context
- `debug`: (optional) If set to `true`, adds a comment to the issue with the full prompt used for generation
- `disable_search_grounding`: (optional) If set to `true`, disables Google Search Grounding for this request
**Output**:
- JSON string containing:
- `issue_url`: URL to the updated GitHub issue
- `issue_number`: The GitHub issue number
**Example Usage**:
```
Please revise workplan #123 to include more detail about error handling and recovery mechanisms.
```
This will:
1. Fetch the existing workplan from issue #123
2. Add a submission comment indicating the revision is in progress
3. Launch a background task to revise the workplan based on your instructions
4. Update the issue with the revised workplan once complete
5. Add a completion comment with metrics
### curate_context
Analyzes the codebase structure to build a .yellhorncontext file with optimized directory filtering rules customized for your specific task. This tool creates a comprehensive context file that includes both blacklist/whitelist patterns to ensure the AI has access to the most relevant directories.
**Input**:
- `user_task`: Description of the task you're working on, used to customize directory selection.
- `codebase_reasoning`: (optional) Analysis mode for codebase structure. Options:
- `"full"`: Performs deep analysis with all codebase context (default)
- `"file_structure"`: Lightweight analysis based only on file/directory structure
- `"lsp"`: Analysis using programming language constructs (functions, classes)
- `ignore_file_path`: (optional) Path to the .yellhornignore file to use. Defaults to ".yellhornignore".
- `output_path`: (optional) Path where the .yellhorncontext file will be created. Defaults to ".yellhorncontext".
- `depth_limit`: (optional) Maximum directory depth to analyze (0 means no limit).
- `disable_search_grounding`: (optional) If set to `true`, disables Google Search Grounding for this request
**Output**:
- Success message with path to created .yellhorncontext file and number of important directories.
**Notes**:
- This tool reads all files not blacklisted/whitelisted from the .yellhornignore file (if it exists).
- It generates a new .yellhorncontext file or overwrites an existing one each time it's called.
- The .yellhorncontext file is prioritized over .yellhornignore for file filtering in all tools.
- It uses chunked LLM calls to process large codebases, analyzing directory structure and identifying important directories.
- The generated file includes:
- Blacklist patterns from .yellhornignore (if it exists)
- Whitelist patterns from .yellhornignore (if it exists)
- Task-specific important directories as explicit whitelist patterns
- Recommended global blacklist pattern (commented out by default)
- The tool customizes directory selection based on the specific task you're working on, ensuring the AI focuses on the most relevant parts of your codebase.
- Three different reasoning modes allow for flexibility in how the codebase is analyzed:
- `full`: Most comprehensive analysis, includes file contents samples
- `file_structure`: Fastest analysis based only on file paths, best for large codebases
- `lsp`: Language-aware analysis, helps identify relevant code constructs
- You can customize the output location using the `output_path` parameter if you don't want to use the default ".yellhorncontext" at the repository root.
**Example Usage**:
```
Please create a .yellhorncontext file optimized for "implementing a user authentication system with JWT tokens".
```
This will analyze your codebase with your specific task in mind, creating a .yellhorncontext file that:
1. Preserves existing filtering from .yellhornignore (if it exists)
2. Identifies the most important directories relevant to authentication and JWT tokens
3. Creates explicit whitelist rules for those directories
4. Provides a commented-out global blacklist rule that can be enabled for stricter filtering
### judge_workplan
Triggers an asynchronous code judgement comparing two git refs (branches or commits) against a workplan described in a GitHub issue. Creates a placeholder GitHub sub-issue immediately and then processes the AI judgement asynchronously, updating the sub-issue with results.
**Workflow**:
1. **Immediate Response**: Creates a placeholder sub-issue with task details and metadata
2. **Asynchronous Processing**: Generates the AI judgement in the background
3. **Sub-issue Update**: Updates the placeholder with the complete judgement, including comparison metadata, detailed analysis, citations (if available), and completion metrics
**Input**:
- `issue_number`: The GitHub issue number for the workplan.
- `base_ref`: Base Git ref (commit SHA, branch name, tag) for comparison. Defaults to 'main'.
- `head_ref`: Head Git ref (commit SHA, branch name, tag) for comparison. Defaults to 'HEAD'.
- `codebase_reasoning`: (optional) Control which codebase context is provided:
- `"full"`: (default) Use full codebase context
- `"lsp"`: Use lighter codebase context (function signatures, class attributes, etc. for Python and Go, plus full diff files)
- `"file_structure"`: Use only directory structure without file contents for faster processing
- `"none"`: Skip codebase context completely for fastest processing
- `debug`: (optional) If set to `true`, adds a comment to the sub-issue with the full prompt used for generation
- `disable_search_grounding`: (optional) If set to `true`, disables Google Search Grounding for this request
Any URLs mentioned in the workplan will be extracted and preserved in a References section in the judgement.
**Output**:
- JSON string containing:
- `message`: Confirmation that the judgement task has been initiated
- `subissue_url`: URL to the created placeholder sub-issue where results will be posted
- `subissue_number`: The GitHub issue number of the placeholder sub-issue
**Labels**:
The created sub-issue is labeled with `yellhorn-judgement-subissue` for easy identification and filtering.
## MCP Resources
Yellhorn MCP implements the standard MCP resource API to provide easy access to workplans:
### Resource Type: yellhorn_workplan
Represents a GitHub issue created by the Yellhorn MCP server with a detailed implementation plan.
**Resource Fields**:
- `id`: The GitHub issue number
- `type`: Always "yellhorn_workplan"
- `name`: The title of the GitHub issue
- `metadata`: Additional information about the issue, including its URL
### Accessing Resources
Use the standard MCP commands to list and access workplans:
```bash
# List all workplans
mcp list-resources yellhorn-mcp
# Get a specific workplan by issue number
mcp get-resource yellhorn-mcp 123
```
Or programmatically with the MCP client API:
```python
# List workplans
resources = await session.list_resources()
# Get a workplan by ID
workplan = await session.get_resource("123")
```
## Integration with Other Programs
### HTTP API
When running in standalone mode, Yellhorn MCP exposes a standard HTTP API that can be accessed by any HTTP client:
```bash
# Run the server with default settings (search grounding enabled for Gemini models)
yellhorn-mcp --host 127.0.0.1 --port 8000
# Run the server with search grounding disabled
yellhorn-mcp --host 127.0.0.1 --port 8000 --no-search-grounding
```
You can then make requests to the server's API endpoints:
```bash
# Get the OpenAPI schema
curl http://127.0.0.1:8000/openapi.json
# List available tools
curl http://127.0.0.1:8000/tools
# Call a tool (create_workplan with full codebase context)
curl -X POST http://127.0.0.1:8000/tools/create_workplan \
-H "Content-Type: application/json" \
-d '{"title": "User Authentication System", "detailed_description": "Implement a secure authentication system using JWT tokens and bcrypt for password hashing", "codebase_reasoning": "full"}'
# Call a tool (create_workplan with lightweight LSP context - function signatures only)
curl -X POST http://127.0.0.1:8000/tools/create_workplan \
-H "Content-Type: application/json" \
-d '{"title": "User Authentication System", "detailed_description": "Implement a secure authentication system using JWT tokens and bcrypt for password hashing", "codebase_reasoning": "lsp"}'
# Call a tool (create_workplan without AI enhancement)
curl -X POST http://127.0.0.1:8000/tools/create_workplan \
-H "Content-Type: application/json" \
-d '{"title": "User Authentication System", "detailed_description": "Implement a secure authentication system using JWT tokens and bcrypt for password hashing", "codebase_reasoning": "none"}'
# Call a tool (get_workplan)
curl -X POST http://127.0.0.1:8000/tools/get_workplan \
-H "Content-Type: application/json" \
-d '{"issue_number": "123"}'
# Call a tool (revise_workplan)
curl -X POST http://127.0.0.1:8000/tools/revise_workplan \
-H "Content-Type: application/json" \
-d '{"issue_number": "123", "revision_instructions": "Add more detail about error handling and recovery mechanisms", "codebase_reasoning": "full"}'
# Call a tool (curate_context)
curl -X POST http://127.0.0.1:8000/tools/curate_context \
-H "Content-Type: application/json" \
-d '{"user_task": "Implementing a user authentication system with JWT tokens", "codebase_reasoning": "file_structure", "output_path": ".yellhorncontext"}'
# Call a tool (judge_workplan with full codebase context - default)
curl -X POST http://127.0.0.1:8000/tools/judge_workplan \
-H "Content-Type: application/json" \
-d '{"issue_number": "456", "base_ref": "main", "head_ref": "feature-branch"}'
# Call a tool (judge_workplan with lightweight LSP context)
curl -X POST http://127.0.0.1:8000/tools/judge_workplan \
-H "Content-Type: application/json" \
-d '{"issue_number": "456", "base_ref": "main", "head_ref": "feature-branch", "codebase_reasoning": "lsp"}'
```
### Example Client
The package includes an example client that demonstrates how to interact with the server programmatically:
```bash
# List available tools
python -m examples.client_example list
# Generate a workplan with full codebase context (default)
python -m examples.client_example plan --title "User Authentication System" --description "Implement a secure authentication system using JWT tokens and bcrypt for password hashing"
# Generate a workplan with lightweight LSP context (function signatures only)
python -m examples.client_example plan --title "User Authentication System" --description "Implement a secure authentication system using JWT tokens and bcrypt for password hashing" --codebase-reasoning lsp
# Generate a basic workplan without AI enhancement
python -m examples.client_example plan --title "User Authentication System" --description "Implement a secure authentication system using JWT tokens and bcrypt for password hashing" --codebase-reasoning none
# Get workplan
python -m examples.client_example getplan --issue-number "123"
# Generate a .yellhorncontext file (using file_structure mode for fast analysis)
python -m examples.client_example curate-context --user-task "Implementing a user authentication system with JWT tokens" --codebase-reasoning file_structure
# Judge work with full codebase context (default)
python -m examples.client_example judge --issue-number "456" --base-ref "main" --head-ref "feature-branch"
# Judge work with lightweight LSP context (function signatures + full diff files)
python -m examples.client_example judge --issue-number "456" --base-ref "main" --head-ref "feature-branch" --codebase-reasoning lsp
```
The example client uses the MCP client API to interact with the server through stdio transport, which is the same approach Claude Code uses.
## Debugging and Troubleshooting
### Common Issues
1. **API Key Not Set**: Make sure your `GEMINI_API_KEY` or `OPENAI_API_KEY` environment variable is set depending on your chosen model.
2. **Not a Git Repository**: Ensure that `REPO_PATH` points to a valid Git repository.
3. **GitHub CLI Issues**: Ensure GitHub CLI (`gh`) is installed, accessible in your PATH, and authenticated.
4. **MCP Connection Issues**: If you have trouble connecting to the server, check that you're using the latest version of the MCP SDK.
5. **Rate Limit Errors**: The server now automatically retries with exponential backoff, but persistent rate limits may indicate quota issues.
6. **Large Codebase Issues**: The server automatically chunks large prompts, but very large codebases may still hit limits.
### Error Messages
- `GEMINI_API_KEY is required`: Set your Gemini API key as an environment variable.
- `OPENAI_API_KEY is required`: Set your OpenAI API key as an environment variable.
- `Not a Git repository`: The specified path is not a Git repository.
- `Git executable not found`: Ensure Git is installed and accessible in your PATH.
- `GitHub CLI not found`: Ensure GitHub CLI (`gh`) is installed and accessible in your PATH.
- `GitHub CLI command failed`: Check that GitHub CLI is authenticated and has appropriate permissions.
- `Failed to generate workplan`: Check the API key and model name for your chosen provider.
- `Failed to create GitHub issue`: Check GitHub CLI authentication and permissions.
- `Failed to fetch GitHub issue/PR content`: The issue or PR URL may be invalid or inaccessible.
- `Failed to fetch GitHub PR diff`: The PR URL may be invalid or inaccessible.
- `Failed to post GitHub PR review`: Check GitHub CLI permissions for posting PR comments.
- `Rate limit exceeded`: The server will automatically retry, but check your API quota if persistent.
- `Context window exceeded`: The server will automatically chunk large prompts, but very large codebases may still hit limits.
## CI/CD
The project includes GitHub Actions workflows for automated testing and deployment.
### Testing Workflow
The testing workflow automatically runs when:
- Pull requests are opened against the main branch
- Pushes are made to the main branch
It performs the following steps:
1. Sets up Python environments (3.10 and 3.11)
2. Installs dependencies
3. Runs linting with flake8
4. Checks formatting with black
5. Runs tests with pytest
6. Checks test coverage against required thresholds (âĨ 70% line coverage)
The workflow configuration is in `.github/workflows/tests.yml`.
### Publishing Workflow
The publishing workflow automatically runs when:
- A version tag (v*) is pushed to the repository
It performs the following steps:
1. Sets up Python 3.10
2. Verifies that the tag version matches the version in pyproject.toml
3. Builds the package
4. Publishes the package to PyPI
The workflow configuration is in `.github/workflows/publish.yml`.
#### Publishing Requirements
To publish to PyPI, you need to:
1. Create a PyPI API token
2. Store it as a repository secret in GitHub named `PYPI_API_TOKEN`
#### Creating a PyPI API Token
1. Log in to your PyPI account
2. Go to Account Settings > API tokens
3. Create a new token with scope "Entire account" or specific to the yellhorn-mcp project
4. Copy the token value
#### Adding the Secret to GitHub
1. Go to your GitHub repository
2. Navigate to Settings > Secrets and variables > Actions
3. Click "New repository secret"
4. Set the name to `PYPI_API_TOKEN`
5. Paste the token value
6. Click "Add secret"
#### Releasing a New Version
1. Update the version in pyproject.toml
2. Update the version in yellhorn_mcp/**init**.py (if needed)
3. Commit changes: `git commit -am "Bump version to X.Y.Z"`
4. Tag the commit: `git tag vX.Y.Z`
5. Push changes and tag: `git push && git push --tags`
The publishing workflow will automatically run when the tag is pushed, building and publishing the package to PyPI.
## Advanced Configuration
For advanced use cases, you can modify the server's behavior by editing the source code:
- Adjust the prompt templates in `process_workplan_async` and `process_judgement_async` functions
- Modify the codebase preprocessing in `get_codebase_snapshot` and `format_codebase_for_prompt`
- Change the Gemini model version with the `YELLHORN_MCP_MODEL` environment variable
- Toggle Google Search Grounding with the `YELLHORN_MCP_SEARCH` environment variable
- Customize the directory tree representation in `tree_utils.py`
- Add support for additional languages in the LSP mode by extending `lsp_utils.py`
## LSP Mode Language Support
The "lsp" codebase reasoning mode provides a lightweight representation of your codebase by extracting language constructs rather than including full file contents. This mode reduces token usage while still providing useful context for AI reasoning.
### Python Language Features
The LSP mode extracts the following Python language constructs:
- **Function signatures** with parameter types and return types
- **Class definitions** with inheritance information
- **Class attributes** including type annotations when available
- **Method signatures** with parameter types and return types
- **Enum definitions** with their literal values
- **Docstrings** (first line only) for functions, classes, and methods
Example Python LSP extraction:
```
class Size(Enum) # Pizza size options
SMALL
MEDIUM
LARGE
class Pizza # Delicious disc of dough
name: str
radius: float
toppings: List[T]
def Pizza.calculate_price(self, tax_rate: float = 0.1) -> float # Calculate price with tax
def Pizza.add_topping(self, topping: T) -> None # Add a topping
def top_level_helper(x: int) -> int # Helper function
```
### Go Language Features
The LSP mode extracts the following Go language constructs:
- **Function signatures** with parameter types and return types
- **Struct definitions** with field names and types
- **Interface definitions**
- **Type definitions** (e.g., type aliases)
- **Receiver methods** with support for pointer receivers and generics
Example Go LSP extraction:
```
type Size int
struct Topping { Name string Price float64 Vegetarian bool }
struct Oven { Temperature int ModelName string }
func (o *Oven) Heat(temperature int) error
func (o *Oven) Bake[T any](p Pizza[T]) (err error)
func (p *Pizza[T]) AddTopping(t T)
func Calculate(radius float64) float64
```
### Diff-aware Processing
The LSP mode is aware of file differences when using the `judge_workplan` tool:
1. It first extracts lightweight signatures for all files
2. Then it identifies which files are included in the diff
3. Those diff-affected files are included in full, rather than just their signatures
4. This provides complete context for changed files while keeping the overall token count low
### Server Dependencies
The server declares its dependencies using the FastMCP dependencies parameter:
```python
mcp = FastMCP(
name="yellhorn-mcp",
dependencies=["google-genai~=1.8.0", "aiohttp~=3.11.14", "pydantic~=2.11.1"],
lifespan=app_lifespan,
)
```
This ensures that when the server is installed in Claude Desktop or used with the MCP CLI, all required dependencies are installed automatically.