generated from personal-projects/leo-claude-mktplace
Compare commits
3 Commits
c9961293d9
...
1c55eed7c0
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c55eed7c0 | |||
| 5075139841 | |||
| 16436c847a |
@@ -143,7 +143,7 @@ cp .env.example .env
|
||||
nano .env
|
||||
|
||||
# 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`).
|
||||
@@ -237,10 +237,10 @@ pip install -e ".[dev]"
|
||||
pytest
|
||||
|
||||
# Run with coverage
|
||||
pytest --cov=gitea_http_wrapper
|
||||
pytest --cov=gitea_mcp_remote
|
||||
|
||||
# Run specific test file
|
||||
pytest src/gitea_http_wrapper/tests/test_config.py
|
||||
pytest src/gitea_mcp_remote/tests/test_config.py
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
@@ -248,7 +248,7 @@ pytest src/gitea_http_wrapper/tests/test_config.py
|
||||
```
|
||||
gitea-mcp-remote/
|
||||
├── src/
|
||||
│ └── gitea_http_wrapper/
|
||||
│ └── gitea_mcp_remote/
|
||||
│ ├── __init__.py
|
||||
│ ├── server.py # Main HTTP server
|
||||
│ ├── config/
|
||||
|
||||
244
docs/sprint-proposals/SPRINT-01-SUMMARY.md
Normal file
244
docs/sprint-proposals/SPRINT-01-SUMMARY.md
Normal 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.
|
||||
329
docs/sprint-proposals/sprint-01-core-architecture-correction.md
Normal file
329
docs/sprint-proposals/sprint-01-core-architecture-correction.md
Normal 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)
|
||||
1454
docs/sprint-proposals/sprint-01-implementation-guide.md
Normal file
1454
docs/sprint-proposals/sprint-01-implementation-guide.md
Normal file
File diff suppressed because it is too large
Load Diff
489
docs/sprint-proposals/sprint-01-issue-breakdown.md
Normal file
489
docs/sprint-proposals/sprint-01-issue-breakdown.md
Normal 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)
|
||||
@@ -44,7 +44,7 @@ dev = [
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
gitea-http-wrapper = "gitea_http_wrapper.server:main"
|
||||
gitea-mcp-remote = "gitea_mcp_remote.server:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/lmiranda/gitea-mcp-remote"
|
||||
@@ -55,7 +55,7 @@ where = ["src"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = "auto"
|
||||
testpaths = ["src/gitea_http_wrapper/tests"]
|
||||
testpaths = ["src/gitea_mcp_remote/tests"]
|
||||
python_files = ["test_*.py"]
|
||||
python_classes = ["Test*"]
|
||||
python_functions = ["test_*"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[pytest]
|
||||
testpaths = src/gitea_http_wrapper/tests
|
||||
testpaths = src/gitea_mcp_remote/tests
|
||||
python_files = test_*.py
|
||||
python_classes = Test*
|
||||
python_functions = test_*
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
"""Configuration loader module."""
|
||||
|
||||
from .settings import GiteaSettings, load_settings
|
||||
|
||||
__all__ = ["GiteaSettings", "load_settings"]
|
||||
5
src/gitea_mcp_remote/config/__init__.py
Normal file
5
src/gitea_mcp_remote/config/__init__.py
Normal 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"]
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Configuration settings for Gitea HTTP MCP wrapper."""
|
||||
"""Configuration settings for Gitea MCP HTTP transport."""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
@@ -30,18 +30,18 @@ class GiteaSettings(BaseSettings):
|
||||
...,
|
||||
description="Default repository owner/organization",
|
||||
)
|
||||
gitea_repo: str = Field(
|
||||
...,
|
||||
description="Default repository name",
|
||||
gitea_repo: str | None = Field(
|
||||
default=None,
|
||||
description="Default repository name (optional)",
|
||||
)
|
||||
|
||||
# HTTP Server Configuration
|
||||
http_host: str = Field(
|
||||
default="127.0.0.1",
|
||||
default="0.0.0.0",
|
||||
description="HTTP server bind address",
|
||||
)
|
||||
http_port: int = Field(
|
||||
default=8000,
|
||||
default=8080,
|
||||
ge=1,
|
||||
le=65535,
|
||||
description="HTTP server port",
|
||||
@@ -52,6 +52,10 @@ class GiteaSettings(BaseSettings):
|
||||
default=None,
|
||||
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
|
||||
enabled_tools: Optional[str] = Field(
|
||||
@@ -85,15 +89,6 @@ class GiteaSettings(BaseSettings):
|
||||
return None
|
||||
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:
|
||||
"""
|
||||
@@ -1,7 +1,10 @@
|
||||
"""Tool filtering for Claude Desktop compatibility."""
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ToolFilter:
|
||||
"""
|
||||
@@ -22,13 +25,11 @@ class ToolFilter:
|
||||
Args:
|
||||
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.
|
||||
|
||||
Raises:
|
||||
ValueError: If both enabled_tools and disabled_tools are specified.
|
||||
"""
|
||||
if enabled_tools is not None and disabled_tools is not None:
|
||||
raise ValueError(
|
||||
"Cannot specify both enabled_tools and disabled_tools. Choose one filtering mode."
|
||||
logger.warning(
|
||||
"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
|
||||
@@ -16,9 +16,9 @@ from starlette.requests import Request
|
||||
from starlette.responses import JSONResponse
|
||||
from starlette.routing import Route
|
||||
|
||||
from gitea_http_wrapper.config import GiteaSettings, load_settings
|
||||
from gitea_http_wrapper.filtering import ToolFilter
|
||||
from gitea_http_wrapper.middleware import (
|
||||
from gitea_mcp_remote.config import GiteaSettings, load_settings
|
||||
from gitea_mcp_remote.filtering import ToolFilter
|
||||
from gitea_mcp_remote.middleware import (
|
||||
BearerAuthMiddleware,
|
||||
HealthCheckBypassMiddleware,
|
||||
)
|
||||
@@ -298,7 +298,7 @@ def main() -> None:
|
||||
|
||||
# Run server
|
||||
uvicorn.run(
|
||||
"gitea_http_wrapper.server:app",
|
||||
"gitea_mcp_remote.server:app",
|
||||
host=settings.http_host,
|
||||
port=settings.http_port,
|
||||
log_level="info",
|
||||
@@ -6,7 +6,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from gitea_http_wrapper.config import GiteaSettings, load_settings
|
||||
from gitea_mcp_remote.config import GiteaSettings, load_settings
|
||||
|
||||
|
||||
class TestGiteaSettings:
|
||||
@@ -2,18 +2,24 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from gitea_http_wrapper.filtering import ToolFilter
|
||||
from gitea_mcp_remote.filtering import ToolFilter
|
||||
|
||||
|
||||
class TestToolFilter:
|
||||
"""Test ToolFilter class."""
|
||||
|
||||
def test_init_with_both_lists_raises(self):
|
||||
"""Test that specifying both enabled and disabled lists raises error."""
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
ToolFilter(enabled_tools=["tool1"], disabled_tools=["tool2"])
|
||||
def test_init_with_both_lists_logs_warning(self, caplog):
|
||||
"""Test that specifying both enabled and disabled lists logs warning."""
|
||||
import logging
|
||||
|
||||
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):
|
||||
"""Test passthrough mode (no filtering)."""
|
||||
@@ -6,7 +6,7 @@ from starlette.responses import JSONResponse
|
||||
from starlette.routing import Route
|
||||
from starlette.testclient import TestClient
|
||||
|
||||
from gitea_http_wrapper.middleware import (
|
||||
from gitea_mcp_remote.middleware import (
|
||||
BearerAuthMiddleware,
|
||||
HealthCheckBypassMiddleware,
|
||||
)
|
||||
Reference in New Issue
Block a user