@goonnguyen/human-mcp 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.claude/agents/project-manager.md +2 -2
  2. package/.env.example +28 -1
  3. package/.github/workflows/publish.yml +43 -6
  4. package/.opencode/agent/code-reviewer.md +142 -0
  5. package/.opencode/agent/debugger.md +74 -0
  6. package/.opencode/agent/docs-manager.md +119 -0
  7. package/.opencode/agent/git-manager.md +60 -0
  8. package/.opencode/agent/planner-researcher.md +100 -0
  9. package/.opencode/agent/project-manager.md +113 -0
  10. package/.opencode/agent/system-architecture.md +200 -0
  11. package/.opencode/agent/tester.md +96 -0
  12. package/.opencode/agent/ui-ux-developer.md +97 -0
  13. package/.opencode/command/cook.md +7 -0
  14. package/.opencode/command/debug.md +10 -0
  15. package/.opencode/command/fix/ci.md +8 -0
  16. package/.opencode/command/fix/fast.md +5 -0
  17. package/.opencode/command/fix/hard.md +7 -0
  18. package/.opencode/command/fix/test.md +16 -0
  19. package/.opencode/command/git/cm.md +5 -0
  20. package/.opencode/command/git/cp.md +4 -0
  21. package/.opencode/command/plan/ci.md +12 -0
  22. package/.opencode/command/plan/two.md +13 -0
  23. package/.opencode/command/plan.md +10 -0
  24. package/.opencode/command/test.md +7 -0
  25. package/.opencode/command/watzup.md +8 -0
  26. package/CHANGELOG.md +21 -0
  27. package/CLAUDE.md +5 -3
  28. package/QUICKSTART.md +3 -3
  29. package/README.md +551 -20
  30. package/bun.lock +275 -3
  31. package/dist/index.js +71091 -17256
  32. package/docs/README.md +51 -0
  33. package/docs/codebase-structure-architecture-code-standards.md +17 -5
  34. package/docs/project-overview-pdr.md +37 -21
  35. package/docs/project-roadmap.md +494 -0
  36. package/human-mcp.png +0 -0
  37. package/package.json +9 -1
  38. package/plans/002-sse-fallback-http-transport-plan.md +161 -0
  39. package/plans/003-fix-test-infrastructure-and-ci-plan.md +699 -0
  40. package/plans/003-http-transport-local-file-access-plan.md +880 -0
  41. package/plans/004-fix-typescript-compilation-errors-plan.md +388 -0
  42. package/plans/005-comprehensive-test-infrastructure-fix-plan.md +854 -0
  43. package/src/index.ts +2 -0
  44. package/src/tools/eyes/index.ts +7 -7
  45. package/src/tools/eyes/processors/image.ts +90 -0
  46. package/src/transports/http/file-interceptor.ts +134 -0
  47. package/src/transports/http/routes.ts +165 -4
  48. package/src/transports/http/server.ts +64 -14
  49. package/src/transports/http/session.ts +11 -3
  50. package/src/transports/http/sse-routes.ts +210 -0
  51. package/src/transports/index.ts +11 -6
  52. package/src/transports/types.ts +13 -0
  53. package/src/utils/cloudflare-r2.ts +107 -0
  54. package/src/utils/config.ts +26 -0
  55. package/tests/integration/http-transport-files.test.ts +190 -0
  56. package/tests/integration/server.test.ts +4 -1
  57. package/tests/integration/sse-transport.test.ts +142 -0
  58. package/tests/setup.ts +45 -1
  59. package/tests/types/api-responses.ts +35 -0
  60. package/tests/types/test-types.ts +105 -0
  61. package/tests/unit/cloudflare-r2.test.ts +118 -0
  62. package/tests/unit/eyes-analyze.test.ts +150 -0
  63. package/tests/unit/formatters.test.ts +1 -1
  64. package/tests/unit/sse-routes.test.ts +92 -0
  65. package/tests/utils/error-scenarios.ts +198 -0
  66. package/tests/utils/index.ts +3 -0
  67. package/tests/utils/mock-helpers.ts +99 -0
  68. package/tests/utils/test-data-generators.ts +217 -0
  69. package/tests/utils/test-server-manager.ts +172 -0
  70. package/tsconfig.json +1 -1
  71. package/plans/reports/001-from-qa-engineer-to-development-team-test-suite-report.md +0 -188
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goonnguyen/human-mcp",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Human MCP: Bringing Human Capabilities to Coding Agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -14,6 +14,8 @@
14
14
  "inspector": "mcp-inspector stdio -- bun run src/index.ts"
15
15
  },
16
16
  "dependencies": {
17
+ "@aws-sdk/client-s3": "^3.888.0",
18
+ "@aws-sdk/s3-request-presigner": "^3.888.0",
17
19
  "@google/generative-ai": "^0.21.0",
18
20
  "@modelcontextprotocol/sdk": "^1.4.0",
19
21
  "compression": "^1.8.1",
@@ -21,7 +23,10 @@
21
23
  "express": "^5.1.0",
22
24
  "fluent-ffmpeg": "^2.1.3",
23
25
  "helmet": "^8.1.0",
26
+ "mime-types": "^3.0.1",
27
+ "multer": "^2.0.2",
24
28
  "sharp": "^0.33.0",
29
+ "uuid": "^13.0.0",
25
30
  "zod": "^3.23.0"
26
31
  },
27
32
  "devDependencies": {
@@ -35,6 +40,9 @@
35
40
  "@types/cors": "^2.8.19",
36
41
  "@types/express": "^5.0.3",
37
42
  "@types/fluent-ffmpeg": "^2.1.26",
43
+ "@types/mime-types": "^3.0.1",
44
+ "@types/multer": "^2.0.0",
45
+ "@types/uuid": "^10.0.0",
38
46
  "semantic-release": "^24.2.7",
39
47
  "typescript": "^5.6.0"
40
48
  },
@@ -0,0 +1,161 @@
1
+ # Implementation Plan: SSE Fallback for HTTP Transport
2
+
3
+ ## Executive Summary
4
+ - Problem Statement
5
+ - We must support legacy MCP clients that only implement the deprecated HTTP+SSE transport while keeping the current Streamable HTTP transport as the default. Current server only supports Streamable HTTP (plus SSE notifications on the same /mcp route), so older clients cannot connect.
6
+ - Proposed Solution (KISS)
7
+ - Add an optional, isolated SSE transport fallback with two endpoints (/sse for GET event stream, /messages for POST messages) alongside the existing Streamable HTTP routes. Keep transports segregated per session to prevent mixing.
8
+ - Resource Requirements
9
+ - 1 backend TS engineer, 0.5 QA engineer, 0.25 DevOps for deploy hooks
10
+ - Timeline (realistic)
11
+ - 1.5–2 weeks including tests, documentation, and hardening
12
+
13
+ ## Architecture Overview
14
+ - System Components (minimal viable set)
15
+ - Existing Streamable HTTP transport (unchanged)
16
+ - New SSE fallback endpoints backed by SDK’s SSEServerTransport
17
+ - Lightweight in-memory registry for SSE sessions (separate from Streamable HTTP sessions)
18
+ - Security middleware reuse (CORS, DNS-rebinding, secret auth)
19
+ - Data Flow (simplified)
20
+ - Legacy client: GET /sse opens SSE stream -> server sends notifications over SSE -> client POSTs JSON-RPC messages to /messages with sessionId -> server routes through SSEServerTransport
21
+ - Modern client: Uses existing /mcp Streamable HTTP POST/GET/DELETE endpoints
22
+ - Integration Points (essential only)
23
+ - SDK: @modelcontextprotocol/sdk/server/sse.js (SSEServerTransport)
24
+ - Existing Express app and middleware
25
+
26
+ ## Implementation Phases
27
+
28
+ ### Phase 1: Design and Config Wiring (Day 1–2)
29
+ - Add config flags (default off to obey YAGNI):
30
+ - HttpTransportConfig.enableSseFallback?: boolean (default false)
31
+ - HttpTransportConfig.ssePaths?: { stream: string; message: string } (defaults: stream='/sse', message='/messages')
32
+ - Reuse existing security and CORS config
33
+ - Non-goals: No persistent session store for SSE initially (YAGNI). In-memory only, like Streamable HTTP by default.
34
+
35
+ ### Phase 2: SSE Routes and Session Handling (Day 3–6)
36
+ - Add router when enableSseFallback=true
37
+ - GET {ssePaths.stream}
38
+ - Create new SSEServerTransport; connect to McpServer
39
+ - Store in sseTransports map keyed by transport.sessionId
40
+ - On res close, delete entry and close transport
41
+ - Return 405 if sessionMode === 'stateless'
42
+ - POST {ssePaths.message}?sessionId=...
43
+ - Look up sseTransports[sessionId]
44
+ - If found: transport.handlePostMessage(req, res, req.body)
45
+ - Else: 400 no transport for sessionId
46
+ - Transport segregation rules (must-have)
47
+ - Do not share sessions across transports
48
+ - Do not allow mixing: Streamable HTTP sessionId cannot be used on SSE endpoints and vice versa
49
+ - Observability
50
+ - Add concise logs for session create/close, message counts, and error paths
51
+
52
+ ### Phase 3: Security, CORS, and Browser Compatibility (Day 7)
53
+ - CORS
54
+ - Ensure Mcp-Session-Id is exposed (already done) and allowed headers include mcp-session-id
55
+ - DNS-rebinding
56
+ - Reuse middleware; align allowedHosts with Streamable HTTP
57
+ - Authentication (optional)
58
+ - Reuse secret-based Bearer token if configured
59
+
60
+ ### Phase 4: Tests and Compatibility (Day 8–10)
61
+ - Unit tests
62
+ - SSE registry add/remove
63
+ - Route guards for stateless mode and missing sessionId
64
+ - Integration tests
65
+ - Happy path: GET /sse -> POST /messages -> tool call success
66
+ - Bad path: POST /messages with unknown sessionId -> 400
67
+ - Mix defense: Using Streamable HTTP sessionId on SSE -> 400; SSE sessionId on /mcp -> 400
68
+ - CORS headers present where applicable
69
+ - Backwards-compat verification
70
+ - Run SDK example client streamableHttpWithSseFallbackClient to confirm legacy connectivity
71
+
72
+ ### Phase 5: Documentation and Rollout (Day 11–12)
73
+ - Update docs/system-architecture-blueprint.md with transport compatibility and routing diagram
74
+ - Update README and docs/codebase-summary.md references where strictly needed
75
+ - Add configuration examples to .env.example
76
+ - Ship behind feature flag (enableSseFallback=false by default)
77
+
78
+ ## Detailed Design
79
+
80
+ ### Config surface (TypeScript, illustrative)
81
+ - HttpTransportConfig additions:
82
+ - enableSseFallback?: boolean
83
+ - ssePaths?: { stream: string; message: string }
84
+ - Defaults:
85
+ - enableSseFallback: false
86
+ - ssePaths: { stream: '/sse', message: '/messages' }
87
+
88
+ ### Express wiring
89
+ - In src/transports/http/server.ts
90
+ - After existing /mcp router registration, check config.enableSseFallback and mount SSE router
91
+ - SSE Router (new):
92
+ - Keeps local Map<string, SSEServerTransport> sseTransports
93
+ - GET stream path: instantiate SSEServerTransport(streamPath, res) or new SSEServerTransport(baseUrl?) per SDK, connect server, onclose cleanup
94
+ - POST message path: route body to transport.handlePostMessage
95
+ - Stateless mode guard
96
+ - Both SSE endpoints respond 405 in stateless mode with MCP-compliant JSON-RPC error structure
97
+
98
+ ### Session and mixing policy
99
+ - Keep streamable transports in SessionManager (existing Map)
100
+ - Keep SSE transports in a separate in-router map
101
+ - Reject requests that attempt to cross-use session IDs across transports
102
+ - Simple check: If sessionId format matches a known SSE session, deny Streamable HTTP use; and vice versa
103
+
104
+ ### Error handling
105
+ - Reuse existing handleError for JSON errors (POST)
106
+ - For GET SSE stream, ensure try/catch logs and res end on exception; avoid double writes
107
+
108
+ ### Health and readiness
109
+ - /health remains as-is; optionally include sseFallback: enabled/disabled flag for diagnostics
110
+
111
+ ## Risk Assessment & Mitigation
112
+ - High-Risk Items
113
+ - Transport mixing bugs leading to undefined state
114
+ - Mitigation: Clear separations and explicit guards; unit tests
115
+ - Resource leaks on SSE disconnection
116
+ - Mitigation: res.on('close') -> transport.close(); map cleanup; add timeouts
117
+ - Browser CORS issues
118
+ - Mitigation: Tests validating exposed headers and preflight handling
119
+ - Probable Failure Points
120
+ - Missing sessionId on POST /messages
121
+ - Misconfigured allowedHosts blocking legitimate access
122
+ - Legacy client behavior variance
123
+ - Mitigation Strategies
124
+ - Strict validation and explicit 4xx errors
125
+ - Feature flag default off; progressive rollout
126
+ - Add structured logs to quickly triage
127
+
128
+ ## Success Criteria
129
+ - Measurable Outcomes
130
+ - Legacy SDK SSE client connects and completes a tool call end-to-end
131
+ - No memory leaks after 1k connect/disconnect cycles in test harness
132
+ - Mix attempts are rejected with clear 400s
133
+ - Performance Benchmarks
134
+ - SSE connection setup < 50ms local; message roundtrip comparable to current HTTP
135
+ - Quality Gates
136
+ - All unit/integration tests pass; CORS/headers verified; security middleware applied
137
+
138
+ ## Out-of-Scope (YAGNI)
139
+ - External/persistent session stores for SSE (revisit if horizontal scaling demand appears)
140
+ - OAuth on SSE endpoints (keep secret-based bearer only if configured)
141
+ - Metrics backend beyond logs
142
+
143
+ ## Implementation Checklist
144
+ - Config additions and defaults
145
+ - SSE router with GET stream and POST message endpoints
146
+ - Segregated SSE session map with lifecycle cleanup
147
+ - Guards for stateless mode and mix prevention
148
+ - Tests: unit + integration
149
+ - Docs updated: blueprint + README + .env.example
150
+ - Rollout: enabled via flag per environment
151
+
152
+ ## Realistic Timeline
153
+ - Week 1
154
+ - Config + routes + session handling + basic tests
155
+ - Week 2
156
+ - Hardening, security validations, compatibility tests, docs, release prep
157
+
158
+ ## References (SDK docs/examples)
159
+ - Typescript SDK SSE server example and compatibility patterns
160
+ - Client with SSE fallback example
161
+ - CORS header requirements for MCP