Merge feat/16: Create deployment documentation

This commit is contained in:
2026-02-03 16:13:50 -05:00
2 changed files with 945 additions and 254 deletions

712
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,712 @@
# Deployment Guide
This guide covers production deployment of the Gitea HTTP MCP Wrapper in various environments.
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Docker Deployment](#docker-deployment)
3. [Security Best Practices](#security-best-practices)
4. [Monitoring and Health Checks](#monitoring-and-health-checks)
5. [Reverse Proxy Configuration](#reverse-proxy-configuration)
6. [Cloud Deployment](#cloud-deployment)
7. [Kubernetes Deployment](#kubernetes-deployment)
8. [Troubleshooting](#troubleshooting)
## Prerequisites
### Required
- Docker and Docker Compose (for Docker deployment)
- Gitea instance with API access
- Gitea API token with appropriate permissions
- Network connectivity between wrapper and Gitea instance
### Recommended
- HTTPS-capable reverse proxy (Nginx, Caddy, Traefik)
- Secrets management solution (not `.env` files in production)
- Monitoring and logging infrastructure
- Firewall or VPN for network security
## Docker Deployment
### Quick Start
1. **Clone the repository:**
```bash
git clone https://github.com/lmiranda/gitea-mcp-remote.git
cd gitea-mcp-remote
```
2. **Create configuration:**
```bash
cp .env.docker.example .env
nano .env # Edit with your values
```
Required configuration:
```bash
GITEA_URL=https://gitea.example.com
GITEA_TOKEN=your_gitea_api_token
GITEA_OWNER=your_username_or_org
GITEA_REPO=your_default_repo
AUTH_TOKEN=your_bearer_token # Recommended
```
3. **Start the service:**
```bash
docker-compose up -d
```
4. **Verify deployment:**
```bash
curl http://localhost:8000/health
```
### Production Configuration
For production, use a more robust `docker-compose.yml`:
```yaml
version: '3.8'
services:
gitea-mcp-wrapper:
build:
context: .
dockerfile: Dockerfile
image: gitea-mcp-wrapper:latest
container_name: gitea-mcp-wrapper
restart: always
ports:
- "127.0.0.1:8000:8000" # Bind to localhost only
environment:
- GITEA_URL=${GITEA_URL}
- GITEA_TOKEN=${GITEA_TOKEN}
- GITEA_OWNER=${GITEA_OWNER}
- GITEA_REPO=${GITEA_REPO}
- HTTP_HOST=0.0.0.0
- HTTP_PORT=8000
- AUTH_TOKEN=${AUTH_TOKEN}
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
- gitea-mcp-network
networks:
gitea-mcp-network:
driver: bridge
```
### Docker Build Options
**Build the image:**
```bash
docker build -t gitea-mcp-wrapper:latest .
```
**Build with specific Python version:**
```bash
docker build --build-arg PYTHON_VERSION=3.11 -t gitea-mcp-wrapper:latest .
```
**Tag for registry:**
```bash
docker tag gitea-mcp-wrapper:latest registry.example.com/gitea-mcp-wrapper:latest
docker push registry.example.com/gitea-mcp-wrapper:latest
```
## Security Best Practices
### 1. Use Authentication
Always set `AUTH_TOKEN` in production:
```bash
# Generate a secure token
openssl rand -base64 32
# Add to .env
AUTH_TOKEN=<generated_token>
```
### 2. Use HTTPS
Never expose the wrapper directly to the internet without HTTPS. Use a reverse proxy (see below).
### 3. Network Isolation
- Bind to localhost only (`127.0.0.1`) if using a reverse proxy
- Use Docker networks to isolate services
- Consider VPN or private networking for access
### 4. Secrets Management
Don't use `.env` files in production. Use Docker secrets, Kubernetes secrets, or a secrets manager:
**Docker Secrets Example:**
```yaml
services:
gitea-mcp-wrapper:
secrets:
- gitea_token
- auth_token
environment:
- GITEA_TOKEN_FILE=/run/secrets/gitea_token
- AUTH_TOKEN_FILE=/run/secrets/auth_token
secrets:
gitea_token:
external: true
auth_token:
external: true
```
### 5. Regular Updates
- Rotate Gitea API token regularly
- Rotate AUTH_TOKEN regularly
- Keep Docker base image updated
- Update dependencies: `pip install --upgrade -r requirements.txt`
### 6. Minimal Permissions
Grant the Gitea API token only the minimum required permissions:
- Repository read/write
- Issue management
- Label management
- Milestone management
Avoid granting admin or organization-level permissions.
## Monitoring and Health Checks
### Health Check Endpoints
The wrapper provides three health check endpoints:
```bash
GET /health
GET /healthz
GET /ping
```
All return `{"status": "healthy"}` with HTTP 200 when the server is operational.
### Docker Health Checks
Docker automatically monitors the health check and can restart if unhealthy:
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
```
### Monitoring Integration
**Prometheus metrics:** (Not yet implemented, but can be added)
**Log monitoring:**
```bash
# View logs
docker-compose logs -f gitea-mcp-wrapper
# JSON structured logs
docker logs gitea-mcp-wrapper --tail 100
```
**Uptime monitoring:**
Use tools like UptimeRobot, Pingdom, or Datadog to monitor `/health` endpoint.
## Reverse Proxy Configuration
### Nginx
```nginx
server {
listen 443 ssl http2;
server_name mcp.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Pass through Authorization header
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
# WebSocket support (if needed in future)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Health check endpoint (optional, can bypass auth)
location /health {
proxy_pass http://127.0.0.1:8000/health;
access_log off;
}
}
```
### Caddy
```caddyfile
mcp.example.com {
reverse_proxy localhost:8000 {
# Pass through Authorization header
header_up Authorization {>Authorization}
}
# Optional: Rate limiting
rate_limit {
zone mcp_zone
rate 100r/m
}
}
```
### Traefik
```yaml
# docker-compose.yml
services:
gitea-mcp-wrapper:
labels:
- "traefik.enable=true"
- "traefik.http.routers.mcp.rule=Host(`mcp.example.com`)"
- "traefik.http.routers.mcp.entrypoints=websecure"
- "traefik.http.routers.mcp.tls.certresolver=letsencrypt"
- "traefik.http.services.mcp.loadbalancer.server.port=8000"
```
## Cloud Deployment
### AWS EC2
1. **Launch EC2 instance:**
- Amazon Linux 2 or Ubuntu 22.04
- t3.micro or larger
- Security group: Allow port 443 (HTTPS)
2. **Install Docker:**
```bash
sudo yum update -y
sudo yum install -y docker
sudo service docker start
sudo usermod -aG docker ec2-user
```
3. **Deploy wrapper:**
```bash
git clone https://github.com/lmiranda/gitea-mcp-remote.git
cd gitea-mcp-remote
cp .env.docker.example .env
nano .env # Configure
docker-compose up -d
```
4. **Configure Nginx or ALB for HTTPS**
### AWS ECS (Fargate)
1. **Create task definition:**
```json
{
"family": "gitea-mcp-wrapper",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "gitea-mcp-wrapper",
"image": "your-ecr-repo/gitea-mcp-wrapper:latest",
"portMappings": [
{
"containerPort": 8000,
"protocol": "tcp"
}
],
"environment": [
{"name": "GITEA_URL", "value": "https://gitea.example.com"},
{"name": "HTTP_HOST", "value": "0.0.0.0"},
{"name": "HTTP_PORT", "value": "8000"}
],
"secrets": [
{
"name": "GITEA_TOKEN",
"valueFrom": "arn:aws:secretsmanager:region:account:secret:gitea-token"
},
{
"name": "AUTH_TOKEN",
"valueFrom": "arn:aws:secretsmanager:region:account:secret:auth-token"
}
],
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 10
}
}
]
}
```
2. **Create ECS service with ALB**
### Google Cloud Run
1. **Build and push image:**
```bash
gcloud builds submit --tag gcr.io/PROJECT_ID/gitea-mcp-wrapper
```
2. **Deploy:**
```bash
gcloud run deploy gitea-mcp-wrapper \
--image gcr.io/PROJECT_ID/gitea-mcp-wrapper \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars GITEA_URL=https://gitea.example.com \
--set-secrets GITEA_TOKEN=gitea-token:latest,AUTH_TOKEN=auth-token:latest \
--port 8000
```
### Azure Container Instances
```bash
az container create \
--resource-group myResourceGroup \
--name gitea-mcp-wrapper \
--image your-registry/gitea-mcp-wrapper:latest \
--ports 8000 \
--dns-name-label gitea-mcp \
--environment-variables \
GITEA_URL=https://gitea.example.com \
HTTP_HOST=0.0.0.0 \
HTTP_PORT=8000 \
--secure-environment-variables \
GITEA_TOKEN=your_token \
AUTH_TOKEN=your_auth_token
```
## Kubernetes Deployment
### Deployment Manifest
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea-mcp-wrapper
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: gitea-mcp-wrapper
template:
metadata:
labels:
app: gitea-mcp-wrapper
spec:
containers:
- name: gitea-mcp-wrapper
image: your-registry/gitea-mcp-wrapper:latest
ports:
- containerPort: 8000
env:
- name: GITEA_URL
value: "https://gitea.example.com"
- name: HTTP_HOST
value: "0.0.0.0"
- name: HTTP_PORT
value: "8000"
- name: GITEA_TOKEN
valueFrom:
secretKeyRef:
name: gitea-secrets
key: token
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: gitea-secrets
key: auth-token
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
name: gitea-mcp-wrapper
namespace: default
spec:
selector:
app: gitea-mcp-wrapper
ports:
- protocol: TCP
port: 80
targetPort: 8000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-mcp-wrapper
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- mcp.example.com
secretName: mcp-tls
rules:
- host: mcp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea-mcp-wrapper
port:
number: 80
```
### Secrets Management
```bash
# Create secret
kubectl create secret generic gitea-secrets \
--from-literal=token=your_gitea_token \
--from-literal=auth-token=your_auth_token \
--namespace=default
```
## Troubleshooting
### Container Won't Start
```bash
# Check logs
docker-compose logs gitea-mcp-wrapper
# Check container status
docker-compose ps
# Rebuild image
docker-compose build --no-cache
docker-compose up -d
```
### Health Check Failing
```bash
# Test health endpoint directly
docker exec gitea-mcp-wrapper curl http://localhost:8000/health
# Check if server is listening
docker exec gitea-mcp-wrapper netstat -tlnp
```
### Cannot Reach Gitea from Container
```bash
# Test connectivity
docker exec gitea-mcp-wrapper curl -v https://gitea.example.com
# Check DNS resolution
docker exec gitea-mcp-wrapper nslookup gitea.example.com
# For docker-compose, ensure network allows egress
```
### High Memory Usage
```bash
# Check container stats
docker stats gitea-mcp-wrapper
# Adjust resource limits in docker-compose.yml
deploy:
resources:
limits:
memory: 256M
```
### Authentication Failures
```bash
# Verify AUTH_TOKEN is set
docker exec gitea-mcp-wrapper printenv AUTH_TOKEN
# Test with curl
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8000/tools/list
# Check logs for auth failures
docker-compose logs gitea-mcp-wrapper | grep -i auth
```
## Scaling Considerations
### Horizontal Scaling
The wrapper is stateless and can be scaled horizontally:
```yaml
# docker-compose.yml
services:
gitea-mcp-wrapper:
deploy:
replicas: 3
```
Or in Kubernetes:
```bash
kubectl scale deployment gitea-mcp-wrapper --replicas=5
```
### Load Balancing
Use a load balancer to distribute traffic:
- Docker Swarm: Built-in load balancing
- Kubernetes: Service with multiple pods
- Cloud: AWS ALB, GCP Load Balancer, Azure Load Balancer
### Caching
Consider caching responses to reduce Gitea API load:
- Add Redis or Memcached
- Cache tool list responses
- Cache frequently accessed issues/labels
### Rate Limiting
Implement rate limiting at reverse proxy level to prevent API abuse:
**Nginx:**
```nginx
limit_req_zone $binary_remote_addr zone=mcp:10m rate=10r/s;
limit_req zone=mcp burst=20 nodelay;
```
**Caddy:**
```caddyfile
rate_limit {
rate 100r/m
}
```
## Backup and Disaster Recovery
### Configuration Backup
```bash
# Backup .env file
cp .env .env.backup.$(date +%Y%m%d)
# Backup docker-compose.yml
cp docker-compose.yml docker-compose.yml.backup.$(date +%Y%m%d)
```
### Image Backup
```bash
# Save Docker image
docker save gitea-mcp-wrapper:latest | gzip > gitea-mcp-wrapper-backup.tar.gz
# Load Docker image
docker load < gitea-mcp-wrapper-backup.tar.gz
```
### Recovery Plan
1. Restore configuration files
2. Rebuild or load Docker image
3. Start services: `docker-compose up -d`
4. Verify health: `curl http://localhost:8000/health`
5. Test authentication and tool access
## Production Checklist
- [ ] HTTPS configured via reverse proxy
- [ ] `AUTH_TOKEN` set and secure
- [ ] Secrets stored in secrets manager (not `.env`)
- [ ] Health checks configured
- [ ] Monitoring and alerting set up
- [ ] Logs aggregated and retained
- [ ] Firewall rules configured
- [ ] Rate limiting enabled
- [ ] Resource limits set
- [ ] Backup strategy in place
- [ ] Disaster recovery plan documented
- [ ] Security updates scheduled
- [ ] Token rotation process defined
---
**For questions or issues, please open an issue on the [GitHub repository](https://github.com/lmiranda/gitea-mcp-remote/issues).**

487
README.md
View File

@@ -1,32 +1,80 @@
# Gitea MCP Server
# Gitea HTTP MCP Wrapper
A Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with Gitea repositories through its API. This server provides tools for managing issues, labels, and milestones in your Gitea instance.
An HTTP transport wrapper around the official Gitea MCP server that enables AI assistants like Claude Desktop to interact with Gitea repositories via HTTP. This wrapper provides authentication, tool filtering, and HTTP transport while delegating Gitea operations to the official `gitea-mcp-server`.
## Architecture
This is NOT a standalone MCP server. It's an HTTP wrapper that:
1. Wraps the official `gitea-mcp-server` (stdio transport)
2. Provides HTTP transport for Claude Desktop compatibility
3. Adds Bearer token authentication
4. Filters tools for Claude Desktop compatibility
5. Proxies requests between HTTP and stdio transport
```
Claude Desktop (HTTP) → HTTP Wrapper → Gitea MCP Server (stdio) → Gitea API
```
## Features
- **Issue Operations**: List, get, create, and update issues with full support for labels, milestones, and assignees
- **Label Management**: List and create labels with custom colors and descriptions
- **Milestone Management**: List and create milestones with due dates and descriptions
- **Async API**: Built on modern async Python for efficient operations
- **Type Safety**: Full type hints for better IDE support and code quality
- **HTTP Transport**: Exposes MCP server via HTTP for Claude Desktop
- **Authentication**: Optional Bearer token authentication
- **Tool Filtering**: Enable/disable specific tools for compatibility
- **Docker Deployment**: Production-ready containerization
- **Health Checks**: Monitoring endpoints (`/health`, `/healthz`, `/ping`)
- **Async Architecture**: Built on Starlette and uvicorn
## Requirements
- Python >= 3.10
- Official `gitea-mcp-server` package (auto-installed as dependency)
- Gitea instance with API access
- Gitea API token with appropriate permissions
## Quick Start with Docker
The easiest way to deploy is using Docker Compose:
```bash
# 1. Clone the repository
git clone https://github.com/lmiranda/gitea-mcp-remote.git
cd gitea-mcp-remote
# 2. Create .env file from template
cp .env.docker.example .env
# 3. Edit .env with your Gitea credentials
nano .env
# 4. Start the server
docker-compose up -d
# 5. Check health
curl http://localhost:8000/health
```
The server will be available at `http://localhost:8000`.
See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed deployment instructions.
## Installation
### From Source
### Option 1: Docker (Recommended)
See [Quick Start](#quick-start-with-docker) above or [DEPLOYMENT.md](DEPLOYMENT.md).
### Option 2: From Source
```bash
# Clone the repository
git clone https://github.com/lmiranda/gitea-mcp-remote.git
cd gitea-mcp-remote
# Install the package
# Install the wrapper and its dependencies (including gitea-mcp-server)
pip install -e .
# Or use requirements.txt
pip install -r requirements.txt
```
### For Development
@@ -39,32 +87,109 @@ pip install -e ".[dev]"
## Configuration
The server requires two environment variables to connect to your Gitea instance:
The wrapper uses environment variables or a `.env` file for configuration.
- `GITEA_API_URL`: Base URL of your Gitea instance (e.g., `https://gitea.example.com/api/v1`)
- `GITEA_API_TOKEN`: Personal access token for authentication
### Creating a .env File
Create a `.env` file in your project directory:
### Required Configuration
```bash
GITEA_API_URL=https://gitea.example.com/api/v1
GITEA_API_TOKEN=your_gitea_token_here
# Gitea Instance
GITEA_URL=https://gitea.example.com
GITEA_TOKEN=your_gitea_api_token_here
GITEA_OWNER=your_username_or_org
GITEA_REPO=your_repo_name
# HTTP Server
HTTP_HOST=127.0.0.1 # Use 0.0.0.0 in Docker
HTTP_PORT=8000
```
### Optional Configuration
```bash
# Bearer Authentication (optional but recommended)
AUTH_TOKEN=your_secret_bearer_token
# Tool Filtering (optional)
ENABLED_TOOLS=list_issues,create_issue,update_issue # Whitelist mode
# OR
DISABLED_TOOLS=delete_issue,close_milestone # Blacklist mode
```
### Getting a Gitea API Token
1. Log into your Gitea instance
2. Navigate to Settings > Applications
3. Under "Generate New Token", enter a name (e.g., "MCP Server")
3. Under "Generate New Token", enter a name (e.g., "MCP Wrapper")
4. Select appropriate permissions (minimum: read/write for repositories)
5. Click "Generate Token" and copy the token
6. Add the token to your `.env` file
## Usage with Claude Desktop
## Usage
Add this configuration to your Claude Desktop config file:
### Running the Server
#### With Docker
```bash
docker-compose up -d
```
#### From Source
```bash
# Create .env file from template
cp .env.example .env
# Edit .env with your configuration
nano .env
# Run the server
gitea-http-wrapper
```
The server will start on the configured host/port (default: `http://127.0.0.1:8000`).
### HTTP Endpoints
#### Health Check
```bash
GET /health
GET /healthz
GET /ping
Response: {"status": "healthy"}
```
#### List Tools
```bash
POST /tools/list
Response: {
"tools": [
{"name": "list_issues", "description": "...", "inputSchema": {...}},
...
]
}
```
#### Call Tool
```bash
POST /tools/call
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN # If auth enabled
{
"name": "list_issues",
"arguments": {
"owner": "myorg",
"repo": "myrepo",
"state": "open"
}
}
```
### With Claude Desktop
Configure Claude Desktop to use the HTTP wrapper:
**Location:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
@@ -77,48 +202,9 @@ Add this configuration to your Claude Desktop config file:
{
"mcpServers": {
"gitea": {
"command": "python",
"args": ["-m", "gitea_mcp.server"],
"env": {
"GITEA_API_URL": "https://gitea.example.com/api/v1",
"GITEA_API_TOKEN": "your_gitea_token_here"
}
}
}
}
```
Or, if you prefer using a .env file:
```json
{
"mcpServers": {
"gitea": {
"command": "python",
"args": ["-m", "gitea_mcp.server"],
"cwd": "/path/to/gitea-mcp-remote"
}
}
}
```
## Usage with Claude Code
Add to your MCP settings file:
**Location:** `~/.config/claude-code/mcp.json` (or your configured MCP settings path)
**Configuration:**
```json
{
"mcpServers": {
"gitea": {
"command": "python",
"args": ["-m", "gitea_mcp.server"],
"env": {
"GITEA_API_URL": "https://gitea.example.com/api/v1",
"GITEA_API_TOKEN": "your_gitea_token_here"
"url": "http://localhost:8000",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
@@ -127,170 +213,13 @@ Add to your MCP settings file:
## Available Tools
### Issue Tools
The wrapper exposes all tools from the official `gitea-mcp-server`. See the [official Gitea MCP documentation](https://github.com/modelcontextprotocol/servers/tree/main/src/gitea) for the complete list of available tools:
#### gitea_list_issues
- **Issues**: List, get, create, update issues
- **Labels**: List, create labels
- **Milestones**: List, create milestones
List issues in a repository with optional filters.
**Parameters:**
- `owner` (required): Repository owner (username or organization)
- `repo` (required): Repository name
- `state` (optional): Filter by state - `open`, `closed`, or `all` (default: `open`)
- `labels` (optional): Comma-separated list of label names to filter by
- `milestone` (optional): Milestone name to filter by
- `page` (optional): Page number for pagination (default: 1)
- `limit` (optional): Number of issues per page (default: 30)
**Example:**
```
List all open issues in myorg/myrepo
```
#### gitea_get_issue
Get details of a specific issue by number.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
- `index` (required): Issue number
**Example:**
```
Get details of issue #42 in myorg/myrepo
```
#### gitea_create_issue
Create a new issue in a repository.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
- `title` (required): Issue title
- `body` (optional): Issue description/body
- `labels` (optional): Array of label IDs to assign
- `milestone` (optional): Milestone ID to assign
- `assignees` (optional): Array of usernames to assign
**Example:**
```
Create an issue in myorg/myrepo with title "Bug: Login fails" and body "Users cannot log in with special characters in password"
```
#### gitea_update_issue
Update an existing issue.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
- `index` (required): Issue number
- `title` (optional): New issue title
- `body` (optional): New issue body
- `state` (optional): Issue state - `open` or `closed`
- `labels` (optional): Array of label IDs (replaces existing)
- `milestone` (optional): Milestone ID to assign
- `assignees` (optional): Array of usernames (replaces existing)
**Example:**
```
Close issue #42 in myorg/myrepo
```
### Label Tools
#### gitea_list_labels
List all labels in a repository.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
**Example:**
```
List all labels in myorg/myrepo
```
#### gitea_create_label
Create a new label in a repository.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
- `name` (required): Label name
- `color` (required): Label color (hex without #, e.g., `ff0000` for red)
- `description` (optional): Label description
**Example:**
```
Create a label "bug" with red color (ff0000) in myorg/myrepo
```
### Milestone Tools
#### gitea_list_milestones
List milestones in a repository.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
- `state` (optional): Filter by state - `open`, `closed`, or `all` (default: `open`)
**Example:**
```
List all milestones in myorg/myrepo
```
#### gitea_create_milestone
Create a new milestone in a repository.
**Parameters:**
- `owner` (required): Repository owner
- `repo` (required): Repository name
- `title` (required): Milestone title
- `description` (optional): Milestone description
- `due_on` (optional): Due date in ISO 8601 format (e.g., `2024-12-31T23:59:59Z`)
**Example:**
```
Create a milestone "v1.0 Release" with due date 2024-12-31 in myorg/myrepo
```
## API Reference
### Core Components
#### GiteaClient
HTTP client for Gitea API interactions.
**Methods:**
- `get(endpoint, params)`: GET request
- `post(endpoint, json)`: POST request
- `patch(endpoint, json)`: PATCH request
#### AuthConfig
Configuration manager for API authentication.
**Environment Variables:**
- `GITEA_API_URL`: Gitea API base URL
- `GITEA_API_TOKEN`: Authentication token
**Methods:**
- `get_auth_headers()`: Returns authentication headers
### Tool Modules
- `gitea_mcp.tools.issues`: Issue operation tools and handlers
- `gitea_mcp.tools.labels`: Label operation tools and handlers
- `gitea_mcp.tools.milestones`: Milestone operation tools and handlers
Tool availability can be controlled via the `ENABLED_TOOLS` or `DISABLED_TOOLS` configuration.
## Development
@@ -304,7 +233,14 @@ pip install -e ".[dev]"
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=gitea_http_wrapper
# Run specific test file
pytest src/gitea_http_wrapper/tests/test_config.py
```
### Project Structure
@@ -312,28 +248,44 @@ pytest
```
gitea-mcp-remote/
├── src/
│ └── gitea_mcp/
│ └── gitea_http_wrapper/
│ ├── __init__.py
│ ├── server.py # MCP server implementation
│ ├── auth.py # Authentication config
├── client.py # Gitea API client
└── tools/ # Tool implementations
├── __init__.py
├── issues.py # Issue tools
── labels.py # Label tools
── milestones.py # Milestone tools
├── tests/ # Test suite
├── pyproject.toml # Project configuration
└── README.md # This file
│ ├── server.py # Main HTTP server
│ ├── config/
│ ├── __init__.py
│ └── settings.py # Configuration loader
├── middleware/
├── __init__.py
── auth.py # HTTP authentication
── filtering/
├── __init__.py
│ │ └── filter.py # Tool filtering
│ └── tests/ # Test suite
│ ├── conftest.py
│ ├── test_config.py
│ ├── test_filtering.py
│ └── test_middleware.py
├── Dockerfile # Docker image
├── docker-compose.yml # Docker orchestration
├── pyproject.toml # Project config
├── requirements.txt # Dependencies
├── .env.example # Config template
├── .env.docker.example # Docker config template
├── README.md # This file
└── DEPLOYMENT.md # Deployment guide
```
### Code Quality
## Deployment
This project uses:
- Type hints throughout the codebase
- Async/await for all I/O operations
- Comprehensive error handling
- Structured logging
For production deployment instructions, see [DEPLOYMENT.md](DEPLOYMENT.md), which covers:
- Docker deployment
- Docker Compose orchestration
- Security best practices
- Monitoring and health checks
- Scaling considerations
- Cloud deployment (AWS, GCP, Azure)
- Kubernetes deployment
## Troubleshooting
@@ -341,27 +293,53 @@ This project uses:
If you receive authentication errors:
1. Verify your `GITEA_API_TOKEN` is correct
1. Verify your `GITEA_TOKEN` is correct
2. Check that the token has appropriate permissions
3. Ensure your `GITEA_API_URL` includes `/api/v1` at the end
4. Verify the Gitea instance is accessible from your network
3. Ensure your `GITEA_URL` does NOT include `/api/v1` (wrapper adds it)
4. Verify the Gitea instance is accessible from the wrapper's network
### HTTP 401/403 Errors
If Claude Desktop receives 401 or 403 errors:
1. Check that `AUTH_TOKEN` is configured (if authentication is enabled)
2. Verify Claude Desktop config includes the correct `Authorization` header
3. Check server logs for authentication failures
### Connection Errors
If you cannot connect to Gitea:
If the wrapper cannot connect to Gitea:
1. Check that `GITEA_API_URL` is correct and accessible
1. Check that `GITEA_URL` is correct and accessible
2. Verify network connectivity to the Gitea instance
3. Check for firewalls or proxies blocking the connection
4. In Docker: Ensure the container can reach the Gitea host
### Tool Not Found
### gitea-mcp-server Not Found
If Claude cannot find the tools:
If the wrapper fails to start with "gitea-mcp-server not found":
1. Restart Claude Desktop/Code after updating the configuration
2. Verify the configuration file syntax is valid JSON
3. Check that Python is in your PATH
4. Ensure the package is properly installed (`pip list | grep gitea-mcp`)
1. Verify `gitea-mcp-server` is installed: `pip list | grep gitea-mcp`
2. Install it manually: `pip install gitea-mcp-server`
3. In Docker: Rebuild the image
### Tool Filtering Not Working
If tool filtering is not applied:
1. Check `.env` file syntax (no spaces around `=`)
2. Verify comma-separated list format
3. Check server logs for filter configuration
4. Query `POST /tools/list` to see filtered tools
## Security Considerations
- **Always use HTTPS** in production (configure reverse proxy)
- **Set AUTH_TOKEN** to secure the HTTP endpoint
- **Rotate tokens regularly** (both Gitea token and auth token)
- **Use secrets management** (not .env files) in production
- **Limit network exposure** (firewall, VPN, or private network)
- **Monitor access logs** for suspicious activity
## Contributing
@@ -383,4 +361,5 @@ Leo Miranda
- Repository: https://github.com/lmiranda/gitea-mcp-remote
- Issues: https://github.com/lmiranda/gitea-mcp-remote/issues
- Official Gitea MCP Server: https://github.com/modelcontextprotocol/servers/tree/main/src/gitea
- MCP Documentation: https://modelcontextprotocol.io