3 Commits

Author SHA1 Message Date
1c55eed7c0 Merge feat/19: Rename package to gitea_mcp_remote and update configuration 2026-02-03 18:00:38 -05:00
5075139841 refactor: Rename package to gitea_mcp_remote and update configuration
Issue #19 - Foundation for Sprint 01: Core Architecture Correction

Changes:
- Renamed package directory: gitea_http_wrapper -> gitea_mcp_remote
- Updated config/settings.py:
  - Made gitea_repo optional (allow None)
  - Added mcp_auth_mode field (default: "optional")
  - Changed HTTP defaults: 0.0.0.0:8080 (was 127.0.0.1:8000)
  - Removed get_gitea_mcp_env() method (no longer needed)
- Updated all import paths throughout codebase
- Updated filtering/filter.py: Changed ValueError to warning when both
  enabled_tools and disabled_tools are specified
- Updated test files with new import paths
- Updated test_filtering.py to test warning instead of ValueError
- Updated pyproject.toml, pytest.ini, and README.md references

All modules preserved - only import paths and configuration updated.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:59:57 -05:00
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
21 changed files with 2562 additions and 44 deletions

View File

@@ -143,7 +143,7 @@ cp .env.example .env
nano .env nano .env
# Run the server # Run the server
gitea-http-wrapper gitea-mcp-remote
``` ```
The server will start on the configured host/port (default: `http://127.0.0.1:8000`). The server will start on the configured host/port (default: `http://127.0.0.1:8000`).
@@ -237,10 +237,10 @@ pip install -e ".[dev]"
pytest pytest
# Run with coverage # Run with coverage
pytest --cov=gitea_http_wrapper pytest --cov=gitea_mcp_remote
# Run specific test file # Run specific test file
pytest src/gitea_http_wrapper/tests/test_config.py pytest src/gitea_mcp_remote/tests/test_config.py
``` ```
### Project Structure ### Project Structure
@@ -248,7 +248,7 @@ pytest src/gitea_http_wrapper/tests/test_config.py
``` ```
gitea-mcp-remote/ gitea-mcp-remote/
├── src/ ├── src/
│ └── gitea_http_wrapper/ │ └── gitea_mcp_remote/
│ ├── __init__.py │ ├── __init__.py
│ ├── server.py # Main HTTP server │ ├── server.py # Main HTTP server
│ ├── config/ │ ├── config/

View File

@@ -0,0 +1,244 @@
# Sprint 01: Core Architecture Correction - SUMMARY
**Status:** 🟡 AWAITING APPROVAL
**Milestone:** [Sprint 01: Core Architecture Correction](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/milestone/29)
**Sprint Duration:** 1 week (Feb 3-10, 2026)
**Total Estimated Effort:** 19-28 hours
---
## Sprint Overview
This sprint addresses **three fatal architectural problems** introduced in the v1.0.0 release. 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: Spawns gitea-mcp-server as subprocess
- Required: Direct Python import from marketplace package
2. **Custom REST API → MCP Streamable HTTP Protocol**
- Current: Custom endpoints `/tools/list` and `/tools/call`
- Required: MCP protocol `POST /mcp` with JSON-RPC 2.0
3. **Missing Marketplace Dependency**
- Current: Comment about installing separately
- Required: Actual pip dependency from marketplace Git repo
---
## Issues Created
All issues are in Gitea milestone: **Sprint 01: Core Architecture Correction**
| Issue | Title | Type | Size | Est. Time | Dependencies |
|-------|-------|------|------|-----------|--------------|
| [#19](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/19) | Rename package to gitea_mcp_remote and update configuration | Refactor | M | 2-3h | None |
| [#20](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/20) | Update middleware and filtering with new import paths | Refactor | S | 1h | #19 |
| [#21](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/21) | Move tests to repository root and update imports | Refactor | M | 1-2h | #19, #20 |
| [#22](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/22) | Add marketplace dependency and update project config | Build | S | 1h | #19 |
| [#23](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/23) | Remove old server and create MCP base server structure | Feature | M | 2-3h | #19, #20, #22 |
| [#24](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/24) | Implement MCP Streamable HTTP protocol endpoints | Feature | M | 2-3h | #23 |
| [#25](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/25) | Create Docker multi-service infrastructure with Caddy | Build | M | 3-4h | #22, #24 |
| [#26](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/26) | Create startup scripts and MCP server tests | Test | M | 2-3h | #24 |
| [#27](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/27) | Create CLAUDE.md and update deployment documentation | Docs | M | 2-3h | All |
| [#28](https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/issues/28) | Final validation and integration testing | Test | M | 2-3h | All |
**Total Issues:** 10 (was 9, split large task into 2 medium tasks)
---
## Execution Order
The dependency graph ensures proper execution order:
```
#19 (Rename + Config) ← FOUNDATION
├─→ #20 (Middleware + Filtering)
│ └─→ #21 (Tests)
├─→ #22 (pyproject.toml)
│ ├─→ #23 (MCP Base Server)
│ │ ├─→ #24 (MCP Protocol)
│ │ │ ├─→ #25 (Docker)
│ │ │ └─→ #26 (Scripts + Tests)
│ │ │
│ └─→ #21 (Tests - can run parallel)
└─→ All above
└─→ #27 (Documentation)
└─→ #28 (Final Validation)
```
**Recommended sequence:**
1. #19#20#22#21 (Foundation - Day 1-2)
2. #23#24 (Core server - Day 2-3)
3. #25#26 (Infrastructure - Day 3-4)
4. #27#28 (Documentation and validation - Day 4-5)
---
## What to KEEP (Rename Imports Only)
These modules are **well-tested and solid**:
-`config/settings.py` - Minor field changes only
-`middleware/auth.py` - Import paths only
-`filtering/filter.py` - Change ValueError to warning
- ✅ All tests - Move to root, update imports
-`DEPLOYMENT.md` - Update references
---
## What to REPLACE
-`server.py` → ✅ `server_http.py` (new MCP implementation)
-`pyproject.toml` → ✅ Updated with marketplace dependency
-`docker-compose.yml` → ✅ `docker/docker-compose.yml` (two services)
-`Dockerfile` → ✅ `docker/Dockerfile` (git + port 8080)
---
## New Files to CREATE
- 📄 `docker/Caddyfile` - Reverse proxy config
- 📄 `CLAUDE.md` - Project guidance for Claude Code
- 📄 `tests/test_server_http.py` - MCP server tests
- 📄 `scripts/start.sh` - Production startup
- 📄 `scripts/healthcheck.sh` - Docker healthcheck
---
## Success Criteria (16 Validations)
### Package Structure (3)
- [ ] `src/gitea_mcp_remote/` exists (not `gitea_http_wrapper`)
- [ ] No imports reference `gitea_http_wrapper`
- [ ] `tests/` is at repository root (not in `src/`)
### Configuration (3)
- [ ] `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 (4)
- [ ] `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 (3)
- [ ] `pyproject.toml` has marketplace Git dependency
- [ ] Entry point is `gitea-mcp-remote` (not `gitea-http-wrapper`)
- [ ] Can run: `pip install -e .` successfully
### Docker (3)
- [ ] `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
---
## Timeline
### Effort Distribution
- **Small (1-2h):** 2 issues (#20, #22) = 2-4 hours
- **Medium (2-4h):** 8 issues (#19, #21, #23-28) = 17-24 hours
- **Total:** 19-28 hours ≈ 23.5 hours average
### Sprint Schedule (1 week)
- **Day 1-2:** Foundation (Issues #19-22) - 5-7 hours
- **Day 2-3:** Core Server (Issues #23-24) - 4-6 hours
- **Day 3-4:** Infrastructure (Issues #25-26) - 5-7 hours
- **Day 4-5:** Docs & Validation (Issues #27-28) - 4-6 hours
- **Buffer:** 1-2 hours for unexpected issues
---
## Risk Assessment
### Low Risk ✅
- Config, middleware, filtering: Well-tested, only import changes
- Test relocation: No logic changes
### Medium Risk ⚠️
- `server_http.py`: New file, but following MCP HTTP spec
- MCP protocol integration: Well-documented standard
### High Risk 🔴
- Docker multi-service: Requires Caddy configuration
- Marketplace Git dependency: Must be accessible during build
### Mitigation
1. Execute in exact dependency order
2. Test at each major milestone
3. Validate Docker build before deployment
4. Keep development branch for rollback
---
## Documentation Created
1. **[sprint-01-core-architecture-correction.md](./sprint-01-core-architecture-correction.md)**
- Executive summary
- Three fatal problems explained
- What to keep vs replace
- Architecture diagram
- Risk assessment
2. **[sprint-01-implementation-guide.md](./sprint-01-implementation-guide.md)**
- Step-by-step technical implementation
- Code snippets for each change
- Validation commands
- Complete file replacements
3. **[sprint-01-issue-breakdown.md](./sprint-01-issue-breakdown.md)**
- Detailed issue descriptions
- Dependency graph
- Execution order
- Size distribution
4. **[SPRINT-01-SUMMARY.md](./SPRINT-01-SUMMARY.md)** (this file)
- Sprint overview
- Issue table with links
- Success criteria
- Approval checklist
---
## Links
- **Milestone:** https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote/milestone/29
- **Repository:** https://gitea.hotserv.cloud/personal-projects/gitea-mcp-remote
- **Branch:** development
- **Marketplace:** https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace
---
## Approval Checklist
Before execution begins, verify:
- [ ] All 10 issues created and assigned to milestone
- [ ] Dependencies correctly set between issues
- [ ] Labels applied correctly (Type, Priority, Component, Size)
- [ ] Implementation guide reviewed and accurate
- [ ] Timeline is realistic (1 week)
- [ ] Success criteria are clear and testable
- [ ] Rollback plan understood (development branch)
- [ ] User has reviewed and approved the plan
---
## Next Steps
**AWAITING USER APPROVAL** to begin execution.
Once approved:
1. Start with Issue #19 (Foundation)
2. Follow dependency order strictly
3. Update issue status as work progresses
4. Run validation after each major milestone
5. Complete sprint with Issue #28 (Final Validation)
**Note:** This is attempt #3. User emphasized paying close attention to details. All requirements from the architectural correction prompt have been captured in the issue breakdown.

View File

@@ -0,0 +1,329 @@
# 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)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,489 @@
# Sprint 01: Issue Breakdown
## Issue Structure
Each issue is sized for 1-4 hours of work and includes:
- Clear acceptance criteria
- Dependencies on other issues
- Reference to implementation guide
- Appropriate labels
---
## Issue #1: Rename Package Directory and Update Config
**Title:** `[Sprint 01] refactor: Rename package to gitea_mcp_remote and update configuration`
**Estimated Time:** 2-3 hours
**Labels:**
- `Type/Refactor`
- `Priority/High`
- `Component/Core`
- `Size/M`
**Dependencies:** None
**Description:**
Rename the package directory from `gitea_http_wrapper` to `gitea_mcp_remote` and update the configuration module with new fields required for MCP protocol.
**Tasks:**
- [ ] Rename `src/gitea_http_wrapper/` to `src/gitea_mcp_remote/`
- [ ] Update `config/settings.py`:
- 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
- [ ] Update `config/__init__.py` imports
- [ ] Verify imports work: `from gitea_mcp_remote.config import GiteaSettings`
**Acceptance Criteria:**
- Package directory is `src/gitea_mcp_remote/`
- Config has `mcp_auth_mode` field
- Config has optional `gitea_repo` field
- HTTP defaults are `0.0.0.0:8080`
- Can import: `from gitea_mcp_remote.config import GiteaSettings`
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 1, Issues #1-2
---
## Issue #2: Update Middleware and Filtering Modules
**Title:** `[Sprint 01] refactor: Update middleware and filtering with new import paths`
**Estimated Time:** 1 hour
**Labels:**
- `Type/Refactor`
- `Priority/High`
- `Component/Core`
- `Size/S`
**Dependencies:** Issue #1
**Description:**
Update middleware and filtering modules to use new package name. Middleware requires only import changes, filtering changes ValueError to warning.
**Tasks:**
- [ ] Update `middleware/__init__.py` imports
- [ ] Update `middleware/auth.py` - imports only
- [ ] Update `filtering/__init__.py` imports
- [ ] Update `filtering/filter.py`:
- Add logging import
- Change line 29-32 ValueError to logger.warning
- [ ] Verify imports work
**Acceptance Criteria:**
- Middleware imports from `gitea_mcp_remote.middleware`
- Filtering imports from `gitea_mcp_remote.filtering`
- ToolFilter logs warning instead of raising ValueError when both filter types specified
- Can import both modules successfully
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 2, Issues #3-4
---
## Issue #3: Relocate Tests and Update Imports
**Title:** `[Sprint 01] refactor: Move tests to repository root and update imports`
**Estimated Time:** 1-2 hours
**Labels:**
- `Type/Refactor`
- `Priority/High`
- `Component/Tests`
- `Size/M`
**Dependencies:** Issue #1, Issue #2
**Description:**
Move test suite from `src/gitea_mcp_remote/tests/` to repository root `tests/` directory and update all test imports to use new package name.
**Tasks:**
- [ ] Move `src/gitea_mcp_remote/tests/` to `tests/`
- [ ] Update imports in `tests/conftest.py`
- [ ] Update imports in `tests/test_config.py`
- [ ] Update imports in `tests/test_middleware.py`
- [ ] Update imports in `tests/test_filtering.py`
- [ ] Update `pytest.ini` to use `testpaths = tests`
- [ ] Run pytest and verify all tests pass
**Acceptance Criteria:**
- Tests located at repository root: `tests/`
- No tests in `src/gitea_mcp_remote/tests/`
- All test imports use `gitea_mcp_remote` package name
- All existing tests pass: `pytest tests/ -v`
- pytest.ini references `testpaths = tests`
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 3, Issues #5-6
---
## Issue #4: Replace pyproject.toml with Marketplace Dependency
**Title:** `[Sprint 01] build: Add marketplace dependency and update project configuration`
**Estimated Time:** 1 hour
**Labels:**
- `Type/Build`
- `Priority/Critical`
- `Component/Dependencies`
- `Size/S`
**Dependencies:** Issue #1
**Description:**
Replace pyproject.toml with new configuration including the marketplace Git dependency for gitea-mcp-server.
**Tasks:**
- [ ] Update `pyproject.toml`:
- Add marketplace Git dependency
- Update package name to `gitea-mcp-remote`
- Change entry point to `gitea-mcp-remote`
- Update version to 1.1.0
- Update test paths to `testpaths = ["tests"]`
- [ ] Test installation: `pip install -e .`
- [ ] Verify marketplace dependency installs
- [ ] Verify entry point exists: `which gitea-mcp-remote`
**Acceptance Criteria:**
- pyproject.toml includes marketplace Git dependency
- Entry point is `gitea-mcp-remote` (not `gitea-http-wrapper`)
- Can run: `pip install -e .` successfully
- Marketplace dependency installs from Git repository
- Command `gitea-mcp-remote` is available
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 5, Issue #9
---
## Issue #5: Implement MCP HTTP Server
**Title:** `[Sprint 01] feat: Implement MCP Streamable HTTP protocol server`
**Estimated Time:** 4-6 hours
**Labels:**
- `Type/Feature`
- `Priority/Critical`
- `Component/Core`
- `Size/L`**BREAKDOWN REQUIRED**
**Dependencies:** Issue #1, Issue #2, Issue #4
**Description:**
**NOTE:** This is a Large (L) task that should be broken down into Medium (M) subtasks:
### Subtask 5.1: Remove Old Server and Create MCP Base Server (2-3 hours)
- Delete `src/gitea_mcp_remote/server.py`
- Create `src/gitea_mcp_remote/server_http.py` with:
- Imports from marketplace `mcp_server`
- GiteaMCPServer class with GiteaClient initialization
- Startup/shutdown handlers
- Basic route structure
### Subtask 5.2: Implement MCP Protocol Endpoints (2-3 hours)
- Add HEAD /mcp endpoint (protocol version)
- Add POST /mcp endpoint (JSON-RPC 2.0 handler)
- Implement MCP methods:
- `initialize`
- `tools/list`
- `tools/call`
- Add error handling for JSON-RPC
**Combined Tasks:**
- [ ] Delete old `server.py`
- [ ] Create new `server_http.py`
- [ ] Import from marketplace: `from mcp_server import ...`
- [ ] Implement GiteaMCPServer class
- [ ] Implement HEAD /mcp (protocol version)
- [ ] Implement POST /mcp (JSON-RPC handler)
- [ ] Implement initialize method
- [ ] Implement tools/list method with filtering
- [ ] Implement tools/call method with dispatcher
- [ ] Keep health endpoints: /health, /healthz, /ping
- [ ] Add JSON-RPC error handling
- [ ] Verify imports: `from gitea_mcp_remote.server_http import GiteaMCPServer`
**Acceptance Criteria:**
- Old `server.py` deleted
- New `server_http.py` exists
- Imports from marketplace `mcp_server` package
- MCP endpoints exist: `POST /mcp`, `HEAD /mcp`
- Health endpoints exist: `/health`, `/healthz`, `/ping`
- No subprocess spawning code
- Can import server module successfully
- JSON-RPC 2.0 request/response handling works
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 4, Issues #7-8
**Recommendation:** Create two separate issues (5.1 and 5.2) to keep within M size.
---
## Issue #6: Create Docker Infrastructure
**Title:** `[Sprint 01] build: Create Docker multi-service infrastructure with Caddy`
**Estimated Time:** 3-4 hours
**Labels:**
- `Type/Build`
- `Priority/High`
- `Component/Docker`
- `Size/M`
**Dependencies:** Issue #4, Issue #5
**Description:**
Create Docker infrastructure with two-service architecture: Python app and Caddy reverse proxy.
**Tasks:**
- [ ] Create `docker/` directory
- [ ] Create `docker/docker-compose.yml` with two services (app + caddy)
- [ ] Create `docker/Dockerfile`:
- Install git package
- Expose port 8080
- Use curl for healthcheck
- Install marketplace dependency
- [ ] Create `docker/Caddyfile`:
- HTTPS termination
- Proxy to app:8080
- MCP endpoint routing
- [ ] Validate Dockerfile builds
- [ ] Validate docker-compose configuration
- [ ] Validate Caddyfile syntax
**Acceptance Criteria:**
- `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
- Can build: `docker build -f docker/Dockerfile -t test .`
- Can validate: `docker-compose -f docker/docker-compose.yml config`
- Caddy config validates successfully
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 6, Issues #11-14
---
## Issue #7: Create Utility Scripts and Server Tests
**Title:** `[Sprint 01] test: Create startup scripts and MCP server tests`
**Estimated Time:** 2-3 hours
**Labels:**
- `Type/Test`
- `Priority/Medium`
- `Component/Tests`
- `Size/M`
**Dependencies:** Issue #5
**Description:**
Create production utility scripts and comprehensive tests for the new MCP HTTP server.
**Tasks:**
- [ ] Create `scripts/start.sh` (production startup)
- [ ] Create `scripts/healthcheck.sh` (Docker healthcheck)
- [ ] Make scripts executable
- [ ] Create `tests/test_server_http.py`:
- Health endpoint tests
- MCP HEAD endpoint test (protocol version)
- MCP POST endpoint tests (initialize, tools/list, tools/call)
- JSON-RPC error handling tests
- Tool filtering integration test
- [ ] Run new tests and verify they pass
**Acceptance Criteria:**
- `scripts/start.sh` validates environment and starts server
- `scripts/healthcheck.sh` checks health endpoint
- Both scripts are executable
- `tests/test_server_http.py` exists with comprehensive coverage
- All new tests pass: `pytest tests/test_server_http.py -v`
- All existing tests still pass: `pytest tests/ -v`
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 7-8, Issues #15-16
---
## Issue #8: Create Documentation
**Title:** `[Sprint 01] docs: Create CLAUDE.md and update deployment documentation`
**Estimated Time:** 2-3 hours
**Labels:**
- `Type/Documentation`
- `Priority/Medium`
- `Component/Documentation`
- `Size/M`
**Dependencies:** All previous issues
**Description:**
Create comprehensive project documentation for Claude Code and update deployment guide with new MCP protocol and Docker structure.
**Tasks:**
- [ ] Create `CLAUDE.md`:
- Project overview
- Architecture diagram
- Development workflows
- MCP protocol notes
- Configuration reference
- Deployment instructions
- Troubleshooting guide
- [ ] Update `DEPLOYMENT.md`:
- Replace custom REST API refs with MCP protocol
- Update Docker structure (docker/ directory, two services)
- Update marketplace dependency installation
- Update Claude Desktop config example
- Add MCP protocol debugging section
- [ ] Verify documentation accuracy
**Acceptance Criteria:**
- `CLAUDE.md` exists with complete project guidance
- `DEPLOYMENT.md` updated with MCP protocol references
- No references to old `/tools/list` or `/tools/call` endpoints
- Docker paths reference `docker/docker-compose.yml`
- Claude Desktop config shows `/mcp` endpoint
- All code examples are accurate
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Phase 9, Issues #17-18
---
## Issue #9: Final Validation and Integration Testing
**Title:** `[Sprint 01] test: Final validation and integration testing`
**Estimated Time:** 2-3 hours
**Labels:**
- `Type/Test`
- `Priority/Critical`
- `Component/Integration`
- `Size/M`
**Dependencies:** All previous issues
**Description:**
Run complete validation checklist to ensure all architectural corrections are in place and working correctly.
**Tasks:**
- [ ] Verify package structure (no gitea_http_wrapper)
- [ ] Verify no old imports remain
- [ ] Verify config has all new fields
- [ ] Verify server has MCP endpoints
- [ ] Run: `pip install -e .` successfully
- [ ] Run: `pytest tests/ -v` - all tests pass
- [ ] Build Docker image successfully
- [ ] Validate docker-compose configuration
- [ ] Validate Caddyfile syntax
- [ ] Test MCP endpoint responds to protocol version request
- [ ] Test MCP endpoint handles JSON-RPC messages
- [ ] Document any issues found
- [ ] Create follow-up issues if needed
**Acceptance Criteria:**
All 16 validation items 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/`
**Implementation Reference:**
See `docs/sprint-proposals/sprint-01-implementation-guide.md` - Final Validation section
---
## Issue Dependencies Graph
```
Issue #1 (Rename + Config)
├─→ Issue #2 (Middleware + Filtering)
│ └─→ Issue #3 (Tests)
├─→ Issue #4 (pyproject.toml)
│ ├─→ Issue #5 (MCP Server)
│ │ ├─→ Issue #6 (Docker)
│ │ └─→ Issue #7 (Scripts + Tests)
│ │
│ └─→ Issue #3 (Tests)
└─→ All above
└─→ Issue #8 (Documentation)
└─→ Issue #9 (Final Validation)
```
## Execution Order
1. Issue #1 - Rename + Config (Foundation)
2. Issue #2 - Middleware + Filtering (Supporting modules)
3. Issue #4 - pyproject.toml (Dependencies before server)
4. Issue #3 - Tests (Can run in parallel with #4)
5. Issue #5 - MCP Server (Core implementation) **Consider splitting into 5.1 and 5.2**
6. Issue #6 - Docker (Deployment infrastructure)
7. Issue #7 - Scripts + Tests (Validation tools)
8. Issue #8 - Documentation (After implementation complete)
9. Issue #9 - Final Validation (Sprint completion)
## Size Distribution
- **Small (1-2h):** Issues #2, #4 (2 issues)
- **Medium (2-4h):** Issues #1, #3, #6, #7, #8, #9 (6 issues)
- **Large (4-6h):** Issue #5 (1 issue - SHOULD BE SPLIT)
**Recommendation:** Split Issue #5 into two Medium issues for better tracking and clearer completion criteria.
## Total Estimated Time
- Minimum: 19 hours
- Maximum: 28 hours
- Average: 23.5 hours
- **Sprint Duration:** 1 week (5 working days)

View File

@@ -44,7 +44,7 @@ dev = [
] ]
[project.scripts] [project.scripts]
gitea-http-wrapper = "gitea_http_wrapper.server:main" gitea-mcp-remote = "gitea_mcp_remote.server:main"
[project.urls] [project.urls]
Homepage = "https://github.com/lmiranda/gitea-mcp-remote" Homepage = "https://github.com/lmiranda/gitea-mcp-remote"
@@ -55,7 +55,7 @@ where = ["src"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
asyncio_mode = "auto" asyncio_mode = "auto"
testpaths = ["src/gitea_http_wrapper/tests"] testpaths = ["src/gitea_mcp_remote/tests"]
python_files = ["test_*.py"] python_files = ["test_*.py"]
python_classes = ["Test*"] python_classes = ["Test*"]
python_functions = ["test_*"] python_functions = ["test_*"]

View File

@@ -1,5 +1,5 @@
[pytest] [pytest]
testpaths = src/gitea_http_wrapper/tests testpaths = src/gitea_mcp_remote/tests
python_files = test_*.py python_files = test_*.py
python_classes = Test* python_classes = Test*
python_functions = test_* python_functions = test_*

View File

@@ -1,5 +0,0 @@
"""Configuration loader module."""
from .settings import GiteaSettings, load_settings
__all__ = ["GiteaSettings", "load_settings"]

View File

@@ -0,0 +1,5 @@
"""Configuration module for Gitea MCP HTTP transport."""
from gitea_mcp_remote.config.settings import GiteaSettings, load_settings
__all__ = ["GiteaSettings", "load_settings"]

View File

@@ -1,4 +1,4 @@
"""Configuration settings for Gitea HTTP MCP wrapper.""" """Configuration settings for Gitea MCP HTTP transport."""
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
@@ -30,18 +30,18 @@ class GiteaSettings(BaseSettings):
..., ...,
description="Default repository owner/organization", description="Default repository owner/organization",
) )
gitea_repo: str = Field( gitea_repo: str | None = Field(
..., default=None,
description="Default repository name", description="Default repository name (optional)",
) )
# HTTP Server Configuration # HTTP Server Configuration
http_host: str = Field( http_host: str = Field(
default="127.0.0.1", default="0.0.0.0",
description="HTTP server bind address", description="HTTP server bind address",
) )
http_port: int = Field( http_port: int = Field(
default=8000, default=8080,
ge=1, ge=1,
le=65535, le=65535,
description="HTTP server port", description="HTTP server port",
@@ -52,6 +52,10 @@ class GiteaSettings(BaseSettings):
default=None, default=None,
description="Bearer token for HTTP authentication (optional)", description="Bearer token for HTTP authentication (optional)",
) )
mcp_auth_mode: str = Field(
default="optional",
description="MCP authentication mode: 'required', 'optional', or 'none'",
)
# Tool Filtering Configuration # Tool Filtering Configuration
enabled_tools: Optional[str] = Field( enabled_tools: Optional[str] = Field(
@@ -85,15 +89,6 @@ class GiteaSettings(BaseSettings):
return None return None
return [tool.strip() for tool in self.disabled_tools.split(",") if tool.strip()] return [tool.strip() for tool in self.disabled_tools.split(",") if tool.strip()]
def get_gitea_mcp_env(self) -> dict[str, str]:
"""Get environment variables for the wrapped Gitea MCP server."""
return {
"GITEA_BASE_URL": self.gitea_url,
"GITEA_API_TOKEN": self.gitea_token,
"GITEA_DEFAULT_OWNER": self.gitea_owner,
"GITEA_DEFAULT_REPO": self.gitea_repo,
}
def load_settings(env_file: Optional[Path] = None) -> GiteaSettings: def load_settings(env_file: Optional[Path] = None) -> GiteaSettings:
""" """

View File

@@ -1,7 +1,10 @@
"""Tool filtering for Claude Desktop compatibility.""" """Tool filtering for Claude Desktop compatibility."""
import logging
from typing import Any from typing import Any
logger = logging.getLogger(__name__)
class ToolFilter: class ToolFilter:
""" """
@@ -22,13 +25,11 @@ class ToolFilter:
Args: Args:
enabled_tools: List of tool names to enable. If None, all tools are enabled. enabled_tools: List of tool names to enable. If None, all tools are enabled.
disabled_tools: List of tool names to disable. Takes precedence over enabled_tools. disabled_tools: List of tool names to disable. Takes precedence over enabled_tools.
Raises:
ValueError: If both enabled_tools and disabled_tools are specified.
""" """
if enabled_tools is not None and disabled_tools is not None: if enabled_tools is not None and disabled_tools is not None:
raise ValueError( logger.warning(
"Cannot specify both enabled_tools and disabled_tools. Choose one filtering mode." "Both enabled_tools and disabled_tools specified. "
"Disabled list takes precedence over enabled list."
) )
self.enabled_tools = set(enabled_tools) if enabled_tools else None self.enabled_tools = set(enabled_tools) if enabled_tools else None

View File

@@ -16,9 +16,9 @@ from starlette.requests import Request
from starlette.responses import JSONResponse from starlette.responses import JSONResponse
from starlette.routing import Route from starlette.routing import Route
from gitea_http_wrapper.config import GiteaSettings, load_settings from gitea_mcp_remote.config import GiteaSettings, load_settings
from gitea_http_wrapper.filtering import ToolFilter from gitea_mcp_remote.filtering import ToolFilter
from gitea_http_wrapper.middleware import ( from gitea_mcp_remote.middleware import (
BearerAuthMiddleware, BearerAuthMiddleware,
HealthCheckBypassMiddleware, HealthCheckBypassMiddleware,
) )
@@ -298,7 +298,7 @@ def main() -> None:
# Run server # Run server
uvicorn.run( uvicorn.run(
"gitea_http_wrapper.server:app", "gitea_mcp_remote.server:app",
host=settings.http_host, host=settings.http_host,
port=settings.http_port, port=settings.http_port,
log_level="info", log_level="info",

View File

@@ -6,7 +6,7 @@ from pathlib import Path
import pytest import pytest
from pydantic import ValidationError from pydantic import ValidationError
from gitea_http_wrapper.config import GiteaSettings, load_settings from gitea_mcp_remote.config import GiteaSettings, load_settings
class TestGiteaSettings: class TestGiteaSettings:

View File

@@ -2,18 +2,24 @@
import pytest import pytest
from gitea_http_wrapper.filtering import ToolFilter from gitea_mcp_remote.filtering import ToolFilter
class TestToolFilter: class TestToolFilter:
"""Test ToolFilter class.""" """Test ToolFilter class."""
def test_init_with_both_lists_raises(self): def test_init_with_both_lists_logs_warning(self, caplog):
"""Test that specifying both enabled and disabled lists raises error.""" """Test that specifying both enabled and disabled lists logs warning."""
with pytest.raises(ValueError) as exc_info: import logging
ToolFilter(enabled_tools=["tool1"], disabled_tools=["tool2"])
assert "Cannot specify both" in str(exc_info.value) with caplog.at_level(logging.WARNING):
filter = ToolFilter(enabled_tools=["tool1"], disabled_tools=["tool2"])
assert "Both enabled_tools and disabled_tools specified" in caplog.text
assert "Disabled list takes precedence" in caplog.text
# Verify disabled list takes precedence
assert not filter.should_include_tool("tool2")
def test_passthrough_mode(self): def test_passthrough_mode(self):
"""Test passthrough mode (no filtering).""" """Test passthrough mode (no filtering)."""

View File

@@ -6,7 +6,7 @@ from starlette.responses import JSONResponse
from starlette.routing import Route from starlette.routing import Route
from starlette.testclient import TestClient from starlette.testclient import TestClient
from gitea_http_wrapper.middleware import ( from gitea_mcp_remote.middleware import (
BearerAuthMiddleware, BearerAuthMiddleware,
HealthCheckBypassMiddleware, HealthCheckBypassMiddleware,
) )