@runhuman/mcp-server 2.0.4 → 2.0.5

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.
package/.env.example CHANGED
@@ -1,12 +1,12 @@
1
- # RunHuman API Configuration
2
-
3
- # API Base URL
4
- # For local development, use http://localhost:3400
5
- # For production, use your deployed API URL
6
- RUNHUMAN_API_URL=http://localhost:3400
7
-
8
- # API Key
9
- # Get this from the API dashboard at http://localhost:3400/app.html
10
- # Or use the default test key below for local development
11
- # Format: qa_live_xxxxxxxxxxxxxxxxxxxxx
12
- RUNHUMAN_API_KEY=qa_live_test_key_for_demo_purposes_only_12345
1
+ # Runhuman API Configuration
2
+
3
+ # API Base URL
4
+ # For local development, use http://localhost:3400
5
+ # For production, use your deployed API URL
6
+ RUNHUMAN_API_URL=http://localhost:3400
7
+
8
+ # API Key
9
+ # Get this from the API dashboard at http://localhost:3400/app.html
10
+ # Or use the default test key below for local development
11
+ # Format: qa_live_xxxxxxxxxxxxxxxxxxxxx
12
+ RUNHUMAN_API_KEY=qa_live_test_key_for_demo_purposes_only_12345
package/README.md CHANGED
@@ -1,243 +1,243 @@
1
- # RunHuman MCP Server
2
-
3
- A Model Context Protocol (MCP) server that allows AI agents to interact with the RunHuman QA testing service.
4
-
5
- ## Overview
6
-
7
- This MCP server provides tools for creating and managing human QA jobs through the RunHuman API. AI agents can use this server to:
8
-
9
- - Create new QA jobs with custom schemas
10
- - Check the status of running jobs
11
- - Retrieve completed job results
12
-
13
- ## Installation
14
-
15
- ### For Claude Desktop (Recommended)
16
-
17
- 1. Get your API key at: https://runhuman.com/dashboard/api-keys
18
-
19
- 2. Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on Mac):
20
-
21
- ```json
22
- {
23
- "mcpServers": {
24
- "runhuman": {
25
- "command": "npx",
26
- "args": ["-y", "@runhuman/mcp-server", "--api-key=qa_live_xxxxxxxxxxxxx"]
27
- }
28
- }
29
- }
30
- ```
31
-
32
- 3. Restart Claude Desktop
33
-
34
- That's it! The server will be automatically downloaded and run by Claude.
35
-
36
- ### For Development
37
-
38
- From the monorepo root:
39
-
40
- ```bash
41
- npm install
42
- npm run build --workspace=@runhuman/mcp-server
43
-
44
- # Run with API key
45
- node packages/mcp-server/dist/index.js --api-key=qa_live_xxxxx
46
- ```
47
-
48
- ### Available Tools
49
-
50
- #### `create_job`
51
- Create a new QA job with human testers.
52
-
53
- **Parameters:**
54
- - `url` (string): The URL to test
55
- - `description` (string): Instructions for the human tester describing what to test
56
- - `schema` (object): Expected result schema that the tester response will be extracted into
57
- - `targetDurationMinutes` (number, optional): Time limit for tester (default: 5, range: 1-60)
58
-
59
- #### `wait_for_result`
60
- Check status, wait, and retrieve results for a QA job in a single convenient call.
61
-
62
- **Parameters:**
63
- - `jobId` (string): The ID of the job to check
64
- - `waitSeconds` (number, optional): How long to wait before checking again (default: 30, range: 1-300)
65
-
66
- **Behavior:**
67
- - Checks status BEFORE waiting (returns immediately if already complete)
68
- - Waits for the specified duration
69
- - Checks status AFTER waiting
70
- - Returns results if complete, otherwise suggests calling again with longer wait time
71
-
72
- **Usage Pattern:**
73
- ```javascript
74
- // After creating a job, call repeatedly with increasing wait times:
75
- let result = await wait_for_result(jobId, { waitSeconds: 30 });
76
- if (result.status !== 'completed') {
77
- result = await wait_for_result(jobId, { waitSeconds: 45 });
78
- }
79
- if (result.status !== 'completed') {
80
- result = await wait_for_result(jobId, { waitSeconds: 60 });
81
- }
82
- ```
83
-
84
- **Returns:**
85
- - `result`: Structured test results extracted from tester's response
86
- - `status`: Job status (completed, failed, timeout, pending, claimed, in_progress)
87
- - `costUsd`: Exact cost in USD with full precision (e.g., 0.396)
88
- - `testDurationSeconds`: Time spent by tester in seconds (rounded up)
89
- - `testerResponse`: Raw natural language feedback from the human tester
90
- - `testerAlias`: Anonymized tester name (e.g., "Tester Alpha")
91
- - `testerAvatarUrl`: Avatar image URL for UI display
92
- - `testerColor`: Hex color code for theming (e.g., "#4A90E2")
93
- - Additional metadata (timestamps, etc.)
94
-
95
- **Cost Calculation:**
96
- - Costs are calculated as: `duration × $0.0018/second` (general-use tier)
97
- - Duration is always rounded UP using Math.ceil (any partial second counts)
98
- - Costs are never $0 unless the tester never actually worked on it
99
- - Full precision maintained (not rounded to cents)
100
-
101
- ## Configuration
102
-
103
- The MCP server needs to be configured with your RunHuman API credentials.
104
-
105
- ### 1. Get an API Key
106
-
107
- **Option A: Via Dashboard**
108
- 1. Start the API server: `npm run dev --workspace=@runhuman/api`
109
- 2. Open http://localhost:3400/api-keys
110
- 3. Click "Create API Key"
111
- 4. Copy the key (starts with `qa_live_`)
112
-
113
- **Option B: Use Default Test Key**
114
- - For local development, you can use: `qa_live_test_key_123`
115
- - This key exists in `packages/api/data/api-keys.json`
116
-
117
- ### 2. Configure Environment Variables
118
-
119
- Create a `.env` file in the MCP server directory:
120
-
121
- ```bash
122
- # For local development
123
- RUNHUMAN_API_URL=http://localhost:3400
124
- RUNHUMAN_API_KEY=qa_live_test_key_123
125
-
126
- # For production
127
- RUNHUMAN_API_URL=https://api.runhuman.com
128
- RUNHUMAN_API_KEY=qa_live_xxxxxxxxxxxxxxxxxxxxx
129
- ```
130
-
131
- **Important:** Never commit `.env` files to git! They're already in `.gitignore`.
132
-
133
- ### 3. Verify Configuration
134
-
135
- Test your API key works:
136
-
137
- ```bash
138
- curl http://localhost:3400/api/jobs \
139
- -H "Authorization: Bearer qa_live_test_key_123" \
140
- -H "Content-Type: application/json" \
141
- -d '{"url":"https://example.com","description":"test","outputSchema":{}}'
142
- ```
143
-
144
- Should return a job ID if authentication works.
145
-
146
- For more details, see [docs/API-AUTHENTICATION.md](docs/API-AUTHENTICATION.md)
147
-
148
- ## Testing
149
-
150
- The MCP server includes automated tests to verify it's working correctly:
151
-
152
- ```bash
153
- # Build first
154
- npm run build --workspace=@runhuman/mcp-server
155
-
156
- # Run simple automated test
157
- npm run test --workspace=@runhuman/mcp-server
158
-
159
- # Or use the MCP Inspector (interactive testing)
160
- npm run test:inspector --workspace=@runhuman/mcp-server
161
- ```
162
-
163
- The test script will:
164
- 1. ✅ Initialize a connection to the MCP server
165
- 2. ✅ List all available tools (create_job, wait_for_result)
166
- 3. ✅ Test calling the create_job tool
167
-
168
- ### Expected Test Output
169
-
170
- ```
171
- ✅ Server initialized successfully
172
- ✅ Tools listed: create_job, wait_for_result
173
- ✅ create_job tool called successfully
174
- ```
175
-
176
- ## Development
177
-
178
- ```bash
179
- # Watch mode (auto-rebuild on changes)
180
- npm run dev --workspace=@runhuman/mcp-server
181
-
182
- # Build
183
- npm run build --workspace=@runhuman/mcp-server
184
-
185
- # Test after building
186
- npm run test --workspace=@runhuman/mcp-server
187
- ```
188
-
189
- ## Integration with Claude Desktop
190
-
191
- To use this MCP server with Claude Desktop, add it to your configuration:
192
-
193
- ```json
194
- {
195
- "mcpServers": {
196
- "runhuman": {
197
- "command": "node",
198
- "args": ["/path/to/qa-experiment/packages/mcp-server/dist/index.js"]
199
- }
200
- }
201
- }
202
- ```
203
-
204
- ## Example Usage
205
-
206
- Once connected to an AI agent (like Claude), the agent can use these tools naturally:
207
-
208
- **User:** "Can someone test my checkout page at https://myapp.com/checkout?"
209
-
210
- **Agent uses create_job:**
211
- ```
212
- ✅ Job created successfully!
213
- Job ID: job_abc123
214
- Status: pending
215
- ...
216
- ```
217
-
218
- **Agent calls wait_for_result repeatedly until complete:**
219
- ```
220
- ⏳ Job Status: in_progress
221
- Waited 30s, job not complete yet.
222
- 💡 Suggestion: Call wait_for_result again with waitSeconds: 45
223
- ```
224
-
225
- **Finally:**
226
- ```
227
- ✅ Test completed!
228
- Results Summary:
229
- - Checkout Flow: ✅ Working
230
- - Payment Processing: ✅ Successful
231
- ...
232
- ```
233
-
234
- ## Developer Documentation
235
-
236
- For developers working on this MCP server:
237
- - [docs/HOW-AGENTS-USE-MCP.md](docs/HOW-AGENTS-USE-MCP.md) - How AI agents discover and use MCP servers
238
- - [docs/TOOL-RESPONSE-BEST-PRACTICES.md](docs/TOOL-RESPONSE-BEST-PRACTICES.md) - Best practices for tool responses
239
-
240
- ## Learn More
241
-
242
- - [Model Context Protocol Documentation](https://modelcontextprotocol.io/)
243
- - [RunHuman API Documentation](../api/README.md)
1
+ # Runhuman MCP Server
2
+
3
+ A Model Context Protocol (MCP) server that allows AI agents to interact with the Runhuman QA testing service.
4
+
5
+ ## Overview
6
+
7
+ This MCP server provides tools for creating and managing human QA jobs through the Runhuman API. AI agents can use this server to:
8
+
9
+ - Create new QA jobs with custom schemas
10
+ - Check the status of running jobs
11
+ - Retrieve completed job results
12
+
13
+ ## Installation
14
+
15
+ ### For Claude Desktop (Recommended)
16
+
17
+ 1. Get your API key at: https://runhuman.com/dashboard/api-keys
18
+
19
+ 2. Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on Mac):
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "runhuman": {
25
+ "command": "npx",
26
+ "args": ["-y", "@runhuman/mcp-server", "--api-key=qa_live_xxxxxxxxxxxxx"]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ 3. Restart Claude Desktop
33
+
34
+ That's it! The server will be automatically downloaded and run by Claude.
35
+
36
+ ### For Development
37
+
38
+ From the monorepo root:
39
+
40
+ ```bash
41
+ npm install
42
+ npm run build --workspace=@runhuman/mcp-server
43
+
44
+ # Run with API key
45
+ node packages/mcp-server/dist/index.js --api-key=qa_live_xxxxx
46
+ ```
47
+
48
+ ### Available Tools
49
+
50
+ #### `create_job`
51
+ Create a new QA job with human testers.
52
+
53
+ **Parameters:**
54
+ - `url` (string): The URL to test
55
+ - `description` (string): Instructions for the human tester describing what to test
56
+ - `schema` (object): Expected result schema that the tester response will be extracted into
57
+ - `targetDurationMinutes` (number, optional): Time limit for tester (default: 5, range: 1-60)
58
+
59
+ #### `wait_for_result`
60
+ Check status, wait, and retrieve results for a QA job in a single convenient call.
61
+
62
+ **Parameters:**
63
+ - `jobId` (string): The ID of the job to check
64
+ - `waitSeconds` (number, optional): How long to wait before checking again (default: 30, range: 1-300)
65
+
66
+ **Behavior:**
67
+ - Checks status BEFORE waiting (returns immediately if already complete)
68
+ - Waits for the specified duration
69
+ - Checks status AFTER waiting
70
+ - Returns results if complete, otherwise suggests calling again with longer wait time
71
+
72
+ **Usage Pattern:**
73
+ ```javascript
74
+ // After creating a job, call repeatedly with increasing wait times:
75
+ let result = await wait_for_result(jobId, { waitSeconds: 30 });
76
+ if (result.status !== 'completed') {
77
+ result = await wait_for_result(jobId, { waitSeconds: 45 });
78
+ }
79
+ if (result.status !== 'completed') {
80
+ result = await wait_for_result(jobId, { waitSeconds: 60 });
81
+ }
82
+ ```
83
+
84
+ **Returns:**
85
+ - `result`: Structured test results extracted from tester's response
86
+ - `status`: Job status (completed, failed, timeout, pending, claimed, in_progress)
87
+ - `costUsd`: Exact cost in USD with full precision (e.g., 0.396)
88
+ - `testDurationSeconds`: Time spent by tester in seconds (rounded up)
89
+ - `testerResponse`: Raw natural language feedback from the human tester
90
+ - `testerAlias`: Anonymized tester name (e.g., "Tester Alpha")
91
+ - `testerAvatarUrl`: Avatar image URL for UI display
92
+ - `testerColor`: Hex color code for theming (e.g., "#4A90E2")
93
+ - Additional metadata (timestamps, etc.)
94
+
95
+ **Cost Calculation:**
96
+ - Costs are calculated as: `duration × $0.0018/second` (general-use tier)
97
+ - Duration is always rounded UP using Math.ceil (any partial second counts)
98
+ - Costs are never $0 unless the tester never actually worked on it
99
+ - Full precision maintained (not rounded to cents)
100
+
101
+ ## Configuration
102
+
103
+ The MCP server needs to be configured with your Runhuman API credentials.
104
+
105
+ ### 1. Get an API Key
106
+
107
+ **Option A: Via Dashboard**
108
+ 1. Start the API server: `npm run dev --workspace=@runhuman/api`
109
+ 2. Open http://localhost:3400/api-keys
110
+ 3. Click "Create API Key"
111
+ 4. Copy the key (starts with `qa_live_`)
112
+
113
+ **Option B: Use Default Test Key**
114
+ - For local development, you can use: `qa_live_test_key_123`
115
+ - This key exists in `packages/api/data/api-keys.json`
116
+
117
+ ### 2. Configure Environment Variables
118
+
119
+ Create a `.env` file in the MCP server directory:
120
+
121
+ ```bash
122
+ # For local development
123
+ RUNHUMAN_API_URL=http://localhost:3400
124
+ RUNHUMAN_API_KEY=qa_live_test_key_123
125
+
126
+ # For production
127
+ RUNHUMAN_API_URL=https://api.runhuman.com
128
+ RUNHUMAN_API_KEY=qa_live_xxxxxxxxxxxxxxxxxxxxx
129
+ ```
130
+
131
+ **Important:** Never commit `.env` files to git! They're already in `.gitignore`.
132
+
133
+ ### 3. Verify Configuration
134
+
135
+ Test your API key works:
136
+
137
+ ```bash
138
+ curl http://localhost:3400/api/jobs \
139
+ -H "Authorization: Bearer qa_live_test_key_123" \
140
+ -H "Content-Type: application/json" \
141
+ -d '{"url":"https://example.com","description":"test","outputSchema":{}}'
142
+ ```
143
+
144
+ Should return a job ID if authentication works.
145
+
146
+ For more details, see [docs/API-AUTHENTICATION.md](docs/API-AUTHENTICATION.md)
147
+
148
+ ## Testing
149
+
150
+ The MCP server includes automated tests to verify it's working correctly:
151
+
152
+ ```bash
153
+ # Build first
154
+ npm run build --workspace=@runhuman/mcp-server
155
+
156
+ # Run simple automated test
157
+ npm run test --workspace=@runhuman/mcp-server
158
+
159
+ # Or use the MCP Inspector (interactive testing)
160
+ npm run test:inspector --workspace=@runhuman/mcp-server
161
+ ```
162
+
163
+ The test script will:
164
+ 1. ✅ Initialize a connection to the MCP server
165
+ 2. ✅ List all available tools (create_job, wait_for_result)
166
+ 3. ✅ Test calling the create_job tool
167
+
168
+ ### Expected Test Output
169
+
170
+ ```
171
+ ✅ Server initialized successfully
172
+ ✅ Tools listed: create_job, wait_for_result
173
+ ✅ create_job tool called successfully
174
+ ```
175
+
176
+ ## Development
177
+
178
+ ```bash
179
+ # Watch mode (auto-rebuild on changes)
180
+ npm run dev --workspace=@runhuman/mcp-server
181
+
182
+ # Build
183
+ npm run build --workspace=@runhuman/mcp-server
184
+
185
+ # Test after building
186
+ npm run test --workspace=@runhuman/mcp-server
187
+ ```
188
+
189
+ ## Integration with Claude Desktop
190
+
191
+ To use this MCP server with Claude Desktop, add it to your configuration:
192
+
193
+ ```json
194
+ {
195
+ "mcpServers": {
196
+ "runhuman": {
197
+ "command": "node",
198
+ "args": ["/path/to/qa-experiment/packages/mcp-server/dist/index.js"]
199
+ }
200
+ }
201
+ }
202
+ ```
203
+
204
+ ## Example Usage
205
+
206
+ Once connected to an AI agent (like Claude), the agent can use these tools naturally:
207
+
208
+ **User:** "Can someone test my checkout page at https://myapp.com/checkout?"
209
+
210
+ **Agent uses create_job:**
211
+ ```
212
+ ✅ Job created successfully!
213
+ Job ID: job_abc123
214
+ Status: pending
215
+ ...
216
+ ```
217
+
218
+ **Agent calls wait_for_result repeatedly until complete:**
219
+ ```
220
+ ⏳ Job Status: in_progress
221
+ Waited 30s, job not complete yet.
222
+ 💡 Suggestion: Call wait_for_result again with waitSeconds: 45
223
+ ```
224
+
225
+ **Finally:**
226
+ ```
227
+ ✅ Test completed!
228
+ Results Summary:
229
+ - Checkout Flow: ✅ Working
230
+ - Payment Processing: ✅ Successful
231
+ ...
232
+ ```
233
+
234
+ ## Developer Documentation
235
+
236
+ For developers working on this MCP server:
237
+ - [docs/HOW-AGENTS-USE-MCP.md](docs/HOW-AGENTS-USE-MCP.md) - How AI agents discover and use MCP servers
238
+ - [docs/TOOL-RESPONSE-BEST-PRACTICES.md](docs/TOOL-RESPONSE-BEST-PRACTICES.md) - Best practices for tool responses
239
+
240
+ ## Learn More
241
+
242
+ - [Model Context Protocol Documentation](https://modelcontextprotocol.io/)
243
+ - [Runhuman API Documentation](../api/README.md)
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * RunHuman MCP Server - stdio entry point
3
+ * Runhuman MCP Server - stdio entry point
4
4
  *
5
5
  * This is the CLI entry point for npx @runhuman/mcp-server.
6
6
  * It uses stdio transport for communication with MCP clients like Claude Desktop.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * RunHuman MCP Server - stdio entry point
3
+ * Runhuman MCP Server - stdio entry point
4
4
  *
5
5
  * This is the CLI entry point for npx @runhuman/mcp-server.
6
6
  * It uses stdio transport for communication with MCP clients like Claude Desktop.
@@ -21,7 +21,7 @@ const apiUrlArg = args.find(arg => arg.startsWith('--api-url='))?.split('=')[1];
21
21
  const API_URL = apiUrlArg || process.env.RUNHUMAN_API_URL || 'https://qa-experiment.fly.dev';
22
22
  const API_KEY = apiKeyArg || process.env.RUNHUMAN_API_KEY;
23
23
  if (!API_KEY) {
24
- console.error('Error: API key is required');
24
+ console.error('Error: API key is required');
25
25
  console.error('');
26
26
  console.error('For Claude Desktop, add to your config:');
27
27
  console.error('{');
@@ -36,8 +36,8 @@ if (!API_KEY) {
36
36
  console.error('Get your API key at: https://qa-experiment.fly.dev/app.html');
37
37
  process.exit(1);
38
38
  }
39
- console.error(`🔗 Connected to RunHuman API at: ${API_URL}`);
40
- console.error(`🔑 Using API key: ${API_KEY.substring(0, 12)}...`);
39
+ console.error(`Connected to Runhuman API at: ${API_URL}`);
40
+ console.error(`Using API key: ${API_KEY.substring(0, 12)}...`);
41
41
  // Create the MCP server with configuration
42
42
  const server = createMcpServer({
43
43
  apiUrl: API_URL,
@@ -49,7 +49,7 @@ const server = createMcpServer({
49
49
  async function main() {
50
50
  const transport = new StdioServerTransport();
51
51
  await server.connect(transport);
52
- console.error('RunHuman MCP server running on stdio');
52
+ console.error('Runhuman MCP server running on stdio');
53
53
  }
54
54
  main().catch((error) => {
55
55
  console.error('Server error:', error);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,iEAAiE;AACjE,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,gBAAgB;AAChB,2CAA2C;AAC3C,0EAA0E;AAC1E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,MAAM,OAAO,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,+BAA+B,CAAC;AAC7F,MAAM,OAAO,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;AAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzC,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IACzF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;AAC7D,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAElE,2CAA2C;AAC3C,MAAM,MAAM,GAAG,eAAe,CAAC;IAC7B,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,OAAO;CAChB,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;AACxD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,iEAAiE;AACjE,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,gBAAgB;AAChB,2CAA2C;AAC3C,0EAA0E;AAC1E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,MAAM,OAAO,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,+BAA+B,CAAC;AAC7F,MAAM,OAAO,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;AAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzC,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IACzF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,KAAK,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;AAC1D,OAAO,CAAC,KAAK,CAAC,kBAAkB,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAE/D,2CAA2C;AAC3C,MAAM,MAAM,GAAG,eAAe,CAAC;IAC7B,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,OAAO;CAChB,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;AACxD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -22,7 +22,7 @@ export function createMcpServer(config) {
22
22
  prompts: [
23
23
  {
24
24
  name: 'explain_runhuman',
25
- description: 'Get an explanation of how to use RunHuman for QA testing',
25
+ description: 'Get an explanation of how to use Runhuman for QA testing',
26
26
  },
27
27
  ],
28
28
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"create-job.tool.d.ts","sourceRoot":"","sources":["../../src/tools/create-job.tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAqB,MAAM,aAAa,CAAC;AAErF,eAAO,MAAM,uBAAuB,EAAE,IAiDrC,CAAC;AAEF,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAgFhF"}
1
+ {"version":3,"file":"create-job.tool.d.ts","sourceRoot":"","sources":["../../src/tools/create-job.tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAqB,MAAM,aAAa,CAAC;AAErF,eAAO,MAAM,uBAAuB,EAAE,IAqDrC,CAAC;AAEF,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAiFhF"}
@@ -3,22 +3,22 @@
3
3
  */
4
4
  export const createJobToolDefinition = {
5
5
  name: 'create_job',
6
- description: `⚠️ IMPORTANT: This ONLY creates and queues a job. It does NOT perform the test or return results. You MUST follow up with wait_for_result.
7
-
8
- Creates a QA job that will be performed by a REAL HUMAN tester (not AI). The human will manually test your application, describe findings in natural language, and GPT-4o will extract structured data from their response.
9
-
10
- Use this when you need human verification of:
11
- - UI/UX functionality that's hard to automate
12
- - Visual issues, accessibility problems
13
- - Complex user flows (login, checkout, forms)
14
- - Cross-browser compatibility
15
- - Real user experience feedback
16
-
17
- ⚠️ REQUIRED WORKFLOW (do NOT skip steps):
18
- 1. create_job → Returns jobId (job is now QUEUED, not complete!)
19
- 2. wait_for_result → Checks status, waits, and retrieves results (takes 2-10 min total)
20
- 3. If not complete, call wait_for_result again with longer wait time
21
-
6
+ description: `IMPORTANT: This ONLY creates and queues a job. It does NOT perform the test or return results. You MUST follow up with wait_for_result.
7
+
8
+ Creates a QA job that will be performed by a REAL HUMAN tester (not AI). The human will manually test your application, describe findings in natural language, and GPT-4o will extract structured data from their response.
9
+
10
+ Use this when you need human verification of:
11
+ - UI/UX functionality that's hard to automate
12
+ - Visual issues, accessibility problems
13
+ - Complex user flows (login, checkout, forms)
14
+ - Cross-browser compatibility
15
+ - Real user experience feedback
16
+
17
+ REQUIRED WORKFLOW (do NOT skip steps):
18
+ 1. create_job → Returns jobId (job is now QUEUED, not complete!)
19
+ 2. wait_for_result → Checks status, waits, and retrieves results (takes 2-10 min total)
20
+ 3. If not complete, call wait_for_result again with longer wait time
21
+
22
22
  DO NOT treat job creation as completion. You MUST wait for and retrieve results.`,
23
23
  inputSchema: {
24
24
  type: 'object',
@@ -47,6 +47,10 @@ DO NOT treat job creation as completion. You MUST wait for and retrieve results.
47
47
  type: ['number', 'boolean'],
48
48
  description: 'Maximum additional minutes allowed for extension. Set to false for unlimited. Default: false (unlimited). Range: 1-60 if number.',
49
49
  },
50
+ additionalValidationInstructions: {
51
+ type: 'string',
52
+ description: 'Optional custom instructions for the AI when validating test results. Use this to specify what to focus on, what to ignore, or how to interpret specific scenarios. Example: "Ignore minor UI glitches in the header. Only mark as failed if the core checkout functionality does not work."',
53
+ },
50
54
  },
51
55
  required: ['url', 'description', 'schema'],
52
56
  },
@@ -67,6 +71,7 @@ export async function handleCreateJob(args, config) {
67
71
  targetDurationMinutes: args.targetDurationMinutes,
68
72
  allowDurationExtension: args.allowDurationExtension,
69
73
  maxExtensionMinutes: args.maxExtensionMinutes,
74
+ additionalValidationInstructions: args.additionalValidationInstructions,
70
75
  }),
71
76
  });
72
77
  if (!response.ok) {
@@ -74,14 +79,14 @@ export async function handleCreateJob(args, config) {
74
79
  return {
75
80
  content: [{
76
81
  type: 'text',
77
- text: `❌ Failed to create job
78
-
79
- Error: ${error.error || error.message || response.statusText}
80
- Status: ${response.status}
81
-
82
- Please check:
83
- - Your RUNHUMAN_API_KEY is valid
84
- - The API server is running at ${apiUrl}
82
+ text: `Failed to create job
83
+
84
+ Error: ${error.error || error.message || response.statusText}
85
+ Status: ${response.status}
86
+
87
+ Please check:
88
+ - Your RUNHUMAN_API_KEY is valid
89
+ - The API server is running at ${apiUrl}
85
90
  - Your API key has permission to create jobs`,
86
91
  }],
87
92
  isError: true,
@@ -92,22 +97,22 @@ Please check:
92
97
  return {
93
98
  content: [{
94
99
  type: 'text',
95
- text: `⏳ Job QUEUED (not complete yet!)
96
-
97
- Job ID: ${data.jobId}
98
- Status: ${data.status}
99
- URL: ${args.url}
100
- Time limit: ${duration} minutes
101
-
102
- The test has been queued for a HUMAN tester. It is NOT complete yet.
103
-
104
- ⚠️ REQUIRED NEXT STEPS:
105
- 1. Call wait_for_result(jobId: "${data.jobId}", waitSeconds: 30)
106
- 2. If not complete, call wait_for_result again with waitSeconds: 45
107
- 3. Continue with increasing wait times (60, 90, etc.) until complete
108
-
109
- Typical completion time: 2-10 minutes total.
110
-
100
+ text: `Job QUEUED (not complete yet!)
101
+
102
+ Job ID: ${data.jobId}
103
+ Status: ${data.status}
104
+ URL: ${args.url}
105
+ Time limit: ${duration} minutes
106
+
107
+ The test has been queued for a HUMAN tester. It is NOT complete yet.
108
+
109
+ REQUIRED NEXT STEPS:
110
+ 1. Call wait_for_result(jobId: "${data.jobId}", waitSeconds: 30)
111
+ 2. If not complete, call wait_for_result again with waitSeconds: 45
112
+ 3. Continue with increasing wait times (60, 90, etc.) until complete
113
+
114
+ Typical completion time: 2-10 minutes total.
115
+
111
116
  DO NOT consider this task done until you have retrieved the results!`,
112
117
  }],
113
118
  };
@@ -116,13 +121,13 @@ DO NOT consider this task done until you have retrieved the results!`,
116
121
  return {
117
122
  content: [{
118
123
  type: 'text',
119
- text: `❌ Error creating job
120
-
121
- ${error instanceof Error ? error.message : 'Unknown error'}
122
-
123
- Please check:
124
- - The API server is running at ${apiUrl}
125
- - Your network connection
124
+ text: `Error creating job
125
+
126
+ ${error instanceof Error ? error.message : 'Unknown error'}
127
+
128
+ Please check:
129
+ - The API server is running at ${apiUrl}
130
+ - Your network connection
126
131
  - Your .env file configuration`,
127
132
  }],
128
133
  isError: true,
@@ -1 +1 @@
1
- {"version":3,"file":"create-job.tool.js","sourceRoot":"","sources":["../../src/tools/create-job.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-job.tool.js","sourceRoot":"","sources":["../../src/tools/create-job.tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"wait-for-result.tool.d.ts","sourceRoot":"","sources":["../../src/tools/wait-for-result.tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAEnF,eAAO,MAAM,2BAA2B,EAAE,IAmCzC,CAAC;AAwEF,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqGhF"}
1
+ {"version":3,"file":"wait-for-result.tool.d.ts","sourceRoot":"","sources":["../../src/tools/wait-for-result.tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAEnF,eAAO,MAAM,2BAA2B,EAAE,IAwCzC,CAAC;AAyFF,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAiHhF"}
@@ -3,22 +3,27 @@
3
3
  */
4
4
  export const waitForResultToolDefinition = {
5
5
  name: 'wait_for_result',
6
- description: `Check status, wait, and retrieve results for a QA job in a single call.
7
-
8
- This tool combines status checking, waiting, and result retrieval into one convenient function:
9
- - Checks status BEFORE waiting (returns immediately if already complete)
10
- - Polls status every 5 seconds during the wait period
11
- - Returns immediately when job completes (no need to wait full duration)
12
- - Returns results if complete, otherwise suggests calling again with longer wait
13
-
14
- Jobs progress through states: pending → claimedin_progress → completed (or failed/timeout)
15
- Typical completion time: 2-10 minutes total
16
-
17
- Use this tool repeatedly with increasing wait times until you get results:
18
- - First call: wait_for_result(jobId, { waitSeconds: 30 })
19
- - If not complete: wait_for_result(jobId, { waitSeconds: 45 })
20
- - If still not complete: wait_for_result(jobId, { waitSeconds: 60 })
21
-
6
+ description: `Check status, wait, and retrieve results for a QA job in a single call.
7
+
8
+ This tool combines status checking, waiting, and result retrieval into one convenient function:
9
+ - Checks status BEFORE waiting (returns immediately if already complete)
10
+ - Polls status every 5 seconds during the wait period
11
+ - Returns immediately when job completes (no need to wait full duration)
12
+ - Returns results if complete, otherwise suggests calling again with longer wait
13
+
14
+ Jobs progress through states: pending → waitingworking → completed (or incomplete/abandoned/error)
15
+ - pending: Job is being prepared
16
+ - waiting: Job posted to Slack, waiting for a tester to claim it
17
+ - working: Tester has claimed the job and is actively testing
18
+ - completed/incomplete/abandoned/error: Terminal states
19
+
20
+ Typical completion time: 2-10 minutes total
21
+
22
+ Use this tool repeatedly with increasing wait times until you get results:
23
+ - First call: wait_for_result(jobId, { waitSeconds: 30 })
24
+ - If not complete: wait_for_result(jobId, { waitSeconds: 45 })
25
+ - If still not complete: wait_for_result(jobId, { waitSeconds: 60 })
26
+
22
27
  Returns immediately if job is already complete (no waiting needed).`,
23
28
  inputSchema: {
24
29
  type: 'object',
@@ -56,10 +61,10 @@ function formatCompletedResult(job) {
56
61
  content: [
57
62
  {
58
63
  type: 'text',
59
- text: `✅ Test completed!
60
-
61
- Job ID: ${job.id}
62
-
64
+ text: `Test completed!
65
+
66
+ Job ID: ${job.id}
67
+
63
68
  **Test Results:**`,
64
69
  },
65
70
  {
@@ -76,27 +81,43 @@ Job ID: ${job.id}
76
81
  ],
77
82
  };
78
83
  }
79
- function formatFailedResult(job) {
84
+ function formatIncompleteResult(job) {
80
85
  return {
81
86
  content: [{
82
87
  type: 'text',
83
- text: `❌ Job failed
84
-
85
- Job ID: ${job.id}
86
- Error: ${job.error || 'Unknown error'}`,
88
+ text: `Test completed with incomplete data
89
+
90
+ Job ID: ${job.id}
91
+
92
+ The test was completed but some required data was missing or incomplete.
93
+ ${job.error ? `\nDetails: ${job.error}` : ''}`,
94
+ }],
95
+ isError: true,
96
+ };
97
+ }
98
+ function formatAbandonedResult(job) {
99
+ return {
100
+ content: [{
101
+ type: 'text',
102
+ text: `Test abandoned
103
+
104
+ Job ID: ${job.id}
105
+
106
+ The tester abandoned this test.
107
+ ${job.error ? `\nReason: ${job.error}` : ''}`,
87
108
  }],
88
109
  isError: true,
89
110
  };
90
111
  }
91
- function formatTimeoutResult(job) {
112
+ function formatErrorResult(job) {
92
113
  return {
93
114
  content: [{
94
115
  type: 'text',
95
- text: `⏰ Job timed out
96
-
97
- Job ID: ${job.id}
98
-
99
- The tester did not complete the test in time.`,
116
+ text: `Test failed due to system error
117
+
118
+ Job ID: ${job.id}
119
+
120
+ Error: ${job.error || 'Unknown error'}`,
100
121
  }],
101
122
  isError: true,
102
123
  };
@@ -113,13 +134,17 @@ export async function handleWaitForResult(args, config) {
113
134
  console.error(`[wait_for_result] Job already completed`);
114
135
  return formatCompletedResult(job);
115
136
  }
116
- if (job.status === 'failed') {
117
- console.error(`[wait_for_result] Job already failed`);
118
- return formatFailedResult(job);
137
+ if (job.status === 'incomplete') {
138
+ console.error(`[wait_for_result] Job already completed with incomplete data`);
139
+ return formatIncompleteResult(job);
140
+ }
141
+ if (job.status === 'abandoned') {
142
+ console.error(`[wait_for_result] Job already abandoned`);
143
+ return formatAbandonedResult(job);
119
144
  }
120
- if (job.status === 'timeout') {
121
- console.error(`[wait_for_result] Job already timed out`);
122
- return formatTimeoutResult(job);
145
+ if (job.status === 'error') {
146
+ console.error(`[wait_for_result] Job already failed with error`);
147
+ return formatErrorResult(job);
123
148
  }
124
149
  // Job not complete yet, poll periodically during the wait period
125
150
  console.error(`[wait_for_result] Job status: ${job.status}. Polling every ${pollIntervalSeconds}s for up to ${waitSeconds}s...`);
@@ -139,44 +164,54 @@ export async function handleWaitForResult(args, config) {
139
164
  // Check status
140
165
  console.error(`[wait_for_result] Polling status (${elapsedSeconds}s elapsed)...`);
141
166
  job = await checkJobStatus(args.jobId, config);
142
- // Check if complete now
167
+ // Check if in terminal state now
143
168
  if (job.status === 'completed') {
144
169
  console.error(`[wait_for_result] Job completed after ${elapsedSeconds}s`);
145
170
  return formatCompletedResult(job);
146
171
  }
147
- if (job.status === 'failed') {
148
- console.error(`[wait_for_result] Job failed after ${elapsedSeconds}s`);
149
- return formatFailedResult(job);
172
+ if (job.status === 'incomplete') {
173
+ console.error(`[wait_for_result] Job completed with incomplete data after ${elapsedSeconds}s`);
174
+ return formatIncompleteResult(job);
150
175
  }
151
- if (job.status === 'timeout') {
152
- console.error(`[wait_for_result] Job timed out after ${elapsedSeconds}s`);
153
- return formatTimeoutResult(job);
176
+ if (job.status === 'abandoned') {
177
+ console.error(`[wait_for_result] Job abandoned after ${elapsedSeconds}s`);
178
+ return formatAbandonedResult(job);
179
+ }
180
+ if (job.status === 'error') {
181
+ console.error(`[wait_for_result] Job failed with error after ${elapsedSeconds}s`);
182
+ return formatErrorResult(job);
154
183
  }
155
184
  console.error(`[wait_for_result] Job still ${job.status}, continuing to poll...`);
156
185
  }
157
186
  // Reached max wait time without completion
158
- const statusEmoji = {
159
- pending: '⏳',
160
- claimed: '👤',
161
- in_progress: '🔄',
162
- };
163
- const emoji = statusEmoji[job.status] || '📊';
164
187
  const nextWait = Math.min(waitSeconds + 15, 120);
165
- const statusMessage = job.status === 'pending'
166
- ? 'Waiting for a tester to claim this job...'
167
- : 'The tester is working on your test...';
188
+ // Determine appropriate status message based on job state
189
+ let statusMessage;
190
+ if (job.status === 'pending') {
191
+ statusMessage = 'Your test is being prepared and will be posted to testers shortly...';
192
+ }
193
+ else if (job.status === 'waiting') {
194
+ statusMessage = 'Waiting for a tester to claim your test...';
195
+ }
196
+ else if (job.status === 'working') {
197
+ statusMessage = 'The tester is working on your test...';
198
+ }
199
+ else {
200
+ // Fallback for any unexpected status
201
+ statusMessage = `Job is in ${job.status} state...`;
202
+ }
168
203
  return {
169
204
  content: [{
170
205
  type: 'text',
171
- text: `${emoji} Job Status: ${job.status}
172
-
173
- Job ID: ${job.id}
174
-
175
- ${statusMessage}
176
-
177
- Waited ${waitSeconds}s (polling every ${pollIntervalSeconds}s), job not complete yet.
178
-
179
- 💡 Suggestion: Call wait_for_result again with waitSeconds: ${nextWait}
206
+ text: `Job Status: ${job.status}
207
+
208
+ Job ID: ${job.id}
209
+
210
+ ${statusMessage}
211
+
212
+ Waited ${waitSeconds}s (polling every ${pollIntervalSeconds}s), job not complete yet.
213
+
214
+ Suggestion: Call wait_for_result again with waitSeconds: ${nextWait}
180
215
  Typical completion time: 2-10 minutes total.`,
181
216
  }],
182
217
  };
@@ -185,8 +220,8 @@ Typical completion time: 2-10 minutes total.`,
185
220
  return {
186
221
  content: [{
187
222
  type: 'text',
188
- text: `❌ Error waiting for result
189
-
223
+ text: `Error waiting for result
224
+
190
225
  ${error instanceof Error ? error.message : 'Unknown error'}`,
191
226
  }],
192
227
  isError: true,
@@ -1 +1 @@
1
- {"version":3,"file":"wait-for-result.tool.js","sourceRoot":"","sources":["../../src/tools/wait-for-result.tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,CAAC,MAAM,2BAA2B,GAAS;IAC/C,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE;;;;;;;;;;;;;;;;oEAgBqD;IAClE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sFAAsF;aACpG;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,gKAAgK;gBAC7K,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;aACb;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;CACF,CAAC;AAEF,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,MAAuB;IAClE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,YAAY,KAAK,EAAE,EAAE;QAChE,OAAO,EAAE;YACP,eAAe,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;SAC3C;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAiB,CAAC;AAC9C,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAgB;IAC7C,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;;UAEJ,GAAG,CAAC,EAAE;;kBAEE;aACX;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;oBACxB,cAAc,EAAE,GAAG,CAAC,cAAc;oBAClC,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,eAAe,EAAE,GAAG,CAAC,eAAe;oBACpC,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;iBAC3B,EAAE,IAAI,EAAE,CAAC,CAAC;aACZ;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAgB;IAC1C,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;;UAEF,GAAG,CAAC,EAAE;SACP,GAAG,CAAC,KAAK,IAAI,eAAe,EAAE;aAClC,CAAC;QACF,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAgB;IAC3C,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;;UAEF,GAAG,CAAC,EAAE;;8CAE8B;aACzC,CAAC;QACF,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAuB,EACvB,MAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACvE,MAAM,mBAAmB,GAAG,CAAC,CAAC,CAAC,uBAAuB;QAEtD,8BAA8B;QAC9B,OAAO,CAAC,KAAK,CAAC,qDAAqD,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;QACpF,IAAI,GAAG,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAEnD,mDAAmD;QACnD,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACzD,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACtD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACzD,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QAED,iEAAiE;QACjE,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,MAAM,mBAAmB,mBAAmB,eAAe,WAAW,MAAM,CAAC,CAAC;QAEjI,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC;QACrC,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,OAAO,IAAI,EAAE,CAAC;YACZ,6BAA6B;YAC7B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC,CAAC,CAAC;YAC9E,cAAc,IAAI,mBAAmB,CAAC;YAEtC,4CAA4C;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACvC,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,8CAA8C,WAAW,GAAG,CAAC,CAAC;gBAC5E,MAAM;YACR,CAAC;YAED,eAAe;YACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,cAAc,eAAe,CAAC,CAAC;YAClF,GAAG,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAE/C,wBAAwB;YACxB,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC/B,OAAO,CAAC,KAAK,CAAC,yCAAyC,cAAc,GAAG,CAAC,CAAC;gBAC1E,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC5B,OAAO,CAAC,KAAK,CAAC,sCAAsC,cAAc,GAAG,CAAC,CAAC;gBACvE,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,KAAK,CAAC,yCAAyC,cAAc,GAAG,CAAC,CAAC;gBAC1E,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,MAAM,yBAAyB,CAAC,CAAC;QACpF,CAAC;QAED,2CAA2C;QAC3C,MAAM,WAAW,GAA2B;YAC1C,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,IAAI;SAClB,CAAC;QACF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;QACjD,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,KAAK,SAAS;YAC5C,CAAC,CAAC,2CAA2C;YAC7C,CAAC,CAAC,uCAAuC,CAAC;QAE5C,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,GAAG,KAAK,gBAAgB,GAAG,CAAC,MAAM;;UAEtC,GAAG,CAAC,EAAE;;EAEd,aAAa;;WAEJ,WAAW,oBAAoB,mBAAmB;;8DAEC,QAAQ;6CACzB;iBACtC,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;EAEZ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;iBACrD,CAAC;YACF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"wait-for-result.tool.js","sourceRoot":"","sources":["../../src/tools/wait-for-result.tool.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * MCP Server Configuration Types
3
3
  */
4
4
  export interface McpServerConfig {
5
- /** Base URL of the RunHuman API */
5
+ /** Base URL of the Runhuman API */
6
6
  apiUrl: string;
7
7
  /** API key for authentication */
8
8
  apiKey: string;
@@ -14,6 +14,8 @@ export interface CreateJobArgs {
14
14
  targetDurationMinutes?: number;
15
15
  allowDurationExtension?: boolean;
16
16
  maxExtensionMinutes?: number | boolean;
17
+ /** Custom instructions for the AI when validating test results */
18
+ additionalValidationInstructions?: string;
17
19
  }
18
20
  export interface WaitForResultArgs {
19
21
  jobId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE;QACX,mBAAmB,EAAE,MAAM,CAAC;QAC5B,eAAe,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC7E,eAAe,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC5F,MAAM,EAAE,KAAK,CAAC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,kEAAkE;IAClE,gCAAgC,CAAC,EAAE,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE;QACX,mBAAmB,EAAE,MAAM,CAAC;QAC5B,eAAe,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC7E,eAAe,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC5F,MAAM,EAAE,KAAK,CAAC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB"}
package/package.json CHANGED
@@ -1,78 +1,78 @@
1
- {
2
- "name": "@runhuman/mcp-server",
3
- "version": "2.0.4",
4
- "description": "Model Context Protocol (MCP) server for RunHuman - Human-powered QA testing for AI agents",
5
- "main": "dist/lib.js",
6
- "type": "module",
7
- "exports": {
8
- ".": {
9
- "import": "./dist/lib.js",
10
- "require": "./dist/lib.js",
11
- "types": "./dist/lib.d.ts"
12
- },
13
- "./factory": {
14
- "import": "./dist/mcp-server-factory.js",
15
- "types": "./dist/mcp-server-factory.d.ts"
16
- },
17
- "./types": {
18
- "import": "./dist/types.js",
19
- "types": "./dist/types.d.ts"
20
- }
21
- },
22
- "bin": {
23
- "runhuman-mcp": "dist/index.js"
24
- },
25
- "files": [
26
- "dist",
27
- "README.md",
28
- ".env.example"
29
- ],
30
- "scripts": {
31
- "build": "tsc",
32
- "dev": "tsx watch src/index.ts",
33
- "start": "node dist/index.js",
34
- "prepublishOnly": "npm run build",
35
- "type-check": "tsc",
36
- "test": "node test-simple.cjs",
37
- "test:all": "node test-all-tools.cjs",
38
- "test:routes": "node test-route-fix.cjs",
39
- "test:endpoints": "node test-api-endpoints.cjs",
40
- "test:ci": "npm run test:endpoints && npm run test:routes",
41
- "test:inspector": "npx @modelcontextprotocol/inspector node dist/index.js"
42
- },
43
- "keywords": [
44
- "mcp",
45
- "model-context-protocol",
46
- "qa",
47
- "testing",
48
- "human-in-the-loop",
49
- "ai-agent",
50
- "claude",
51
- "anthropic",
52
- "qa-testing",
53
- "manual-testing"
54
- ],
55
- "author": "RunHuman <hey@runhuman.com>",
56
- "repository": {
57
- "type": "git",
58
- "url": "git+https://github.com/yueranyuan/qa-experiment.git",
59
- "directory": "packages/mcp-server"
60
- },
61
- "homepage": "https://runhuman.com",
62
- "bugs": {
63
- "url": "https://github.com/yueranyuan/qa-experiment/issues"
64
- },
65
- "license": "ISC",
66
- "engines": {
67
- "node": ">=18.0.0"
68
- },
69
- "dependencies": {
70
- "@modelcontextprotocol/sdk": "latest",
71
- "dotenv": "^17.2.3"
72
- },
73
- "devDependencies": {
74
- "@types/node": "^20.11.17",
75
- "tsx": "^4.7.1",
76
- "typescript": "^5.3.3"
77
- }
78
- }
1
+ {
2
+ "name": "@runhuman/mcp-server",
3
+ "version": "2.0.5",
4
+ "description": "Model Context Protocol (MCP) server for Runhuman - Human-powered QA testing for AI agents",
5
+ "main": "dist/lib.js",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/lib.js",
10
+ "require": "./dist/lib.js",
11
+ "types": "./dist/lib.d.ts"
12
+ },
13
+ "./factory": {
14
+ "import": "./dist/mcp-server-factory.js",
15
+ "types": "./dist/mcp-server-factory.d.ts"
16
+ },
17
+ "./types": {
18
+ "import": "./dist/types.js",
19
+ "types": "./dist/types.d.ts"
20
+ }
21
+ },
22
+ "bin": {
23
+ "runhuman-mcp": "dist/index.js"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ ".env.example"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "dev": "tsx watch src/index.ts",
33
+ "start": "node dist/index.js",
34
+ "prepublishOnly": "npm run build",
35
+ "type-check": "tsc",
36
+ "test": "node test-simple.cjs",
37
+ "test:all": "node test-all-tools.cjs",
38
+ "test:routes": "node test-route-fix.cjs",
39
+ "test:endpoints": "node test-api-endpoints.cjs",
40
+ "test:ci": "npm run test:endpoints && npm run test:routes",
41
+ "test:inspector": "npx @modelcontextprotocol/inspector node dist/index.js"
42
+ },
43
+ "keywords": [
44
+ "mcp",
45
+ "model-context-protocol",
46
+ "qa",
47
+ "testing",
48
+ "human-in-the-loop",
49
+ "ai-agent",
50
+ "claude",
51
+ "anthropic",
52
+ "qa-testing",
53
+ "manual-testing"
54
+ ],
55
+ "author": "Runhuman <hey@runhuman.com>",
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "git+https://github.com/yueranyuan/qa-experiment.git",
59
+ "directory": "packages/mcp-server"
60
+ },
61
+ "homepage": "https://runhuman.com",
62
+ "bugs": {
63
+ "url": "https://github.com/yueranyuan/qa-experiment/issues"
64
+ },
65
+ "license": "ISC",
66
+ "engines": {
67
+ "node": ">=18.0.0"
68
+ },
69
+ "dependencies": {
70
+ "@modelcontextprotocol/sdk": "latest",
71
+ "dotenv": "^17.2.3"
72
+ },
73
+ "devDependencies": {
74
+ "@types/node": "^20.11.17",
75
+ "tsx": "^4.7.1",
76
+ "typescript": "^5.3.3"
77
+ }
78
+ }