Files
lmiranda 9044fe28ec fix(gitea): fix 15 failing tests and update documentation
Test Fixes:
- Fix mock_config fixture to use 'owner/repo' format (was separate fields)
- Update test_client_initialization to match current client API
- Add required 'org' argument to get_org_labels, list_repos, aggregate_issues tests
- Update error message assertion in test_no_repo_specified_error
- Fix test_create_issue to mock is_org_repo and label resolution
- Update aggregate_issues tests in test_issues.py with org argument

Documentation Updates:
- Expand tools table from 8 to 36 tools (organized by category)
- Update directory structure to show all 6 tool files
- Remove unused GITEA_OWNER from configuration docs
- Add automatic repository detection documentation
- Add project directory detection strategies
- Update test count from 42 to 64
- Create CHANGELOG.md with full version history

All 64 tests now pass. No production code changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:22:02 -05:00

491 lines
14 KiB
Markdown

# Gitea MCP Server
Model Context Protocol (MCP) server for Gitea integration with Claude Code.
## Overview
The Gitea MCP Server provides Claude Code with direct access to Gitea for issue management, label operations, and repository tracking. It supports both single-repository (project mode) and multi-repository (company/PMO mode) operations.
**Status**: ✅ Phase 1 Complete - Fully functional and tested
## Features
### Core Functionality
- **Issue Management**: CRUD operations for Gitea issues
- **Label Taxonomy**: Dynamic 44-label system with intelligent suggestions
- **Mode Detection**: Automatic project vs company-wide mode detection
- **Branch-Aware Security**: Prevents accidental changes on production branches
- **Hybrid Configuration**: System-level credentials + project-level paths
- **PMO Support**: Multi-repository aggregation for organization-wide views
### Tools Provided (36 total)
#### Issue Management (6 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `list_issues` | List issues from repository | Both |
| `get_issue` | Get specific issue details | Both |
| `create_issue` | Create new issue with labels | Both |
| `update_issue` | Update existing issue | Both |
| `add_comment` | Add comment to issue | Both |
| `aggregate_issues` | Cross-repository issue aggregation | PMO Only |
#### Label Management (5 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `get_labels` | Get all labels (org + repo) | Both |
| `suggest_labels` | Intelligent label suggestion | Both |
| `create_label` | Create repo-level label | Both |
| `create_org_label` | Create organization-level label | Both |
| `create_label_smart` | Auto-detect org vs repo for label creation | Both |
#### Wiki & Lessons Learned (7 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `list_wiki_pages` | List all wiki pages | Both |
| `get_wiki_page` | Get specific wiki page content | Both |
| `create_wiki_page` | Create new wiki page | Both |
| `update_wiki_page` | Update existing wiki page | Both |
| `create_lesson` | Create lessons learned entry | Both |
| `search_lessons` | Search lessons by query/tags | Both |
| `allocate_rfc_number` | Get next available RFC number | Both |
#### Milestone Management (5 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `list_milestones` | List all milestones | Both |
| `get_milestone` | Get specific milestone | Both |
| `create_milestone` | Create new milestone | Both |
| `update_milestone` | Update existing milestone | Both |
| `delete_milestone` | Delete a milestone | Both |
#### Issue Dependencies (4 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `list_issue_dependencies` | List blocking issues | Both |
| `create_issue_dependency` | Create dependency between issues | Both |
| `remove_issue_dependency` | Remove dependency | Both |
| `get_execution_order` | Calculate parallelizable execution order | Both |
#### Pull Request Tools (7 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `list_pull_requests` | List PRs from repository | Both |
| `get_pull_request` | Get specific PR details | Both |
| `get_pr_diff` | Get PR diff content | Both |
| `get_pr_comments` | Get comments on a PR | Both |
| `create_pr_review` | Create PR review (approve/request changes) | Both |
| `add_pr_comment` | Add comment to PR | Both |
| `create_pull_request` | Create new pull request | Both |
#### Validation Tools (2 tools)
| Tool | Description | Mode |
|------|-------------|------|
| `validate_repo_org` | Check if repo belongs to organization | Both |
| `get_branch_protection` | Get branch protection rules | Both |
## Architecture
### Directory Structure
```
mcp-servers/gitea/
├── .venv/ # Python virtual environment
├── requirements.txt # Python dependencies
├── run.sh # Entry point script
├── mcp_server/
│ ├── __init__.py
│ ├── server.py # MCP server entry point (36 tools)
│ ├── config.py # Configuration loader with auto-detection
│ ├── gitea_client.py # Gitea API client
│ └── tools/
│ ├── __init__.py
│ ├── issues.py # Issue management tools
│ ├── labels.py # Label management tools
│ ├── wiki.py # Wiki & lessons learned tools
│ ├── milestones.py # Milestone management tools
│ ├── dependencies.py # Issue dependency tools
│ └── pull_requests.py # Pull request tools
├── tests/
│ ├── __init__.py
│ ├── test_config.py
│ ├── test_gitea_client.py
│ ├── test_issues.py
│ └── test_labels.py
├── README.md # This file
├── TESTING.md # Testing instructions
└── CHANGELOG.md # Version history
```
### Mode Detection
The server operates in two modes based on environment variables:
**Project Mode** (Single Repository):
- When `GITEA_REPO` is set
- Operates on single repository
- Used by `projman` plugin
**Company Mode** (Multi-Repository / PMO):
- When `GITEA_REPO` is NOT set
- Operates on all repositories in organization
- Used by `projman-pmo` plugin
### Branch-Aware Security
Operations are restricted based on the current Git branch:
| Branch | Read | Create Issue | Update/Comment |
|--------|------|--------------|----------------|
| `main`, `master`, `prod/*` | ✅ | ❌ | ❌ |
| `staging`, `stage/*` | ✅ | ✅ | ❌ |
| `development`, `develop`, `feat/*`, `dev/*` | ✅ | ✅ | ✅ |
## Installation
### Prerequisites
- Python 3.10 or higher
- Git repository (for branch detection)
- Access to Gitea instance with API token
### Step 1: Install Dependencies
```bash
cd mcp-servers/gitea
python3 -m venv .venv
source .venv/bin/activate # Linux/Mac
# or .venv\Scripts\activate # Windows
pip install -r requirements.txt
```
### Step 2: Configure System-Level Settings
Create `~/.config/claude/gitea.env`:
```bash
mkdir -p ~/.config/claude
cat > ~/.config/claude/gitea.env << EOF
GITEA_API_URL=https://gitea.example.com/api/v1
GITEA_API_TOKEN=your_gitea_token_here
EOF
chmod 600 ~/.config/claude/gitea.env
```
### Step 3: Configure Project-Level Settings (Optional)
For project mode, create `.env` in your project root:
```bash
echo "GITEA_REPO=your-repo-name" > .env
echo ".env" >> .gitignore
```
For company/PMO mode, omit the `.env` file or don't set `GITEA_REPO`.
## Configuration
### System-Level Configuration
**File**: `~/.config/claude/gitea.env`
**Required Variables**:
- `GITEA_API_URL` - Gitea API endpoint (e.g., `https://gitea.example.com/api/v1`)
- `GITEA_API_TOKEN` - Personal access token with repo permissions
### Project-Level Configuration
**File**: `<project-root>/.env`
**Optional Variables**:
- `GITEA_REPO` - Repository in `owner/repo` format (enables project mode)
### Automatic Repository Detection
If `GITEA_REPO` is not set, the server auto-detects the repository from your git remote:
**Supported URL Formats**:
- SSH: `ssh://git@gitea.example.com:22/owner/repo.git`
- SSH short: `git@gitea.example.com:owner/repo.git`
- HTTPS: `https://gitea.example.com/owner/repo.git`
- HTTP: `http://gitea.example.com/owner/repo.git`
The repository is extracted as `owner/repo` format automatically.
### Project Directory Detection
The server finds your project directory using these strategies (in order):
1. `CLAUDE_PROJECT_DIR` environment variable (highest priority)
2. `PWD` environment variable (if `.git` or `.env` present)
3. Current working directory (if `.git` or `.env` present)
4. Falls back to company/PMO mode if no project found
### Generating Gitea API Token
1. Log into Gitea: https://gitea.example.com
2. Navigate to: **Settings****Applications****Manage Access Tokens**
3. Click **Generate New Token**
4. Configure token:
- **Token Name**: `claude-code-mcp`
- **Permissions**:
-`repo` (all) - Read/write repositories, issues, labels
-`read:org` - Read organization information and labels
-`read:user` - Read user information
5. Click **Generate Token**
6. Copy token immediately (shown only once)
7. Add to `~/.config/claude/gitea.env`
## Usage
### Running the MCP Server
```bash
cd mcp-servers/gitea
source .venv/bin/activate
python -m mcp_server.server
```
The server communicates via JSON-RPC 2.0 over stdio.
### Integration with Claude Code Plugins
The MCP server is designed to be used by Claude Code plugins via `.mcp.json` configuration:
```json
{
"mcpServers": {
"gitea": {
"command": "python",
"args": ["-m", "mcp_server.server"],
"cwd": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea",
"env": {
"PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea"
}
}
}
}
```
### Example Tool Calls
**List Issues**:
```python
from mcp_server.tools.issues import IssueTools
from mcp_server.gitea_client import GiteaClient
client = GiteaClient()
issue_tools = IssueTools(client)
issues = await issue_tools.list_issues(state='open', labels=['Type/Bug'])
```
**Suggest Labels**:
```python
from mcp_server.tools.labels import LabelTools
label_tools = LabelTools(client)
context = "Fix critical authentication bug in production API"
suggestions = await label_tools.suggest_labels(context)
# Returns: ['Type/Bug', 'Priority/Critical', 'Component/Auth', 'Component/API', ...]
```
## Testing
### Unit Tests
Run all 64 unit tests with mocks:
```bash
pytest tests/ -v
```
Expected: `64 passed`
### Integration Tests
Test with real Gitea instance:
```bash
python -c "
from mcp_server.gitea_client import GiteaClient
client = GiteaClient()
issues = client.list_issues(state='open')
print(f'Found {len(issues)} open issues')
"
```
### Full Testing Guide
See [TESTING.md](./TESTING.md) for comprehensive testing instructions.
## Label Taxonomy System
The system supports a dynamic 44-label taxonomy (28 org + 16 repo):
**Organization Labels (28)**:
- `Agent/*` (2) - Agent/Human, Agent/Claude
- `Complexity/*` (3) - Simple, Medium, Complex
- `Efforts/*` (5) - XS, S, M, L, XL
- `Priority/*` (4) - Low, Medium, High, Critical
- `Risk/*` (3) - Low, Medium, High
- `Source/*` (4) - Development, Staging, Production, Customer
- `Type/*` (6) - Bug, Feature, Refactor, Documentation, Test, Chore
**Repository Labels (16)**:
- `Component/*` (9) - Backend, Frontend, API, Database, Auth, Deploy, Testing, Docs, Infra
- `Tech/*` (7) - Python, JavaScript, Docker, PostgreSQL, Redis, Vue, FastAPI
Labels are fetched dynamically from Gitea and suggestions adapt to the current taxonomy.
## Security
### Token Storage
- Store tokens in `~/.config/claude/gitea.env`
- Set file permissions to `600` (read/write owner only)
- Never commit tokens to Git
- Use separate tokens for development and production
### Branch Detection
The MCP server implements defense-in-depth branch detection:
1. **MCP Tools**: Check branch before operations
2. **Agent Prompts**: Warn users about branch restrictions
3. **CLAUDE.md**: Provides additional context
### Input Validation
- All user input is validated before API calls
- Issue titles and descriptions are sanitized
- Label names are checked against taxonomy
- Repository names are validated
## Troubleshooting
### Common Issues
**Module not found**:
```bash
cd mcp-servers/gitea
source .venv/bin/activate
```
**Configuration not found**:
```bash
ls -la ~/.config/claude/gitea.env
# If missing, create it following installation steps
```
**Authentication failed**:
```bash
# Test token manually
curl -H "Authorization: token YOUR_TOKEN" \
https://gitea.example.com/api/v1/user
```
**Permission denied on branch**:
```bash
# Check current branch
git branch --show-current
# Switch to development branch
git checkout development
```
See [TESTING.md](./TESTING.md#troubleshooting) for more details.
## Development
### Project Structure
- `config.py` - Hybrid configuration loader with auto-detection
- `gitea_client.py` - Synchronous Gitea API client using requests
- `tools/issues.py` - Issue management with branch detection
- `tools/labels.py` - Label management and intelligent suggestions
- `tools/wiki.py` - Wiki pages and lessons learned
- `tools/milestones.py` - Milestone CRUD operations
- `tools/dependencies.py` - Issue dependency tracking
- `tools/pull_requests.py` - PR review and management
- `server.py` - MCP server with 36 tools over JSON-RPC 2.0 stdio
### Adding New Tools
1. Add method to `GiteaClient` (sync)
2. Add async wrapper to appropriate tool class
3. Register tool in `server.py` `setup_tools()`
4. Add unit tests
5. Update documentation
### Testing Philosophy
- **Unit tests**: Use mocks for fast feedback
- **Integration tests**: Use real Gitea API for validation
- **Branch detection**: Test all branch types
- **Mode detection**: Test both project and company modes
## Performance
### Caching
Labels are cached to reduce API calls:
```python
from functools import lru_cache
@lru_cache(maxsize=128)
def get_labels_cached(self, repo: str):
return self.get_labels(repo)
```
### Retry Logic
API calls include automatic retry with exponential backoff:
```python
@retry_on_failure(max_retries=3, delay=1)
def list_issues(self, state='open', labels=None, repo=None):
# Implementation
```
## Changelog
See [CHANGELOG.md](./CHANGELOG.md) for full version history.
### Recent Updates
- **v1.3.0** - Pull request tools (7 tools), label creation tools (3)
- **v1.2.0** - Milestone management (5 tools), issue dependencies (4 tools)
- **v1.1.0** - Wiki & lessons learned system (7 tools)
- **v1.0.0** - Initial release with core issue/label tools (8 tools)
## License
MIT License - Part of the Leo Claude Marketplace project.
## Related Documentation
- **Projman Documentation**: `plugins/projman/README.md`
- **Configuration Guide**: `plugins/projman/CONFIGURATION.md`
- **Testing Guide**: `TESTING.md`
## Support
For issues or questions:
1. Check [TESTING.md](./TESTING.md) troubleshooting section
2. Review [plugins/projman/README.md](../../README.md) for plugin documentation
3. Create an issue in the project repository
---
**Built for**: Leo Claude Marketplace - Project Management Plugins
**Tools**: 36
**Status**: ✅ Production Ready
**Last Updated**: 2026-02-03