initial commit after one day coding agent session

This commit is contained in:
Hans Aschauer 2026-02-07 07:45:57 +01:00
commit 372af75b90
88 changed files with 22694 additions and 0 deletions

181
docs/HTTP_TRANSPORT.md Normal file
View file

@ -0,0 +1,181 @@
# HTTP Transport Configuration Example
This example shows how to configure MCP-Forge to connect to external HTTP-based MCP servers.
## Configuration File
```yaml
# config.yaml
server:
host: localhost
port: 3000
podman_socket: /run/user/1000/podman/podman.sock
security:
audit_log: ./logs/audit.log
enforce_resource_limits: true
allow_network: false
execution:
default_backend: simple
default_timeout: 300
max_timeout: 1800
default_memory: 512m
max_memory: 2g
base_image: docker.io/library/python:3.13-slim
environment_builder:
enabled: true
uv_cache_path: ./cache/uv
max_packages_per_build: 50
max_build_time: 600
max_image_size: 2147483648
max_concurrent_builds: 3
build_rate_limit:
requests: 10
period: 60
package_validation:
use_allowlist: true
allowlist_path: ./config/allowlist.txt
blocklist_path: ./config/blocklist.txt
require_approval_patterns: []
# Connect to external MCP servers
mcp_tools:
# HTTP-based MCP server
remote_api:
transport: http
url: http://localhost:8006/mcp
headers:
Authorization: "Bearer your-token-here"
X-Custom-Header: "value"
# SSE-based MCP server
sse_service:
transport: sse
url: http://localhost:9000/events
headers:
Authorization: "Bearer your-token-here"
# Traditional stdio-based MCP server (still supported)
filesystem:
transport: stdio # default, can be omitted
command: uvx
args: [mcp-server-filesystem, /path/to/workspace]
env:
SOME_VAR: value
```
## Transport Types
### 1. HTTP Transport
Used for HTTP-based MCP servers that communicate via HTTP requests.
```yaml
remote_api:
transport: http
url: http://localhost:8006/mcp
headers:
Authorization: "Bearer token123"
Content-Type: "application/json"
```
**Required:**
- `url`: HTTP endpoint URL
**Optional:**
- `headers`: HTTP headers (dict)
### 2. SSE Transport
Used for Server-Sent Events (SSE) based MCP servers.
```yaml
sse_service:
transport: sse
url: http://localhost:9000/events
headers:
Authorization: "Bearer token123"
```
**Required:**
- `url`: SSE endpoint URL
**Optional:**
- `headers`: HTTP headers (dict)
### 3. Stdio Transport (Default)
Traditional command-based MCP servers.
```yaml
filesystem:
transport: stdio # default, can be omitted
command: uvx
args: [mcp-server-filesystem, /workspace]
env:
PATH: /usr/bin
```
**Required:**
- `command`: Executable command
**Optional:**
- `args`: Command arguments (list)
- `env`: Environment variables (dict)
## Running the Server
```bash
# Start with HTTP transport configuration
uv run mcp-forge --config config.yaml
# Or with SSE transport
uv run mcp-forge --config config.yaml --transport sse --host 0.0.0.0 --port 8080
```
## Client Connection
Once the server is running, MCP clients can connect using the configured transport:
```python
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
# Connect to MCP-Forge server via HTTP
transport = StreamableHttpTransport(url="http://localhost:3000/mcp")
client = Client(transport)
async with client:
# List available tools (from all configured MCP servers)
tools = await client.list_tools()
print(tools)
```
## Testing the Connection
You can test your HTTP transport configuration using curl:
```bash
# Test HTTP endpoint
curl -X POST http://localhost:8006/mcp \
-H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```
## Troubleshooting
### Connection Refused
- Verify the external MCP server is running
- Check the URL and port are correct
- Ensure firewall rules allow the connection
### Authentication Errors
- Verify the authorization header is correct
- Check if the external server requires specific headers
### Tool Not Found
- Ensure the external MCP server exposes the expected tools
- Check the server logs for any errors

1598
docs/architecture1.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,374 @@
# AI-Assisted Software Development: A Methodology for Rapid, Test-Driven Implementation
## Abstract
This document describes a development methodology that combines architectural planning, test-driven development, and AI-assisted implementation to achieve rapid yet robust software construction. Using the mcp-forge project as a case study (5,325 lines of production code developed in one day), we demonstrate how structured planning and clear acceptance criteria enable effective human-AI collaboration while maintaining code quality and architectural integrity.
## Introduction
Traditional software development faces a fundamental tension: moving fast often compromises quality, while maintaining quality slows development. AI-assisted development promises to resolve this tension, but requires methodological discipline to avoid producing technically functional yet architecturally weak systems.
The methodology described here was validated through building mcp-forge, a production-grade secure Python execution server with MCP protocol integration, achieving:
- **5,325 lines of code** in a single development session
- **388 passing tests** (100% test coverage of core functionality)
- **Zero architectural rework** required post-implementation
- **Production-ready security** (container isolation, audit logging, resource limits)
## Methodology Overview
The approach consists of four sequential phases, each building upon the previous:
```
1. Architecture Design
2. Test-Driven Work Planning
3. Guided AI Implementation
4. Integration Validation
```
### Phase 1: Architecture-First Planning
**Objective**: Establish system structure before writing any code.
**Process**:
1. Create an architecture document (`architecture.md`) containing:
- System overview and objectives
- Component breakdown with responsibilities
- Data flow diagrams
- Technology stack decisions
- Security considerations
- Integration points
2. Focus on **interfaces over implementation**:
- Define contracts between components
- Specify data structures
- Identify abstraction boundaries
3. Make **technology choices explicit**:
- State assumptions and constraints
- Document why alternatives were rejected
- Note potential technical risks
**Example from mcp-forge**:
```markdown
## Component: Execution Backend
**Responsibility**: Execute Python code in isolated containers
**Interface**:
- `execute(code: str, timeout: int, memory: str) -> ExecutionResult`
**Implementation Options**:
1. Simple: Stateless execution (chosen for MVP)
2. Jupyter: Stateful sessions (Phase 2)
**Security Requirements**:
- No network access by default
- Resource limits enforced
- Container isolation mandatory
```
**Key Principle**: The architecture document serves as a contract between human designer and AI implementer. Ambiguity here multiplies into implementation uncertainty.
### Phase 2: Test-Driven Work Planning
**Objective**: Convert architecture into actionable tasks with verifiable completion criteria.
**Process**:
1. Create a development plan (`todo.md`) structured as:
- Phases (major milestones)
- Tasks (implementable units)
- Acceptance criteria (objective success metrics)
2. **Enforce bottom-up development**:
- Start with foundational components (no dependencies)
- Build progressively toward integration
- Each layer tested before next begins
3. **Write acceptance criteria that prevent shortcuts**:
- Require specific test coverage
- Mandate error handling
- Specify edge cases
- Include performance requirements
4. **Make testing non-optional**:
- Every task includes "Tests written and passing"
- Integration tasks require integration tests
- No task complete without verification
**Example Task Structure**:
```markdown
## Phase 1: Foundation
### Task 1.1: Configuration Schema
- [ ] Create Pydantic models for all config sections
- [ ] Validate YAML parsing
- [ ] Handle missing/invalid configurations
- [ ] **Tests**: Config validation tests (>90% coverage)
- [ ] **Acceptance**: All edge cases handled, no runtime config errors
### Task 1.2: Podman Client Wrapper
- [ ] Implement container create/start/stop/remove
- [ ] Handle connection errors gracefully
- [ ] Add timeout protection
- [ ] **Tests**: Unit tests with mocked Podman API
- [ ] **Acceptance**: All Podman operations covered, error paths tested
```
**Anti-pattern Warning**: Vague criteria like "Implement X" or "Make Y work" lead to incomplete implementations. The AI will declare success prematurely without specific verification requirements.
### Phase 3: Guided AI Implementation
**Objective**: Leverage AI for rapid implementation while maintaining human control over design decisions.
**Human Role**:
- **Architect**: Make design choices when ambiguity exists
- **Reviewer**: Validate implementations against architecture
- **Course-corrector**: Intervene when AI diverges from requirements
- **Preference-setter**: Override AI's default choices when alternatives better suit your needs
**AI Role**:
- **Implementer**: Write code following specifications
- **Test-writer**: Create comprehensive test coverage
- **Problem-solver**: Debug issues and propose solutions
- **Documenter**: Generate docstrings and comments
**Collaboration Pattern**:
```
Human: [Reviews architecture] → [Creates task with acceptance criteria]
AI: [Implements task] → [Writes tests] → [Runs tests]
Human: [Validates approach] → [Accepts OR provides feedback]
AI: [Refines if needed] → [Marks task complete]
```
**When to Intervene**:
1. **Design Disagreement**: AI chooses approach that conflicts with architecture
- *Example*: "Use threads instead of async for the bridge server"
- *Action*: Redirect to architectural decision
2. **Preference Mismatch**: Implementation works but doesn't match your style
- *Example*: "I prefer explicit error handling over exceptions here"
- *Action*: Request specific changes
3. **Incomplete Coverage**: AI claims completion but acceptance criteria not met
- *Example*: "Task complete" but edge case tests missing
- *Action*: Point to specific uncovered scenarios
4. **Over-engineering**: AI adds unnecessary complexity
- *Example*: Elaborate caching when simple lookup sufficient
- *Action*: Request simplification
**When NOT to Intervene**:
- Implementation details within architectural constraints
- Naming conventions (unless critical to domain)
- Code organization within modules
- Test structure (if coverage is adequate)
### Phase 4: Integration Validation
**Objective**: Verify components work together as designed.
**Trigger**: As soon as two or more components interact.
**Process**:
1. **Write integration tests immediately**:
```python
def test_execute_with_audit_logging():
"""Integration: Execution + Audit"""
result = backend.execute(code="print('test')")
assert result.success
# Verify audit log entry created
logs = audit_logger.get_recent()
assert any(log.event_type == "EXECUTION" for log in logs)
```
2. **Test failure paths**:
- Network errors during MCP communication
- Container crashes during execution
- Resource limit violations
3. **Validate end-to-end flows**:
- Complete user scenarios from entry to exit
- Cross-component data flow
- State consistency across boundaries
4. **Performance validation**:
- Measure actual execution times
- Verify resource cleanup
- Check memory leaks
**Critical Insight**: Unit tests verify components work in isolation; integration tests verify your architecture is correct. Both are mandatory.
## Case Study: MCP Tool Injection Feature
This feature demonstrates the methodology in practice:
### Architecture Decision
```markdown
**Requirement**: Python code in containers must call rag-mcp tools
**Design**: Unix socket bridge
- Bridge server runs on host
- Socket mounted into containers
- Python wrapper functions generated dynamically
- JSON-RPC over socket
```
### Task Breakdown
```markdown
1. MCPClientManager: Connect to external MCP servers
2. ToolBridgeServer: Unix socket server forwarding calls
3. ToolInjectionGenerator: Generate Python wrapper code
4. Integration: Volume mounting + code injection
```
### Guided Implementation
**Iteration 1**: AI used threading for bridge server
- **Human intervention**: "Use asyncio instead, server already async"
- **Result**: Full async rewrite
**Iteration 2**: Root() serialization returned empty dicts
- **AI debugging**: Discovered FastMCP wraps data in Root objects
- **Solution**: Parse from `content[0].text` instead
- **Human validation**: "Test with real rag-mcp call"
**Iteration 3**: Integration test
```python
def test_tool_injection_end_to_end():
result = execute_python(
code='''
docs = browse_documents(page_size=2)
print(f"Retrieved {len(docs)} documents")
''',
mcp_tools=['browse_documents']
)
assert "Retrieved 2 documents" in result.stdout
```
**Result**: Working in 2 seconds per call, 100 records retrieved without context pollution.
## Benefits and Limitations
### Benefits
1. **Speed**: 5,000+ LOC in one day without sacrificing quality
2. **Quality**: Test-driven approach forces correctness
3. **Architecture**: Planning phase prevents structural rework
4. **Maintainability**: Clear separation of concerns, well-documented
5. **Flexibility**: Easy to adjust during development (change architecture → update tasks → re-implement)
### Limitations
1. **Requires Domain Knowledge**: Human must understand the problem space
- *Mitigated by*: AI can explain concepts, but cannot design unfamiliar systems
2. **Architecture Skills Critical**: Poor initial design leads to rework
- *Mitigated by*: Start with high-level design, refine before implementation
3. **Acceptance Criteria Must Be Precise**: Vague criteria → incomplete implementation
- *Mitigated by*: Include specific tests and edge cases in task descriptions
4. **AI Can't Resolve Ambiguity**: Will make assumptions that may not align with intent
- *Mitigated by*: Review implementations actively, provide feedback early
### Comparison with Traditional Development
| Aspect | Traditional | This Methodology | Speedup |
|--------|------------|------------------|---------|
| Planning | 1-2 days | 2-3 hours | 3-4x |
| Implementation | 2-3 weeks | 1 day | 10-15x |
| Testing | 2-3 days | Concurrent | 2-3x |
| Documentation | 1-2 days | Concurrent | ∞ |
| **Total** | **3-4 weeks** | **1-2 days** | **15-20x** |
*Note: Assumes experienced developer familiar with domain*
## Best Practices
### DO:
1. **Invest in architecture**: 2-3 hours planning saves days of rework
2. **Write specific acceptance criteria**: Include edge cases, error conditions
3. **Test continuously**: Don't accumulate untested code
4. **Intervene early**: Small course corrections prevent large detours
5. **Document decisions**: Capture "why" not just "what"
### DON'T:
1. **Skip planning**: "Start coding and figure it out" fails with AI
2. **Accept vague completions**: AI will claim success too early
3. **Batch testing**: Test each component before building next
4. **Over-specify implementation**: Allow AI freedom within constraints
5. **Ignore integration testing**: Unit tests alone miss architectural issues
## Applicability
This methodology works best for:
### Ideal Projects:
- ✅ Well-defined requirements
- ✅ Known technology stack
- ✅ Experienced human architect
- ✅ Clear success criteria
- ✅ 1,000-10,000 LOC scale
### Less Suitable For:
- ❌ Research/exploratory projects
- ❌ Novel algorithm development
- ❌ UI/UX heavy applications
- ❌ Undefined requirements
- ❌ Extreme performance optimization
## Future Directions
Potential methodology enhancements:
1. **Formal Verification**: Use AI to generate formal specifications from architecture
2. **Automated Architecture Validation**: Check implementations against architectural constraints
3. **Progressive Refinement**: Start with high-level design, AI proposes detailed architecture
4. **Multi-Agent Collaboration**: Separate AI agents for architecture, implementation, testing
## Conclusion
AI-assisted development can achieve 10-20x speedups over traditional development when combined with:
1. Upfront architectural planning
2. Test-driven task breakdown
3. Human oversight on design decisions
4. Continuous integration validation
The key insight is that **AI excels at implementation but requires human guidance on architecture**. By clearly separating these concerns and establishing objective acceptance criteria, we can leverage AI's speed while maintaining human control over system design.
The mcp-forge case study demonstrates this is not theoretical: 5,325 lines of production-quality code, fully tested, with zero architectural rework, in a single day of development. This represents a paradigm shift in how software can be built.
## References
**Project**: mcp-forge - Secure Python Execution Server with MCP Support
- **Repository**: [URL]
- **LOC**: 5,325 (source), 388 tests
- **Development Time**: 1 day (single human + AI)
- **Technology**: Python, FastMCP, Podman, asyncio
- **Complexity**: Multi-component system with security, async I/O, container orchestration
**Artifacts**:
- `docs/architecture1.md`: Initial architecture document
- `docs/todo.md`: Test-driven task breakdown
- `src/`: Implementation following architecture
- `tests/`: 388 tests with >90% coverage
---
*Document Version*: 1.0
*Date*: February 6, 2026
*Author*: Based on mcp-forge development experience

3156
docs/todo.md Normal file

File diff suppressed because it is too large Load diff