This commit completes Beat 1 of the SequentialThinkingForCHORUS implementation, providing a functional plaintext skeleton for the age-encrypted wrapper. ## Deliverables ### 1. Main Wrapper Entry Point - `cmd/seqthink-wrapper/main.go`: HTTP server on :8443 - Configuration loading from environment variables - Graceful shutdown handling - MCP server readiness checking with timeout ### 2. MCP Client Package - `pkg/seqthink/mcpclient/client.go`: HTTP client for MCP server - Communicates with MCP server on localhost:8000 - Health check endpoint - Tool call endpoint with 120s timeout ### 3. Proxy Server Package - `pkg/seqthink/proxy/server.go`: HTTP handlers for wrapper - Health and readiness endpoints - Tool call proxy (plaintext for Beat 1) - SSE endpoint placeholder - Metrics endpoint integration ### 4. Observability Package - `pkg/seqthink/observability/logger.go`: Structured logging with zerolog - `pkg/seqthink/observability/metrics.go`: Prometheus metrics - Counters for requests, errors, decrypt/encrypt failures, policy denials - Request duration histogram ### 5. Docker Infrastructure - `deploy/seqthink/Dockerfile`: Multi-stage build - `deploy/seqthink/entrypoint.sh`: Startup orchestration - `deploy/seqthink/mcp_stub.py`: Minimal MCP server for testing ### 6. Build System Integration - Updated `Makefile` with `build-seqthink` target - Uses GOWORK=off and -mod=mod for clean builds - `docker-seqthink` target for container builds ## Testing Successfully builds with: ``` make build-seqthink ``` Binary successfully starts and waits for MCP server connection. ## Next Steps Beat 2 will add: - Age encryption/decryption (pkg/seqthink/ageio) - Content-Type: application/age enforcement - SSE streaming with encrypted frames - Golden tests for crypto round-trips 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Sequential Thinking MCP Server Stub (Beat 1)
|
|
|
|
This is a minimal implementation for testing the wrapper infrastructure.
|
|
In later beats, this will be replaced with the full Sequential Thinking MCP server.
|
|
"""
|
|
|
|
from fastapi import FastAPI, HTTPException
|
|
from pydantic import BaseModel
|
|
from typing import Dict, Any, Optional
|
|
import uvicorn
|
|
|
|
app = FastAPI(title="Sequential Thinking MCP Server Stub")
|
|
|
|
|
|
class ToolRequest(BaseModel):
|
|
tool: str
|
|
payload: Dict[str, Any]
|
|
|
|
|
|
class ToolResponse(BaseModel):
|
|
result: Optional[Any] = None
|
|
error: Optional[str] = None
|
|
|
|
|
|
@app.get("/health")
|
|
async def health():
|
|
"""Health check endpoint"""
|
|
return {"status": "ok"}
|
|
|
|
|
|
@app.post("/mcp/tool")
|
|
async def call_tool(request: ToolRequest) -> ToolResponse:
|
|
"""
|
|
Tool call endpoint - stub implementation
|
|
|
|
In Beat 1, this just echoes back the request to verify the wrapper works.
|
|
Later beats will implement the actual Sequential Thinking logic.
|
|
"""
|
|
if request.tool != "mcp__sequential-thinking__sequentialthinking":
|
|
return ToolResponse(
|
|
error=f"Unknown tool: {request.tool}"
|
|
)
|
|
|
|
# Stub response for Sequential Thinking tool
|
|
payload = request.payload
|
|
thought_number = payload.get("thoughtNumber", 1)
|
|
total_thoughts = payload.get("totalThoughts", 5)
|
|
thought = payload.get("thought", "")
|
|
next_thought_needed = payload.get("nextThoughtNeeded", True)
|
|
|
|
return ToolResponse(
|
|
result={
|
|
"thoughtNumber": thought_number,
|
|
"totalThoughts": total_thoughts,
|
|
"thought": thought,
|
|
"nextThoughtNeeded": next_thought_needed,
|
|
"message": "Beat 1 stub - Sequential Thinking not yet implemented"
|
|
}
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
uvicorn.run(
|
|
app,
|
|
host="127.0.0.1",
|
|
port=8000,
|
|
log_level="info"
|
|
)
|