initial commit after one day coding agent session
This commit is contained in:
commit
372af75b90
88 changed files with 22694 additions and 0 deletions
181
docs/HTTP_TRANSPORT.md
Normal file
181
docs/HTTP_TRANSPORT.md
Normal 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
1598
docs/architecture1.md
Normal file
File diff suppressed because it is too large
Load diff
374
docs/development-methodology.md
Normal file
374
docs/development-methodology.md
Normal 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
3156
docs/todo.md
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue