@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
@@ -0,0 +1,172 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { startHttpTransport } from "../../src/transports/http/server.js";
3
+ import type { HttpTransportConfig, HttpServerHandle } from "../../src/transports/types.js";
4
+
5
+ export class TestServerManager {
6
+ private servers: Map<number, HttpServerHandle> = new Map();
7
+ private usedPorts: Set<number> = new Set();
8
+
9
+ /**
10
+ * Get a random available port for testing using OS-level port checking
11
+ */
12
+ async getAvailablePort(): Promise<number> {
13
+ // Try sequential ports starting from a random high port
14
+ const basePort = 4000 + Math.floor(Math.random() * 1000);
15
+ const maxAttempts = 50;
16
+
17
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
18
+ const port = basePort + attempt;
19
+
20
+ if (!this.usedPorts.has(port) && await this.isPortAvailable(port)) {
21
+ this.usedPorts.add(port);
22
+ return port;
23
+ }
24
+ }
25
+
26
+ throw new Error(`Unable to find available port after ${maxAttempts} attempts (tried ${basePort} to ${basePort + maxAttempts - 1})`);
27
+ }
28
+
29
+ /**
30
+ * Check if a port is available using Node.js net module
31
+ */
32
+ private async isPortAvailable(port: number): Promise<boolean> {
33
+ return new Promise((resolve) => {
34
+ const net = require('net');
35
+ const server = net.createServer();
36
+
37
+ server.listen(port, '127.0.0.1', () => {
38
+ server.close(() => {
39
+ resolve(true);
40
+ });
41
+ });
42
+
43
+ server.on('error', () => {
44
+ resolve(false);
45
+ });
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Start a test server with the given configuration
51
+ */
52
+ async startTestServer(config: Partial<HttpTransportConfig> = {}): Promise<{
53
+ server: HttpServerHandle;
54
+ port: number;
55
+ baseUrl: string;
56
+ }> {
57
+ const port = await this.getAvailablePort();
58
+
59
+ // Create a basic MCP server for testing
60
+ const mcpServer = new McpServer(
61
+ {
62
+ name: "test-server",
63
+ version: "1.0.0"
64
+ },
65
+ {
66
+ capabilities: {
67
+ tools: {}
68
+ }
69
+ }
70
+ );
71
+
72
+ const serverConfig: HttpTransportConfig = {
73
+ port,
74
+ host: "127.0.0.1",
75
+ sessionMode: "stateful",
76
+ enableSse: true,
77
+ enableJsonResponse: true,
78
+ enableSseFallback: true,
79
+ ssePaths: {
80
+ stream: "/sse",
81
+ message: "/messages"
82
+ },
83
+ security: {
84
+ enableCors: true,
85
+ enableDnsRebindingProtection: true,
86
+ allowedHosts: ["127.0.0.1", "localhost"]
87
+ },
88
+ ...config
89
+ };
90
+
91
+ const server = await startHttpTransport(mcpServer, serverConfig);
92
+ this.servers.set(port, server);
93
+
94
+ // Wait for server to be ready
95
+ await this.waitForServerReady(port);
96
+
97
+ return {
98
+ server,
99
+ port,
100
+ baseUrl: `http://127.0.0.1:${port}`
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Wait for server to be ready by checking health endpoint
106
+ */
107
+ private async waitForServerReady(port: number, timeout = 15000): Promise<void> {
108
+ const startTime = Date.now();
109
+ let lastError: Error | undefined;
110
+
111
+ while (Date.now() - startTime < timeout) {
112
+ try {
113
+ const response = await fetch(`http://127.0.0.1:${port}/health`, {
114
+ signal: AbortSignal.timeout(2000)
115
+ });
116
+
117
+ if (response.ok) {
118
+ const health = await response.json() as { status: string };
119
+ if (health.status === 'healthy') {
120
+ // Give the server a bit more time to fully initialize
121
+ await new Promise(resolve => setTimeout(resolve, 200));
122
+ return;
123
+ }
124
+ }
125
+ } catch (error) {
126
+ lastError = error as Error;
127
+ // Server not ready yet, continue waiting
128
+ }
129
+
130
+ await new Promise(resolve => setTimeout(resolve, 250));
131
+ }
132
+
133
+ throw new Error(`Server on port ${port} did not become ready within ${timeout}ms. Last error: ${lastError?.message || 'Unknown'}`);
134
+ }
135
+
136
+ /**
137
+ * Stop a specific server by port
138
+ */
139
+ async stopServer(port: number): Promise<void> {
140
+ const server = this.servers.get(port);
141
+ if (server) {
142
+ await server.close();
143
+ this.servers.delete(port);
144
+ this.usedPorts.delete(port);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Stop all test servers
150
+ */
151
+ async stopAllServers(): Promise<void> {
152
+ const stopPromises = Array.from(this.servers.keys()).map(port => this.stopServer(port));
153
+ await Promise.all(stopPromises);
154
+ }
155
+
156
+ /**
157
+ * Get the number of active servers
158
+ */
159
+ getActiveServerCount(): number {
160
+ return this.servers.size;
161
+ }
162
+
163
+ /**
164
+ * Check if any servers are still running
165
+ */
166
+ hasActiveServers(): boolean {
167
+ return this.servers.size > 0;
168
+ }
169
+ }
170
+
171
+ // Global test server manager instance
172
+ export const testServerManager = new TestServerManager();
package/tsconfig.json CHANGED
@@ -21,6 +21,6 @@
21
21
  "@/*": ["*"]
22
22
  }
23
23
  },
24
- "include": ["src/**/*"],
24
+ "include": ["src/**/*", "tests/**/*"],
25
25
  "exclude": ["node_modules", "dist"]
26
26
  }
@@ -1,188 +0,0 @@
1
- # Human MCP Test Suite Analysis Report
2
-
3
- **Report Generated:** September 8, 2025
4
- **Project:** Human MCP - Model Context Protocol Server
5
- **Test Framework:** Bun Test
6
- **Report By:** QA Engineer
7
-
8
- ## Executive Summary
9
-
10
- The test suite execution reveals **3 failing tests out of 10 total tests** (70% pass rate). While TypeScript compilation passes successfully, there are critical inconsistencies between test expectations and actual implementation that need immediate attention.
11
-
12
- ## Test Results Overview
13
-
14
- - **Total Tests:** 10
15
- - **Tests Passed:** 7 (70%)
16
- - **Tests Failed:** 3 (30%)
17
- - **Tests Skipped:** 0
18
- - **Execution Time:** 417ms
19
- - **TypeScript Compilation:** ✅ PASS
20
-
21
- ## Detailed Test Failures
22
-
23
- ### 1. Formatters Test Failure: Accessibility Prompt
24
-
25
- **File:** `tests/unit/formatters.test.ts`
26
- **Test:** "should create accessibility prompt"
27
- **Status:** ❌ FAIL
28
-
29
- **Issue:** Test expects "concise analysis" text in accessibility prompt for basic detail level, but the actual implementation uses "Provide a concise analysis focusing on the most important findings." instead.
30
-
31
- **Expected:** `"concise analysis"`
32
- **Received:** Full prompt text without the expected substring
33
-
34
- **Root Cause:** Mismatch between test expectations and the `createPrompt()` function implementation in `src/tools/eyes/utils/formatters.ts`.
35
-
36
- ### 2. Config Test Failure: Default Model Mismatch
37
-
38
- **File:** `tests/unit/config.test.ts`
39
- **Test:** "should override defaults with environment variables"
40
- **Status:** ❌ FAIL
41
-
42
- **Issue:** Test expects `"gemini-2.0-flash-exp"` model but actual implementation returns `"gemini-2.5-flash"`.
43
-
44
- **Expected:** `"gemini-2.0-flash-exp"`
45
- **Received:** `"gemini-2.5-flash"`
46
-
47
- **Root Cause:** The test is setting `process.env.GOOGLE_GEMINI_MODEL = "gemini-2.5-flash"` but expecting a different model name in the assertion.
48
-
49
- ### 3. Server Integration Test Failure: Type Mismatch
50
-
51
- **File:** `tests/integration/server.test.ts`
52
- **Test:** "should be properly configured"
53
- **Status:** ❌ FAIL
54
-
55
- **Issue:** Test expects server to be instance of `Server` class but receives `McpServer` instance.
56
-
57
- **Expected:** Instance of `Server` (from `@modelcontextprotocol/sdk/server/index.js`)
58
- **Received:** Instance of `McpServer`
59
-
60
- **Root Cause:** Incorrect import and type expectation. The `createServer()` function returns `McpServer` instance, not `Server`.
61
-
62
- ## Coverage Analysis
63
-
64
- **Note:** No coverage metrics are currently configured in the project. The package.json does not include coverage scripts.
65
-
66
- **Recommendations for Coverage:**
67
- - Add coverage collection with `bun test --coverage`
68
- - Target minimum 80% coverage for critical paths
69
- - Focus on vision analysis tools and configuration validation
70
-
71
- ## Performance Metrics
72
-
73
- - **Test Execution Time:** 417ms (Acceptable)
74
- - **Slowest Individual Test:** ~1.54ms (Server creation test)
75
- - **Average Test Time:** ~41.7ms per test
76
-
77
- The test performance is excellent with sub-second execution time.
78
-
79
- ## Critical Issues Requiring Immediate Attention
80
-
81
- ### High Priority
82
- 1. **Config Test Logic Error:** Test is setting an environment variable to one value but expecting a different value
83
- 2. **Server Type Mismatch:** Import and expectation mismatch for server type
84
-
85
- ### Medium Priority
86
- 1. **Formatter Test Expectations:** String matching issues in prompt generation tests
87
-
88
- ## Detailed Recommendations
89
-
90
- ### 1. Fix Config Test (HIGH PRIORITY)
91
- **Location:** `tests/unit/config.test.ts:28`
92
-
93
- ```typescript
94
- // Current problematic code:
95
- process.env.GOOGLE_GEMINI_MODEL = "gemini-2.5-flash";
96
- expect(config.gemini.model).toBe("gemini-2.0-flash-exp"); // Wrong expectation
97
-
98
- // Should be:
99
- process.env.GOOGLE_GEMINI_MODEL = "gemini-2.0-flash-exp";
100
- expect(config.gemini.model).toBe("gemini-2.0-flash-exp");
101
- ```
102
-
103
- ### 2. Fix Server Type Test (HIGH PRIORITY)
104
- **Location:** `tests/integration/server.test.ts:22`
105
-
106
- ```typescript
107
- // Current problematic code:
108
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
109
- expect(server).toBeInstanceOf(Server);
110
-
111
- // Should be:
112
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
113
- expect(server).toBeInstanceOf(McpServer);
114
- ```
115
-
116
- ### 3. Fix Formatter Test (MEDIUM PRIORITY)
117
- **Location:** `tests/unit/formatters.test.ts:30`
118
-
119
- Update test expectation to match actual implementation:
120
- ```typescript
121
- // Either update the test expectation:
122
- expect(prompt).toContain("Provide a concise analysis");
123
-
124
- // Or update the formatters.ts implementation to include "concise analysis"
125
- ```
126
-
127
- ### 4. Add Test Coverage (MEDIUM PRIORITY)
128
- Add to package.json:
129
- ```json
130
- {
131
- "scripts": {
132
- "test:coverage": "bun test --coverage",
133
- "test:watch": "bun test --watch"
134
- }
135
- }
136
- ```
137
-
138
- ### 5. Enhance Test Suite (LOW PRIORITY)
139
- - Add error scenario testing for vision analysis tools
140
- - Add integration tests for Google Gemini API calls (with mocking)
141
- - Add performance benchmarks for image/video processing
142
- - Add end-to-end tests for MCP protocol compliance
143
-
144
- ## Test Quality Assessment
145
-
146
- ### Strengths
147
- - Good separation between unit and integration tests
148
- - Proper use of test setup/teardown with `beforeEach`/`afterAll`
149
- - Environment variable management in tests
150
- - Structured test organization
151
-
152
- ### Weaknesses
153
- - Missing error scenario coverage
154
- - No mocking for external dependencies (Google Gemini API)
155
- - Limited edge case testing
156
- - Missing performance validation tests
157
-
158
- ## Security Considerations
159
-
160
- - Tests properly manage environment variables for API keys
161
- - No sensitive data leakage detected in test files
162
- - Test environment isolation appears adequate
163
-
164
- ## Next Steps (Prioritized)
165
-
166
- 1. **IMMEDIATE:** Fix the 3 failing tests by correcting assertions and imports
167
- 2. **SHORT TERM:** Add test coverage collection and reporting
168
- 3. **MEDIUM TERM:** Expand test suite with error scenarios and edge cases
169
- 4. **LONG TERM:** Add performance benchmarks and comprehensive integration tests
170
-
171
- ## Build Process Verification
172
-
173
- - **TypeScript Compilation:** ✅ PASS - No type errors detected
174
- - **Dependency Resolution:** ✅ PASS - All imports resolve correctly
175
- - **Build Configuration:** ✅ PASS - Project builds successfully
176
-
177
- ## Files Requiring Attention
178
-
179
- 1. `/Users/duynguyen/www/human-mcp/tests/unit/config.test.ts` - Fix environment variable test logic
180
- 2. `/Users/duynguyen/www/human-mcp/tests/integration/server.test.ts` - Fix server type expectation
181
- 3. `/Users/duynguyen/www/human-mcp/tests/unit/formatters.test.ts` - Update string expectations
182
- 4. `/Users/duynguyen/www/human-mcp/package.json` - Add coverage scripts
183
-
184
- ---
185
-
186
- **Quality Gate Status:** ❌ BLOCKED
187
- **Reason:** 3 failing tests prevent production deployment
188
- **Required Action:** Fix failing tests before proceeding with any releases