Files
gitea-mcp-remote/docs/sprint-proposals/sprint-01-core-architecture-correction.md
lmiranda 16436c847a docs: Add Sprint 01 planning documentation
Create comprehensive sprint planning documentation for Core Architecture
Correction sprint. This addresses three fatal architectural problems from
v1.0.0 release.

Sprint documents include:
- Executive proposal with architecture analysis
- Detailed implementation guide with code snippets
- Issue breakdown with dependencies
- Sprint summary with approval checklist

Sprint creates 10 issues in Gitea milestone 29:
- Issues #19-28 covering package rename, MCP protocol implementation,
  Docker infrastructure, testing, and documentation
- Total estimated effort: 19-28 hours (1 week sprint)
- All issues properly sized (S/M), labeled, and dependency-tracked

This is attempt #3 - all details from architectural correction prompt
have been captured.

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

14 KiB

Sprint 01: Core Architecture Correction

Status: Planning Sprint Duration: 1 week (estimated 20-24 hours of work) Priority: CRITICAL - Architectural Foundation Attempt: #3 (Pay close attention to details)

Executive Summary

This sprint addresses three fatal architectural problems introduced in the v1.0.0 release that prevent the HTTP wrapper from functioning correctly with the MCP protocol. This is surgical correction work, not a rewrite. Supporting modules (config, middleware, filtering, tests) are solid and only need import path updates.

The Three Fatal Problems

1. Subprocess Architecture → Direct Python Import

Current (Wrong): server.py spawns gitea-mcp-server as a subprocess Required (Correct): Direct Python import from marketplace package

# WRONG (current)
self.process = await asyncio.create_subprocess_exec("gitea-mcp-server", ...)

# CORRECT (target)
from mcp_server import get_tool_definitions, create_tool_dispatcher, GiteaClient, GiteaConfig

Why this is fatal: Cannot access marketplace code as subprocess, breaks MCP protocol contract.

2. Custom REST API → MCP Streamable HTTP Protocol

Current (Wrong): Custom endpoints /tools/list and /tools/call Required (Correct): MCP Streamable HTTP protocol

# WRONG (current)
POST /tools/list
POST /tools/call

# CORRECT (target)
POST /mcp          # JSON-RPC 2.0 messages
HEAD /mcp          # Protocol version header

Why this is fatal: Not compatible with Claude Desktop's MCP client implementation.

3. Missing Marketplace Dependency

Current (Wrong): Comment in pyproject.toml about installing separately Required (Correct): Actual pip dependency from marketplace Git repository

# WRONG (current)
# gitea-mcp-server - installed separately (not on PyPI yet)

# CORRECT (target)
dependencies = [
    "gitea-mcp-server @ git+https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace.git#subdirectory=mcp-servers/gitea",
    ...
]

Why this is fatal: Dependency not installable, breaks Docker builds and deployment.

What to KEEP (Rename Imports Only)

These modules are solid and well-tested. Only update import paths from gitea_http_wrapper to gitea_mcp_remote:

config/settings.py

  • Keep: Overall structure, Pydantic settings, validation logic
  • Minor changes:
    • Make gitea_repo optional (allow None)
    • Add mcp_auth_mode: str = "optional" field
    • Change HTTP defaults: http_host="0.0.0.0", http_port=8080
    • Remove get_gitea_mcp_env() method (no longer needed for subprocess)

middleware/auth.py

  • Keep: Entire file logic unchanged
  • Change: Import paths only (gitea_http_wrappergitea_mcp_remote)

filtering/filter.py

  • Keep: Entire filtering logic
  • Changes:
    • Line 30: Change raise ValueError(...) to logger.warning(...) (non-fatal)
    • Import paths: gitea_http_wrappergitea_mcp_remote

Tests (all files)

  • Keep: All test logic and fixtures
  • Move: src/gitea_http_wrapper/tests/tests/ (top-level)
  • Change: Import paths to reflect new structure

DEPLOYMENT.md

  • Keep: Overall deployment guide structure
  • Update: References to new MCP endpoints, Docker structure, marketplace dependency

What to REPLACE

server.py → server_http.py

Complete replacement with:

  • Direct Python imports from marketplace mcp_server
  • MCP Streamable HTTP transport (POST /mcp, HEAD /mcp)
  • JSON-RPC 2.0 message handling
  • GiteaClient instantiation with GiteaConfig
  • Tool dispatcher integration
  • Keep health endpoints: /health, /healthz, /ping

pyproject.toml

Full replacement with:

  • Marketplace Git dependency
  • Updated package name: gitea-mcp-remote
  • New entry point: gitea-mcp-remote = "gitea_mcp_remote.server_http:main"
  • Updated test paths: testpaths = ["tests"]

docker-compose.yml → docker/docker-compose.yml

Move and restructure with:

  • Two services: app (Python server) and caddy (reverse proxy)
  • App listens on port 8080 (internal)
  • Caddy exposes port 443 (external HTTPS)
  • Volume for Caddy certs persistence

Dockerfile → docker/Dockerfile

Replace with:

  • Install git package (for Git dependency install)
  • Expose port 8080 (not 8000)
  • Use curl for healthcheck (not wget)
  • Install from requirements.txt first, then marketplace dependency

New Files to CREATE

docker/Caddyfile

Reverse proxy configuration:

  • HTTPS termination
  • Proxy to app:8080
  • MCP endpoint routing

CLAUDE.md

Project guidance for Claude Code:

  • Architecture explanation
  • Development workflows
  • Deployment procedures
  • MCP protocol notes

scripts/start.sh

Production startup script:

  • Environment validation
  • Graceful startup
  • Logging configuration

scripts/healthcheck.sh

Docker healthcheck script:

  • Check /health endpoint
  • Validate MCP endpoint
  • Exit codes for Docker

tests/test_server_http.py

New test file for HTTP server:

  • MCP endpoint tests
  • JSON-RPC 2.0 validation
  • Protocol version tests

Package Rename

From: src/gitea_http_wrapper/ To: src/gitea_mcp_remote/

All imports throughout codebase must be updated:

# OLD
from gitea_http_wrapper.config import GiteaSettings

# NEW
from gitea_mcp_remote.config import GiteaSettings

Execution Order (18 Steps)

This is the exact sequence that must be followed:

  1. Rename package directory: gitea_http_wrappergitea_mcp_remote
  2. Update config/settings.py (fields + imports)
  3. Update middleware/auth.py (imports only)
  4. Update filtering/filter.py (warning + imports)
  5. Move tests: src/gitea_mcp_remote/tests/tests/
  6. Update all test imports
  7. Delete old server.py
  8. Create new server_http.py with MCP protocol
  9. Replace pyproject.toml with marketplace dependency
  10. Update pytest.ini test paths
  11. Create docker/ directory
  12. Move and update docker-compose.ymldocker/docker-compose.yml
  13. Replace Dockerfiledocker/Dockerfile
  14. Create docker/Caddyfile
  15. Create scripts/start.sh and scripts/healthcheck.sh
  16. Create tests/test_server_http.py
  17. Create CLAUDE.md
  18. Update DEPLOYMENT.md references

Validation Checklist (16 Items)

After implementation, ALL must pass:

Package Structure

  • src/gitea_mcp_remote/ exists (not gitea_http_wrapper)
  • No imports reference gitea_http_wrapper
  • tests/ is at repository root (not in src/)

Configuration

  • config/settings.py has mcp_auth_mode field
  • config/settings.py has gitea_repo: str | None
  • HTTP defaults are 0.0.0.0:8080

Server Implementation

  • server_http.py imports from mcp_server package
  • MCP endpoints exist: POST /mcp, HEAD /mcp
  • Health endpoints exist: /health, /healthz, /ping
  • No subprocess spawning code

Dependencies

  • pyproject.toml has marketplace Git dependency
  • Entry point is gitea-mcp-remote (not gitea-http-wrapper)
  • Can run: pip install -e . successfully

Docker

  • docker/docker-compose.yml has two services (app + caddy)
  • docker/Dockerfile installs git and uses port 8080
  • docker/Caddyfile exists and proxies to app:8080

Tests

  • All tests pass: pytest tests/

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│ Claude Desktop (MCP Client)                                 │
└───────────────────────┬─────────────────────────────────────┘
                        │ JSON-RPC 2.0 over HTTP
                        │ POST /mcp
                        ↓
┌─────────────────────────────────────────────────────────────┐
│ Caddy (HTTPS Termination)                                   │
│ - TLS/SSL                                                   │
│ - Reverse proxy to :8080                                    │
└───────────────────────┬─────────────────────────────────────┘
                        │
                        ↓
┌─────────────────────────────────────────────────────────────┐
│ server_http.py (MCP HTTP Transport)                         │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Starlette App                                           │ │
│ │ - POST /mcp (JSON-RPC handler)                          │ │
│ │ - HEAD /mcp (protocol version)                          │ │
│ │ - /health endpoints                                     │ │
│ └────────────────────┬────────────────────────────────────┘ │
│                      │                                       │
│                      ↓                                       │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Middleware Stack                                        │ │
│ │ - BearerAuthMiddleware (auth.py) ✓ Keep                │ │
│ │ - HealthCheckBypassMiddleware     ✓ Keep                │ │
│ └────────────────────┬────────────────────────────────────┘ │
│                      │                                       │
│                      ↓                                       │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Tool Dispatcher                                         │ │
│ │ - create_tool_dispatcher() from mcp_server             │ │
│ │ - Tool filtering (filter.py) ✓ Keep                    │ │
│ └────────────────────┬────────────────────────────────────┘ │
└──────────────────────┼──────────────────────────────────────┘
                       │ Direct Python calls
                       ↓
┌─────────────────────────────────────────────────────────────┐
│ Marketplace: mcp_server (gitea-mcp-server)                  │
│ - GiteaClient                                               │
│ - GiteaConfig                                               │
│ - get_tool_definitions()                                    │
│ - create_tool_dispatcher()                                  │
└───────────────────────┬─────────────────────────────────────┘
                        │ HTTPS API calls
                        ↓
┌─────────────────────────────────────────────────────────────┐
│ Gitea Instance (gitea.hotserv.cloud)                        │
└─────────────────────────────────────────────────────────────┘

Risk Assessment

Low Risk (Supporting Modules)

  • Config, middleware, filtering: Well-tested, only import changes
  • Tests: Moving location, no logic changes

Medium Risk (New Server Implementation)

  • server_http.py: New file, but following MCP HTTP spec closely
  • MCP protocol integration: Well-documented standard

High Risk (Deployment Changes)

  • Docker multi-service setup: Requires Caddy configuration
  • Marketplace Git dependency: Must be accessible during build

Mitigation Strategy

  1. Execute in exact order (dependencies first, server last)
  2. Test at each major milestone (config → middleware → server)
  3. Validate Docker build before final deployment
  4. Keep development branch for rollback if needed

Success Criteria

  1. All 16 validation items pass
  2. Can install via pip install -e .
  3. Can build Docker image successfully
  4. Can start via docker-compose up
  5. MCP endpoint responds to POST /mcp with protocol version
  6. Claude Desktop can connect and list tools
  7. Can create Gitea issue via MCP protocol
  8. All tests pass

Timeline Estimate

  • Setup & Config Changes: 2-3 hours
  • Server Rewrite: 4-6 hours
  • Docker Restructure: 3-4 hours
  • Testing & Validation: 4-5 hours
  • Documentation: 2-3 hours
  • Buffer for Issues: 4-5 hours

Total: 19-26 hours → 1 week sprint

References