Files
gitea-mcp-remote/CLAUDE.md
lmiranda 2dbb66deae docs: Create CLAUDE.md and update deployment documentation (#27)
- Create CLAUDE.md with comprehensive project guidance for Claude Code
- Update README.md with correct architecture (direct import, not subprocess)
- Update project structure to reflect tests/ at repo root and docker/ directory
- Update default port from 8000 to 8080
- Update repository links to Gitea
- Update DEPLOYMENT.md with two-service Docker architecture (app + Caddy)
- Fix Claude Desktop config example to use /mcp endpoint

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

7.1 KiB

CLAUDE.md - Gitea MCP Remote

This file provides guidance to Claude Code when working with this repository.

Project Overview

Name: gitea-mcp-remote Type: HTTP transport server for MCP (Model Context Protocol) Purpose: Expose Gitea operations via MCP Streamable HTTP protocol for AI assistants

This is NOT a standalone MCP server. It imports tools from the gitea-mcp-server marketplace package and serves them over HTTP with authentication and tool filtering.

Architecture

Client (Claude Desktop) ──HTTP──▶ gitea-mcp-remote ──imports──▶ gitea-mcp-server ──API──▶ Gitea
                                       │
                                       ├── Authentication (Bearer token)
                                       ├── Tool Filtering (enable/disable)
                                       └── MCP Streamable HTTP protocol

Key Design Decision: This server uses direct imports from the marketplace gitea-mcp-server package, NOT subprocess spawning. Tool definitions and dispatchers are imported and used directly.

Project Structure

gitea-mcp-remote/
├── src/gitea_mcp_remote/          # Main package
│   ├── __init__.py
│   ├── server_http.py             # MCP HTTP server (main module)
│   ├── config/                    # Configuration module
│   │   ├── __init__.py
│   │   └── settings.py            # Pydantic settings loader
│   ├── middleware/                # HTTP middleware
│   │   ├── __init__.py
│   │   └── auth.py                # Bearer auth + health check bypass
│   └── filtering/                 # Tool filtering
│       ├── __init__.py
│       └── filter.py              # Whitelist/blacklist filtering
├── tests/                         # Test suite (at repo root)
│   ├── conftest.py
│   ├── test_config.py
│   ├── test_middleware.py
│   ├── test_filtering.py
│   └── test_mcp_endpoints.py
├── docker/                        # Docker infrastructure
│   ├── Dockerfile                 # Multi-stage build
│   ├── docker-compose.yml         # App + Caddy services
│   ├── Caddyfile                  # Reverse proxy config
│   └── .env.example               # Environment template
├── scripts/                       # Utility scripts
│   ├── start.sh                   # Production startup
│   └── healthcheck.sh             # Docker health check
├── docs/                          # Documentation
│   └── sprint-proposals/          # Sprint planning docs
├── pyproject.toml                 # Project configuration
├── requirements.txt               # Dependencies
├── README.md                      # User documentation
├── DEPLOYMENT.md                  # Deployment guide
└── CLAUDE.md                      # This file

Development Workflows

Setup Development Environment

# Create virtual environment
python -m venv .venv
source .venv/bin/activate

# Install with development dependencies
pip install -e ".[dev]"

Running Tests

# All tests
pytest tests/ -v

# With coverage
pytest tests/ --cov=gitea_mcp_remote

# Specific test file
pytest tests/test_mcp_endpoints.py -v

Running the Server Locally

# Set required environment variables
export GITEA_URL=https://gitea.example.com
export GITEA_TOKEN=your_token
export GITEA_OWNER=your_org

# Run server
gitea-mcp-remote

Docker Development

# Build and run
docker-compose -f docker/docker-compose.yml up --build

# Validate configuration
docker-compose -f docker/docker-compose.yml config

# Check logs
docker-compose -f docker/docker-compose.yml logs -f

Key Files

server_http.py

The main MCP server implementation:

  • Imports tools from mcp_server (marketplace package)
  • Creates Server instance with tool handlers
  • Uses StreamableHTTPServerTransport for MCP protocol
  • Health endpoint at /health (bypasses auth)
  • MCP endpoint at /mcp (POST for requests, HEAD for protocol version)

config/settings.py

Pydantic settings with:

  • gitea_url, gitea_token, gitea_owner (required)
  • gitea_repo (optional)
  • http_host (default: 0.0.0.0), http_port (default: 8080)
  • auth_token (optional Bearer token)
  • mcp_auth_mode (optional/required/none)
  • enabled_tools, disabled_tools (comma-separated)

middleware/auth.py

Two middleware classes:

  • BearerAuthMiddleware: Validates Authorization header
  • HealthCheckBypassMiddleware: Sets skip_auth flag for health endpoints

Important: Middleware order matters. HealthCheckBypass must wrap BearerAuth (outermost) so it runs first.

MCP Protocol Notes

This server implements the MCP Streamable HTTP protocol:

  1. HEAD /mcp - Returns protocol version header (x-mcp-protocol-version: 2024-11-05)
  2. POST /mcp - Accepts JSON-RPC 2.0 requests, returns SSE responses

Supported methods:

  • initialize - Protocol handshake
  • tools/list - List available tools
  • tools/call - Execute a tool

Request Format

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_issues",
    "arguments": {"owner": "org", "repo": "repo", "state": "open"}
  }
}

Response Format (SSE)

event: message
data: {"jsonrpc":"2.0","id":1,"result":[...]}

Configuration Reference

Variable Required Default Description
GITEA_URL Yes - Gitea instance URL
GITEA_TOKEN Yes - Gitea API token
GITEA_OWNER Yes - Default owner/org
GITEA_REPO No None Default repository
HTTP_HOST No 0.0.0.0 Server bind address
HTTP_PORT No 8080 Server port
AUTH_TOKEN No None Bearer token for auth
MCP_AUTH_MODE No optional Auth mode
ENABLED_TOOLS No None Whitelist (comma-sep)
DISABLED_TOOLS No None Blacklist (comma-sep)

Troubleshooting

Import Errors from mcp_server

If from mcp_server import ... fails:

  1. Verify gitea-mcp-server is installed: pip list | grep gitea
  2. The package is installed from Git via pyproject.toml dependency
  3. Reinstall: pip install -e .

Health Endpoint Returns 401

Middleware order is wrong. HealthCheckBypassMiddleware must be outermost:

if settings.auth_token:
    app = BearerAuthMiddleware(app, auth_token=settings.auth_token)
app = HealthCheckBypassMiddleware(app)  # Must be last (outermost)

Tests Not Found

Ensure pyproject.toml has correct testpaths:

[tool.pytest.ini_options]
testpaths = ["tests"]

MCP Requests Fail with 406

Missing Accept header. Requests must include:

Accept: application/json, text/event-stream

Dependencies

Runtime:

  • gitea-mcp-server - Marketplace package (Git dependency)
  • mcp - MCP SDK
  • uvicorn - ASGI server
  • starlette - Web framework
  • pydantic-settings - Configuration

Development:

  • pytest - Testing
  • pytest-asyncio - Async test support
  • pytest-cov - Coverage
  • httpx - HTTP client for tests