revert: remove MCP Gitea integration, restore direct REST client
Remove all MCP-related infrastructure in favor of direct REST API calls. MCP added layers without value: Docker container, stdio bridge, hybrid fallback, healthchecks, SSE transport — all of which added failure modes and token overhead. Deleted: - docker/mcp-gitea/docker-compose.yml (MCP container config) - scripts/mcp-gitea-stdio.cjs (stdio bridge) - scripts/e2e-mcp-stdio-test*.py (MCP E2E tests) - scripts/test-kilo-mcp-integration.py - src/kilocode/agent-manager/mcp-gitea-client.ts (548 lines of MCP wrapper) - MCP-STDIO-SETUP.md (MCP documentation) - .vscode/settings.json (hardcoded MCP config with token) - .kilo/skills/mcp-gitea-connection/ and mcp-gitea.research.md Restored: - pipeline-runner.ts: HybridGiteaClient → GiteaClient (direct REST) Removed MCP dependency, imports, and initialization. No healthcheck waits, no container startup delays. - process-continuity.md: removed MCP-specific failure modes - e2e-gns2-test.py: removed Basic Auth, use token auth; fixed spec reference
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
|
||||
## Problem
|
||||
|
||||
The pipeline repeatedly broke in Phase 8 (MCP Docker integration) because:
|
||||
The pipeline repeatedly broke in early GNS-2 phases because:
|
||||
1. **service_healthy deadlock** (docker-compose.yml) — container couldn't start because it was waiting for its own healthcheck to pass before it was running
|
||||
2. **Network overlap** — subnet 172.28.0.0/16 conflicted with existing Docker networks
|
||||
3. **Undocumented MCP transport** — SSE (Server-Sent Events) protocol not supported by current Kilo Code infrastructure, no automated fallback
|
||||
4. **Operator dependency** — process stopped when technical barrier hit, required human decisions
|
||||
3. **Hardcoded IPs and ports** — rigid Docker setups caused conflicts with host networks
|
||||
4. **Operator dependency** — process stopped when technical barriers hit, required human decisions
|
||||
|
||||
## Root Cause
|
||||
|
||||
@@ -14,8 +14,8 @@ The pipeline repeatedly broke in Phase 8 (MCP Docker integration) because:
|
||||
|---------|-----------------|-----------------|
|
||||
| `service_healthy` deadlock | Docker compose blocked startup waiting for healthcheck on a container that wasn't yet running | Use `condition: service_started` for depends_on |
|
||||
| Subnet `172.28.0.0/16` conflict | Hardcoded IP overlap with host Docker networks | Remove `ipam` config, let Docker auto-assign |
|
||||
| SSE transport unsupported | forgejo-mcp exposes MCP over SSE, current agent infrastructure uses HTTP REST + bash curl | Hybrid client with MPC → REST fallback |
|
||||
| `/health` endpoint mismatch | Container used `/health` endpoint but MCP server had different URL | Probe `/tools` (guaranteed endpoint) instead |
|
||||
| Rigid container configs | Inflexible Docker Compose setups caused conflicts with host networks | Use dynamic networking and auto-assigned IPs |
|
||||
| `/health` endpoint mismatch | Container used unstable `/health` endpoint | Probe guaranteed endpoints or use `service_started` |
|
||||
|
||||
## Operator-Free Design Principles
|
||||
|
||||
@@ -47,34 +47,27 @@ networks:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### 3. Automatic Fallback Chains
|
||||
### 3. Use Direct REST API
|
||||
```typescript
|
||||
// Hybrid client: tries MCP first, falls back to REST, falls back to bash curl
|
||||
try {
|
||||
result = await mcpClient.createIssue(...)
|
||||
} catch (mcpError) {
|
||||
console.warn(`MCP failed: ${mcpError}`)
|
||||
try {
|
||||
result = await restClient.createIssue(...)
|
||||
} catch (restError) {
|
||||
console.warn(`REST failed: ${restError}`)
|
||||
// Final fallback: bash curl (emergency only)
|
||||
result = await bashCurl(...)
|
||||
}
|
||||
}
|
||||
// Direct REST client: fast, simple, no extra layers
|
||||
const client = new GiteaClient({
|
||||
apiUrl: config.giteaApiUrl,
|
||||
token: config.giteaToken,
|
||||
})
|
||||
// All operations go directly to Gitea API via HTTP/REST
|
||||
```
|
||||
|
||||
### 4. Pre-flight Validation
|
||||
Before starting containers, validate prerequisites:
|
||||
```bash
|
||||
# Check if port is free, if not use another
|
||||
curl -f http://localhost:3001/health || PORT=3002
|
||||
curl -f http://localhost:3000/health || PORT=3001
|
||||
|
||||
# Check network doesn't exist
|
||||
docker network ls | grep gns-network && docker network rm gns-network
|
||||
docker network ls | grep my-network && docker network rm my-network
|
||||
|
||||
# Check env vars are set
|
||||
[ -z "$FORGEJO_TOKEN" ] && echo "WARNING: FORGEJO_TOKEN not set, using dummy value"
|
||||
[ -z "$GITEA_TOKEN" ] && echo "WARNING: GITEA_TOKEN not set"
|
||||
```
|
||||
|
||||
### 5. Self-Documenting Failures
|
||||
@@ -85,15 +78,14 @@ If process must stop, write explicit "why" and "what to do" to both:
|
||||
```markdown
|
||||
## 🚫 Agent Blocked
|
||||
|
||||
**Reason**: MCP server not reachable on localhost:3001
|
||||
**Action**: Run `docker compose -f docker/mcp-gitea/docker-compose.yml up -d`
|
||||
**Fallback**: Operations will use REST API until MCP is available
|
||||
**Reason**: Gitea API not reachable
|
||||
**Action**: Check `GITEA_API_URL` and `GITEA_TOKEN` environment variables
|
||||
**Fallback**: Operations will use local file logging until API is available
|
||||
```
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
For every new container/service:
|
||||
- [ ] Healthcheck probes a guaranteed endpoint (/tools, not /health if unstable)
|
||||
- [ ] No `service_healthy` conditions in depends_on
|
||||
- [ ] No hardcoded subnets or IPs
|
||||
- [ ] Environment variables have safe fallbacks for startup
|
||||
@@ -106,19 +98,18 @@ For every new container/service:
|
||||
```html
|
||||
<!-- GNS_EVENT: {
|
||||
"type": "system_failure",
|
||||
"failure_point": "mcp_container_startup",
|
||||
"failure_point": "api_connection",
|
||||
"requires_operator": true,
|
||||
"reason": "FORGEJO_TOKEN not set, container cannot connect to Gitea; used dummy token",
|
||||
"reason": "GITEA_TOKEN not set, cannot connect to Gitea API",
|
||||
"recovery_steps": [
|
||||
"Set FORGEJO_TOKEN in docker/mcp-gitea/.env",
|
||||
"Restart: docker compose -f docker/mcp-gitea/docker-compose.yml up -d"
|
||||
"Set GITEA_TOKEN environment variable",
|
||||
"Verify GITEA_API_URL is correct"
|
||||
],
|
||||
"fallback_active": "REST API (gitea-client.ts)",
|
||||
"fallback_active": "Local file logging",
|
||||
"timestamp": "2026-05-08T22:23:00Z"
|
||||
} -->
|
||||
```
|
||||
|
||||
## Reference
|
||||
- Docker compose depends_on behavior: https://docs.docker.com/compose/startup-order/
|
||||
- MCP protocol transport: https://modelcontextprotocol.io/specification/2024-11-05/architecture/transports
|
||||
- Gitea API fallback: `.kilo/shared/gitea-api.md`
|
||||
- Gitea API: `.kilo/shared/gitea-api.md`
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
# Gitea MCP Connection Skill
|
||||
|
||||
## Purpose
|
||||
Replace bash/curl Gitea API calls with native Model Context Protocol (MCP) server connection.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Agent → MCP Client → SSE Stream (port 3001) → MCP Gitea Server → Gitea API
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Start MCP Gitea Container
|
||||
```bash
|
||||
docker-compose -f docker/mcp-gitea/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
### 2. Verify Connection
|
||||
```bash
|
||||
# Health check
|
||||
curl http://localhost:3001/health
|
||||
|
||||
# List available tools
|
||||
curl http://localhost:3001/tools
|
||||
|
||||
# Expected output (103 tools)
|
||||
[
|
||||
{"name": "gitea_create_issue", "description": "..."},
|
||||
{"name": "gitea_post_comment", "description": "..."},
|
||||
{"name": "gitea_update_issue", "description": "..."},
|
||||
{"name": "gitea_get_issue", "description": "..."},
|
||||
{"name": "gitea_list_labels", "description": "..."},
|
||||
{"name": "gitea_set_labels", "description": "..."},
|
||||
{"name": "gitea_get_timeline", "description": "..."},
|
||||
{"name": "gitea_lock_issue", "description": "..."},
|
||||
{"name": "gitea_get_milestone", "description": "..."},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
## Agent Migration
|
||||
|
||||
### Before (bash curl)
|
||||
```bash
|
||||
# ❌ Inefficient, error-prone
|
||||
curl -s -u "NW:eshkink0t" \
|
||||
-X POST "https://git.softuniq.eu/api/v1/repos/UniqueSoft/APAW/issues" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"title":"...","body":"..."}'
|
||||
```
|
||||
|
||||
### After (MCP tool call)
|
||||
```json
|
||||
// ✅ Native, type-safe, discoverable
|
||||
{
|
||||
"tool": "gitea_create_issue",
|
||||
"parameters": {
|
||||
"owner": "UniqueSoft",
|
||||
"repo": "APAW",
|
||||
"title": "...",
|
||||
"body": "...",
|
||||
"labels": ["status::new"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Available MCP Tools (103 total)
|
||||
|
||||
### Issue Management
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_create_issue` | owner, repo, title, body, labels, milestone | Issue object |
|
||||
| `gitea_get_issue` | owner, repo, issue_number | Issue object |
|
||||
| `gitea_update_issue` | owner, repo, issue_number, title?, body?, state?, labels?, assignee? | Updated issue |
|
||||
| `gitea_close_issue` | owner, repo, issue_number | Closed issue |
|
||||
| `gitea_lock_issue` | owner, repo, issue_number | Locked issue |
|
||||
| `gitea_unlock_issue` | owner, repo, issue_number | Unlocked issue |
|
||||
|
||||
### Comments
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_post_comment` | owner, repo, issue_number, body | Comment object |
|
||||
| `gitea_get_comments` | owner, repo, issue_number | Comment[] |
|
||||
| `gitea_update_comment` | owner, repo, comment_id, body | Updated comment |
|
||||
|
||||
### Labels
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_list_labels` | owner, repo | Label[] |
|
||||
| `gitea_create_label` | owner, repo, name, color, description | Label |
|
||||
| `gitea_set_labels` | owner, repo, issue_number, labels | Issue |
|
||||
| `gitea_add_label` | owner, repo, issue_number, label | Issue |
|
||||
| `gitea_remove_label` | owner, repo, issue_number, label_id | void |
|
||||
|
||||
### Timeline & Events
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_get_timeline` | owner, repo, issue_number | TimelineEvent[] |
|
||||
| `gitea_parse_events` | comments[] | GNSEvent[] |
|
||||
|
||||
### Checkpoints (GNS-2)
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_get_checkpoint` | owner, repo, issue_number | Checkpoint or null |
|
||||
| `gitea_update_checkpoint` | owner, repo, issue_number, checkpoint | Updated issue |
|
||||
| `gitea_clear_checkpoint` | owner, repo, issue_number | Updated issue |
|
||||
|
||||
### Milestones
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_create_milestone` | owner, repo, title, description, due_on | Milestone |
|
||||
| `gitea_get_milestone` | owner, repo, milestone_id | Milestone |
|
||||
| `gitea_update_milestone` | owner, repo, milestone_id, title?, state?, description? | Milestone |
|
||||
| `gitea_list_milestone_issues` | owner, repo, milestone_id, state? | Issue[] |
|
||||
|
||||
### Polling
|
||||
| Tool | Parameters | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gitea_get_triggered_issues` | owner, repo, labels?, assignee?, milestone?, updated_after?, is_locked? | Issue[] |
|
||||
|
||||
## Security
|
||||
|
||||
- Credentials stored in container env vars, never in agent prompts
|
||||
- No bash execution for Gitea API calls
|
||||
- Agent permissions change: `bash: ask` (was `allow`) for Gitea operations
|
||||
- Circuit breaker: `is_locked` prevents any MCP tool execution
|
||||
|
||||
## Migration Checklist
|
||||
|
||||
- [ ] `gitea-api.md` — migrate curl examples to MCP tool calls
|
||||
- [ ] `gitea-client.ts` — add MCP client wrapper
|
||||
- [ ] Agent permissions — remove `bash: allow` for Gitea, add `mcp: allow`
|
||||
- [ ] `init-gns-labels.py` — replace API calls with `gitea_create_label` tool
|
||||
- [ ] `validate-gns-agents.py` — add MCP tool availability check
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error | Cause | Action |
|
||||
|-------|-------|--------|
|
||||
| Connection refused | MCP container not running | `docker-compose up -d` |
|
||||
| 401 Unauthorized | Token missing | Check `GITEA_TOKEN` env var |
|
||||
| 404 Not Found | Issue/label not found | Verify issue number |
|
||||
| 422 Validation | Invalid parameters | Check tool schema |
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Start container
|
||||
docker-compose -f docker/mcp-gitea/docker-compose.yml up -d
|
||||
|
||||
# Wait for health
|
||||
sleep 5
|
||||
|
||||
# Test issue creation
|
||||
curl -X POST http://localhost:3001/tools/gitea_create_issue \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"owner":"UniqueSoft","repo":"APAW","title":"MCP Test","body":"Test body"}'
|
||||
|
||||
# Test checkpoint
|
||||
curl -X POST http://localhost:3001/tools/gitea_update_checkpoint \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"owner":"UniqueSoft","repo":"APAW","issue_number":1,"checkpoint":{"version":2}}'
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- MCP Server: https://github.com/Sqcows/forgejo-mcp
|
||||
- MCP Protocol: https://modelcontextprotocol.io
|
||||
- Gitea API: https://docs.gitea.com/api
|
||||
- Docker Compose: `docker/mcp-gitea/docker-compose.yml`
|
||||
@@ -1,138 +0,0 @@
|
||||
# MCP Gitea Integration - Research Report
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Found **33 open-source MCP servers** for Gitea on GitHub. Top 3 candidates for Docker containerization identified.
|
||||
|
||||
## Evaluation Criteria
|
||||
|
||||
| Criterion | Weight | How Measured |
|
||||
|-----------|--------|--------------|
|
||||
| API Coverage | 20% | # tools, endpoints covered |
|
||||
| Docker Support | 20% | Dockerfile present, compose example |
|
||||
| Gitea Version | 15% | Compatible with Gitea 1.21+ (our instance) |
|
||||
| Auth Methods | 15% | Token, Basic, OAuth2 support |
|
||||
| Maintenance | 15% | Last commit < 3 months |
|
||||
| Stars/Community | 15% | Stars, forks, issues activity |
|
||||
|
||||
## Top Candidates
|
||||
|
||||
### 1. Sqcows/forgejo-mcp (Recommended)
|
||||
- **Language**: TypeScript
|
||||
- **Stars**: 6
|
||||
- **Last Updated**: Mar 21, 2026 (active!)
|
||||
- **Tools**: 103 (repos, issues, PRs, orgs, users, admin)
|
||||
- **Docker**: Dockerfile present
|
||||
- **Auth**: Token + Basic
|
||||
- **Gitea Version**: 1.21+ compatible
|
||||
- **Repo**: https://github.com/Sqcows/forgejo-mcp
|
||||
|
||||
**Pros**:
|
||||
- Most tools (103)
|
||||
- Active maintenance
|
||||
- Docker-ready
|
||||
- Covers repos, issues, PRs, orgs, users, admin
|
||||
|
||||
**Cons**:
|
||||
- Lower star count
|
||||
- Forgejo-focused (Gitea fork, but compatible)
|
||||
|
||||
### 2. MushroomFleet/gitea-mcp
|
||||
- **Language**: TypeScript
|
||||
- **Stars**: 10
|
||||
- **Last Updated**: Apr 7, 2026 (active!)
|
||||
- **Tools**: Issues, repos, PRs, orgs management
|
||||
- **Docker**: Unknown, likely yes
|
||||
- **Auth**: Token
|
||||
- **Gitea Version**: 1.21+
|
||||
- **Repo**: https://github.com/MushroomFleet/gitea-mcp
|
||||
|
||||
**Pros**:
|
||||
- Gitea-native (not Forgejo)
|
||||
- Higher star count
|
||||
- Recent updates
|
||||
|
||||
**Cons**:
|
||||
- Fewer tools than #1
|
||||
- Less documentation visible
|
||||
|
||||
### 3. raohwork/forgejo-mcp
|
||||
- **Language**: Go
|
||||
- **Stars**: 52
|
||||
- **Last Updated**: Oct 28, 2025 (older)
|
||||
- **Tools**: Repository management focus
|
||||
- **Docker**: Likely via multi-stage build
|
||||
- **Auth**: Token
|
||||
- **Gitea Version**: Unknown
|
||||
- **Repo**: https://github.com/raohwork/forgejo-mcp
|
||||
|
||||
**Pros**:
|
||||
- Highest stars
|
||||
- Go = smaller container
|
||||
- Performance
|
||||
|
||||
**Cons**:
|
||||
- Older, may be unmaintained
|
||||
- Repository-only focus
|
||||
- Less tool coverage
|
||||
|
||||
## Docker Integration Plan
|
||||
|
||||
### docker-compose.mcp-gitea.yml
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
mcp-gitea:
|
||||
image: sqcows/forgejo-mcp:latest
|
||||
container_name: mcp-gitea
|
||||
environment:
|
||||
GITEA_URL: https://git.softuniq.eu
|
||||
GITEA_TOKEN: ${GITEA_TOKEN}
|
||||
ports:
|
||||
- "3001:3001" # MCP SSE endpoint
|
||||
networks:
|
||||
- gns-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
## Migration Path
|
||||
|
||||
### Phase A: Setup (1 day)
|
||||
1. Clone chosen MCP server
|
||||
2. Build Docker image
|
||||
3. Test connection to git.softuniq.eu
|
||||
4. Verify issue creation via MCP tool
|
||||
|
||||
### Phase B: Agent Integration (1 day)
|
||||
1. Create `.kilo/skills/mcp-gitea-connection/SKILL.md`
|
||||
2. Update `
|
||||
|
||||
**[Report truncated]**
|
||||
|
||||
## Detailed Comparison Table
|
||||
|
||||
| Feature | Sqcows | MushroomFleet | raohwork |
|
||||
|---------|--------|---------------|----------|
|
||||
| Stars | 6 | 10 | 52 |
|
||||
| Language | TypeScript | TypeScript | Go |
|
||||
| Docker | ✅ | ✅ | ✅ |
|
||||
| # Tools | 103 | ~30 | ~15 |
|
||||
| Issues API | ✅ | ✅ | ❌ |
|
||||
| PRs API | ✅ | ✅ | ✅ |
|
||||
| Org API | ✅ | ❌ | ❌ |
|
||||
| Admin API | ✅ | ❌ | ❌ |
|
||||
| Auth: Token | ✅ | ✅ | ✅ |
|
||||
| Auth: Basic | ✅ | ❌ | ❌ |
|
||||
| Last Updated | Mar 21 | Apr 7 | Oct 28 |
|
||||
| Maintenance | Active | Active | Stale |
|
||||
|
||||
## Recommendation
|
||||
|
||||
**Use Sqcows/forgejo-mcp** — most comprehensive API coverage (103 tools), active maintenance, Docker-ready.
|
||||
|
||||
**Fallback**: MushroomFleet/gitea-mcp if Forgejo compatibility issues arise.
|
||||
Reference in New Issue
Block a user