# 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 ```python # 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 ```python # 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 ```toml # 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_wrapper` → `gitea_mcp_remote`) ### filtering/filter.py - **Keep:** Entire filtering logic - **Changes:** - Line 30: Change `raise ValueError(...)` to `logger.warning(...)` (non-fatal) - Import paths: `gitea_http_wrapper` → `gitea_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: ```python # 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_wrapper` → `gitea_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.yml` → `docker/docker-compose.yml` 13. Replace `Dockerfile` → `docker/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 - MCP Streamable HTTP Spec: https://spec.modelcontextprotocol.io/specification/basic/transports/ - JSON-RPC 2.0 Spec: https://www.jsonrpc.org/specification - Marketplace Repository: https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace - Original Issue: (To be created in this sprint)