@runhuman/mcp-server 1.0.1 → 1.1.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.
- package/.env.example +12 -12
- package/README.md +219 -206
- package/dist/index.js +98 -112
- package/dist/index.js.map +1 -1
- package/package.json +62 -59
package/.env.example
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# RunHuman API Configuration
|
|
2
|
-
|
|
3
|
-
# API Base URL
|
|
4
|
-
# For local development, use http://localhost:
|
|
5
|
-
# For production, use your deployed API URL
|
|
6
|
-
RUNHUMAN_API_URL=http://localhost:
|
|
7
|
-
|
|
8
|
-
# API Key
|
|
9
|
-
# Get this from the API dashboard at http://localhost:
|
|
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,206 +1,219 @@
|
|
|
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://
|
|
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
|
-
|
|
58
|
-
#### `get_job_status`
|
|
59
|
-
Get the current status of a QA job.
|
|
60
|
-
|
|
61
|
-
**Parameters:**
|
|
62
|
-
- `jobId` (string): The ID of the job to check
|
|
63
|
-
|
|
64
|
-
#### `get_job_result`
|
|
65
|
-
Get the results of a completed QA job.
|
|
66
|
-
|
|
67
|
-
**Parameters:**
|
|
68
|
-
- `jobId` (string): The ID of the completed job
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
###
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
The
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
##
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
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/app.html
|
|
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
|
+
|
|
58
|
+
#### `get_job_status`
|
|
59
|
+
Get the current status of a QA job.
|
|
60
|
+
|
|
61
|
+
**Parameters:**
|
|
62
|
+
- `jobId` (string): The ID of the job to check
|
|
63
|
+
|
|
64
|
+
#### `get_job_result`
|
|
65
|
+
Get the results of a completed QA job.
|
|
66
|
+
|
|
67
|
+
**Parameters:**
|
|
68
|
+
- `jobId` (string): The ID of the completed job
|
|
69
|
+
|
|
70
|
+
**Returns:**
|
|
71
|
+
- `result`: Structured test results extracted from tester's response
|
|
72
|
+
- `status`: Job status (completed, failed, etc.)
|
|
73
|
+
- `costUsd`: Exact cost in USD with full precision (e.g., 0.396)
|
|
74
|
+
- `testDurationSeconds`: Time spent by tester in seconds (rounded up)
|
|
75
|
+
- Additional metadata (timestamps, tester info, etc.)
|
|
76
|
+
|
|
77
|
+
**Cost Calculation:**
|
|
78
|
+
- Costs are calculated as: `duration × $0.0018/second` (general-use tier)
|
|
79
|
+
- Duration is always rounded UP using Math.ceil (any partial second counts)
|
|
80
|
+
- Costs are never $0 unless the tester never actually worked on it
|
|
81
|
+
- Full precision maintained (not rounded to cents)
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
The MCP server needs to be configured with your RunHuman API credentials.
|
|
86
|
+
|
|
87
|
+
### 1. Get an API Key
|
|
88
|
+
|
|
89
|
+
**Option A: Via Dashboard**
|
|
90
|
+
1. Start the API server: `npm run dev --workspace=@runhuman/api`
|
|
91
|
+
2. Open http://localhost:3400/app.html
|
|
92
|
+
3. Go to "API Keys" tab
|
|
93
|
+
4. Click "Create API Key"
|
|
94
|
+
5. Copy the key (starts with `qa_live_`)
|
|
95
|
+
|
|
96
|
+
**Option B: Use Default Test Key**
|
|
97
|
+
- For local development, you can use: `qa_live_test_key_123`
|
|
98
|
+
- This key exists in `packages/api/data/api-keys.json`
|
|
99
|
+
|
|
100
|
+
### 2. Configure Environment Variables
|
|
101
|
+
|
|
102
|
+
Create a `.env` file in the MCP server directory:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# For local development
|
|
106
|
+
RUNHUMAN_API_URL=http://localhost:3400
|
|
107
|
+
RUNHUMAN_API_KEY=qa_live_test_key_123
|
|
108
|
+
|
|
109
|
+
# For production
|
|
110
|
+
RUNHUMAN_API_URL=https://api.runhuman.com
|
|
111
|
+
RUNHUMAN_API_KEY=qa_live_xxxxxxxxxxxxxxxxxxxxx
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Important:** Never commit `.env` files to git! They're already in `.gitignore`.
|
|
115
|
+
|
|
116
|
+
### 3. Verify Configuration
|
|
117
|
+
|
|
118
|
+
Test your API key works:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
curl http://localhost:3400/api/jobs \
|
|
122
|
+
-H "Authorization: Bearer qa_live_test_key_123" \
|
|
123
|
+
-H "Content-Type: application/json" \
|
|
124
|
+
-d '{"url":"https://example.com","description":"test","outputSchema":{}}'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Should return a job ID if authentication works.
|
|
128
|
+
|
|
129
|
+
For more details, see [docs/API-AUTHENTICATION.md](docs/API-AUTHENTICATION.md)
|
|
130
|
+
|
|
131
|
+
## Testing
|
|
132
|
+
|
|
133
|
+
The MCP server includes automated tests to verify it's working correctly:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Build first
|
|
137
|
+
npm run build --workspace=@runhuman/mcp-server
|
|
138
|
+
|
|
139
|
+
# Run simple automated test
|
|
140
|
+
npm run test --workspace=@runhuman/mcp-server
|
|
141
|
+
|
|
142
|
+
# Or use the MCP Inspector (interactive testing)
|
|
143
|
+
npm run test:inspector --workspace=@runhuman/mcp-server
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The test script will:
|
|
147
|
+
1. ✅ Initialize a connection to the MCP server
|
|
148
|
+
2. ✅ List all available tools (create_job, get_job_status, get_job_result)
|
|
149
|
+
3. ✅ Test calling the create_job tool
|
|
150
|
+
|
|
151
|
+
### Expected Test Output
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
✅ Server initialized successfully
|
|
155
|
+
✅ Tools listed: create_job, get_job_status, get_job_result
|
|
156
|
+
✅ create_job tool called successfully
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Development
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Watch mode (auto-rebuild on changes)
|
|
163
|
+
npm run dev --workspace=@runhuman/mcp-server
|
|
164
|
+
|
|
165
|
+
# Build
|
|
166
|
+
npm run build --workspace=@runhuman/mcp-server
|
|
167
|
+
|
|
168
|
+
# Test after building
|
|
169
|
+
npm run test --workspace=@runhuman/mcp-server
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Integration with Claude Desktop
|
|
173
|
+
|
|
174
|
+
To use this MCP server with Claude Desktop, add it to your configuration:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"mcpServers": {
|
|
179
|
+
"runhuman": {
|
|
180
|
+
"command": "node",
|
|
181
|
+
"args": ["/path/to/qa-experiment/packages/mcp-server/dist/index.js"]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Example Usage
|
|
188
|
+
|
|
189
|
+
Once connected to an AI agent (like Claude), the agent can use these tools naturally:
|
|
190
|
+
|
|
191
|
+
**User:** "Can someone test my checkout page at https://myapp.com/checkout?"
|
|
192
|
+
|
|
193
|
+
**Agent uses create_job:**
|
|
194
|
+
```
|
|
195
|
+
✅ Job created successfully!
|
|
196
|
+
Job ID: job_abc123
|
|
197
|
+
Status: pending
|
|
198
|
+
...
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Agent polls get_job_status until complete, then calls get_job_result:**
|
|
202
|
+
```
|
|
203
|
+
✅ Test completed!
|
|
204
|
+
Results Summary:
|
|
205
|
+
- Checkout Flow: ✅ Working
|
|
206
|
+
- Payment Processing: ✅ Successful
|
|
207
|
+
...
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Developer Documentation
|
|
211
|
+
|
|
212
|
+
For developers working on this MCP server:
|
|
213
|
+
- [docs/HOW-AGENTS-USE-MCP.md](docs/HOW-AGENTS-USE-MCP.md) - How AI agents discover and use MCP servers
|
|
214
|
+
- [docs/TOOL-RESPONSE-BEST-PRACTICES.md](docs/TOOL-RESPONSE-BEST-PRACTICES.md) - Best practices for tool responses
|
|
215
|
+
|
|
216
|
+
## Learn More
|
|
217
|
+
|
|
218
|
+
- [Model Context Protocol Documentation](https://modelcontextprotocol.io/)
|
|
219
|
+
- [RunHuman API Documentation](../api/README.md)
|
package/dist/index.js
CHANGED
|
@@ -75,22 +75,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
75
75
|
tools: [
|
|
76
76
|
{
|
|
77
77
|
name: 'create_job',
|
|
78
|
-
description: `⚠️ IMPORTANT: This ONLY creates and queues a job. It does NOT perform the test or return results. You MUST follow up with get_job_status and get_job_result.
|
|
79
|
-
|
|
80
|
-
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.
|
|
81
|
-
|
|
82
|
-
Use this when you need human verification of:
|
|
83
|
-
- UI/UX functionality that's hard to automate
|
|
84
|
-
- Visual issues, accessibility problems
|
|
85
|
-
- Complex user flows (login, checkout, forms)
|
|
86
|
-
- Cross-browser compatibility
|
|
87
|
-
- Real user experience feedback
|
|
88
|
-
|
|
89
|
-
⚠️ REQUIRED WORKFLOW (do NOT skip steps):
|
|
90
|
-
1. create_job → Returns jobId (job is now QUEUED, not complete!)
|
|
91
|
-
2. get_job_status → Poll every 30-60 seconds until status="completed" (takes 2-10 min)
|
|
92
|
-
3. get_job_result → Retrieve the actual test results
|
|
93
|
-
|
|
78
|
+
description: `⚠️ IMPORTANT: This ONLY creates and queues a job. It does NOT perform the test or return results. You MUST follow up with get_job_status and get_job_result.
|
|
79
|
+
|
|
80
|
+
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.
|
|
81
|
+
|
|
82
|
+
Use this when you need human verification of:
|
|
83
|
+
- UI/UX functionality that's hard to automate
|
|
84
|
+
- Visual issues, accessibility problems
|
|
85
|
+
- Complex user flows (login, checkout, forms)
|
|
86
|
+
- Cross-browser compatibility
|
|
87
|
+
- Real user experience feedback
|
|
88
|
+
|
|
89
|
+
⚠️ REQUIRED WORKFLOW (do NOT skip steps):
|
|
90
|
+
1. create_job → Returns jobId (job is now QUEUED, not complete!)
|
|
91
|
+
2. get_job_status → Poll every 30-60 seconds until status="completed" (takes 2-10 min)
|
|
92
|
+
3. get_job_result → Retrieve the actual test results
|
|
93
|
+
|
|
94
94
|
DO NOT treat job creation as completion. You MUST wait for and retrieve results.`,
|
|
95
95
|
inputSchema: {
|
|
96
96
|
type: 'object',
|
|
@@ -107,16 +107,20 @@ DO NOT treat job creation as completion. You MUST wait for and retrieve results.
|
|
|
107
107
|
type: 'object',
|
|
108
108
|
description: 'JSON Schema defining the structure you want extracted from the tester\'s response. Example: { "type": "object", "properties": { "checkoutWorks": { "type": "boolean" }, "totalIsCorrect": { "type": "boolean" }, "issues": { "type": "array", "items": { "type": "string" } } } }',
|
|
109
109
|
},
|
|
110
|
+
targetDurationMinutes: {
|
|
111
|
+
type: 'number',
|
|
112
|
+
description: 'Time limit in minutes for the tester to complete the test after claiming. Default: 5 minutes. Range: 1-60.',
|
|
113
|
+
},
|
|
110
114
|
},
|
|
111
115
|
required: ['url', 'description', 'schema'],
|
|
112
116
|
},
|
|
113
117
|
},
|
|
114
118
|
{
|
|
115
119
|
name: 'get_job_status',
|
|
116
|
-
description: `Check the current status of a QA job. Jobs progress through states: pending → claimed → in_progress → completed (or failed/timeout).
|
|
117
|
-
|
|
118
|
-
Use this to poll for completion before fetching results. Typical job completion time is 2-10 minutes depending on test complexity.
|
|
119
|
-
|
|
120
|
+
description: `Check the current status of a QA job. Jobs progress through states: pending → claimed → in_progress → completed (or failed/timeout).
|
|
121
|
+
|
|
122
|
+
Use this to poll for completion before fetching results. Typical job completion time is 2-10 minutes depending on test complexity.
|
|
123
|
+
|
|
120
124
|
Returns: { status: "pending" | "claimed" | "in_progress" | "completed" | "failed" | "timeout", message: "..." }`,
|
|
121
125
|
inputSchema: {
|
|
122
126
|
type: 'object',
|
|
@@ -131,10 +135,10 @@ Returns: { status: "pending" | "claimed" | "in_progress" | "completed" | "failed
|
|
|
131
135
|
},
|
|
132
136
|
{
|
|
133
137
|
name: 'get_job_result',
|
|
134
|
-
description: `Get the structured results of a completed QA job. Only call this after get_job_status shows status="completed".
|
|
135
|
-
|
|
136
|
-
Returns the tester's response extracted into your specified schema, plus metadata about timing and the raw tester response.
|
|
137
|
-
|
|
138
|
+
description: `Get the structured results of a completed QA job. Only call this after get_job_status shows status="completed".
|
|
139
|
+
|
|
140
|
+
Returns the tester's response extracted into your specified schema, plus metadata about timing and the raw tester response.
|
|
141
|
+
|
|
138
142
|
If the job isn't complete yet, returns an error. If extraction failed, includes the raw response so you can see what the tester said.`,
|
|
139
143
|
inputSchema: {
|
|
140
144
|
type: 'object',
|
|
@@ -171,7 +175,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
171
175
|
body: JSON.stringify({
|
|
172
176
|
url: args.url,
|
|
173
177
|
description: args.description,
|
|
174
|
-
outputSchema: args.schema
|
|
178
|
+
outputSchema: args.schema,
|
|
179
|
+
targetDurationMinutes: args.targetDurationMinutes,
|
|
175
180
|
})
|
|
176
181
|
});
|
|
177
182
|
if (!response.ok) {
|
|
@@ -179,38 +184,40 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
179
184
|
return {
|
|
180
185
|
content: [{
|
|
181
186
|
type: 'text',
|
|
182
|
-
text: `❌ Failed to create job
|
|
183
|
-
|
|
184
|
-
Error: ${error.error || error.message || response.statusText}
|
|
185
|
-
Status: ${response.status}
|
|
186
|
-
|
|
187
|
-
Please check:
|
|
188
|
-
- Your RUNHUMAN_API_KEY is valid
|
|
189
|
-
- The API server is running at ${API_URL}
|
|
187
|
+
text: `❌ Failed to create job
|
|
188
|
+
|
|
189
|
+
Error: ${error.error || error.message || response.statusText}
|
|
190
|
+
Status: ${response.status}
|
|
191
|
+
|
|
192
|
+
Please check:
|
|
193
|
+
- Your RUNHUMAN_API_KEY is valid
|
|
194
|
+
- The API server is running at ${API_URL}
|
|
190
195
|
- Your API key has permission to create jobs`
|
|
191
196
|
}],
|
|
192
197
|
isError: true
|
|
193
198
|
};
|
|
194
199
|
}
|
|
195
200
|
const data = await response.json();
|
|
201
|
+
const duration = args.targetDurationMinutes || 5;
|
|
196
202
|
return {
|
|
197
203
|
content: [
|
|
198
204
|
{
|
|
199
205
|
type: 'text',
|
|
200
|
-
text: `⏳ Job QUEUED (not complete yet!)
|
|
201
|
-
|
|
202
|
-
Job ID: ${data.jobId}
|
|
203
|
-
Status: ${data.status}
|
|
204
|
-
URL: ${args.url}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
text: `⏳ Job QUEUED (not complete yet!)
|
|
207
|
+
|
|
208
|
+
Job ID: ${data.jobId}
|
|
209
|
+
Status: ${data.status}
|
|
210
|
+
URL: ${args.url}
|
|
211
|
+
Time limit: ${duration} minutes
|
|
212
|
+
|
|
213
|
+
The test has been queued for a HUMAN tester. It is NOT complete yet.
|
|
214
|
+
|
|
215
|
+
⚠️ REQUIRED NEXT STEPS:
|
|
216
|
+
1. Wait 30-60 seconds
|
|
217
|
+
2. Call get_job_status(jobId: "${data.jobId}") to check if complete
|
|
218
|
+
3. Repeat step 2 until status="completed" (typical time: 2-10 minutes)
|
|
219
|
+
4. Call get_job_result(jobId: "${data.jobId}") to get the actual test results
|
|
220
|
+
|
|
214
221
|
DO NOT consider this task done until you have retrieved the results!`,
|
|
215
222
|
},
|
|
216
223
|
],
|
|
@@ -220,13 +227,13 @@ DO NOT consider this task done until you have retrieved the results!`,
|
|
|
220
227
|
return {
|
|
221
228
|
content: [{
|
|
222
229
|
type: 'text',
|
|
223
|
-
text: `❌ Error creating job
|
|
224
|
-
|
|
225
|
-
${error instanceof Error ? error.message : 'Unknown error'}
|
|
226
|
-
|
|
227
|
-
Please check:
|
|
228
|
-
- The API server is running at ${API_URL}
|
|
229
|
-
- Your network connection
|
|
230
|
+
text: `❌ Error creating job
|
|
231
|
+
|
|
232
|
+
${error instanceof Error ? error.message : 'Unknown error'}
|
|
233
|
+
|
|
234
|
+
Please check:
|
|
235
|
+
- The API server is running at ${API_URL}
|
|
236
|
+
- Your network connection
|
|
230
237
|
- Your .env file configuration`
|
|
231
238
|
}],
|
|
232
239
|
isError: true
|
|
@@ -234,7 +241,7 @@ Please check:
|
|
|
234
241
|
}
|
|
235
242
|
case 'get_job_status':
|
|
236
243
|
try {
|
|
237
|
-
const response = await fetch(`${API_URL}/api/
|
|
244
|
+
const response = await fetch(`${API_URL}/api/job/${args.jobId}`, {
|
|
238
245
|
headers: {
|
|
239
246
|
'Authorization': `Bearer ${API_KEY}`
|
|
240
247
|
}
|
|
@@ -244,10 +251,10 @@ Please check:
|
|
|
244
251
|
return {
|
|
245
252
|
content: [{
|
|
246
253
|
type: 'text',
|
|
247
|
-
text: `❌ Job not found
|
|
248
|
-
|
|
249
|
-
Job ID: ${args.jobId}
|
|
250
|
-
|
|
254
|
+
text: `❌ Job not found
|
|
255
|
+
|
|
256
|
+
Job ID: ${args.jobId}
|
|
257
|
+
|
|
251
258
|
The job does not exist or you don't have permission to access it.`
|
|
252
259
|
}],
|
|
253
260
|
isError: true
|
|
@@ -256,22 +263,15 @@ The job does not exist or you don't have permission to access it.`
|
|
|
256
263
|
return {
|
|
257
264
|
content: [{
|
|
258
265
|
type: 'text',
|
|
259
|
-
text: `❌ Failed to get job status
|
|
260
|
-
|
|
261
|
-
Status: ${response.status}
|
|
266
|
+
text: `❌ Failed to get job status
|
|
267
|
+
|
|
268
|
+
Status: ${response.status}
|
|
262
269
|
Error: ${response.statusText}`
|
|
263
270
|
}],
|
|
264
271
|
isError: true
|
|
265
272
|
};
|
|
266
273
|
}
|
|
267
274
|
const job = await response.json();
|
|
268
|
-
// Format timeline
|
|
269
|
-
const createdAt = new Date(job.createdAt);
|
|
270
|
-
const now = new Date();
|
|
271
|
-
const elapsed = Math.floor((now.getTime() - createdAt.getTime()) / 1000 / 60);
|
|
272
|
-
// Calculate estimated time remaining (typical completion: 2-10 min, let's use 6 min average)
|
|
273
|
-
const typicalCompletionMin = 6;
|
|
274
|
-
const estimatedRemaining = Math.max(0, typicalCompletionMin - elapsed);
|
|
275
275
|
const statusEmoji = {
|
|
276
276
|
pending: '⏳',
|
|
277
277
|
claimed: '👤',
|
|
@@ -281,30 +281,20 @@ Error: ${response.statusText}`
|
|
|
281
281
|
timeout: '⏰'
|
|
282
282
|
};
|
|
283
283
|
const emoji = statusEmoji[job.status] || '📊';
|
|
284
|
-
let message = `${emoji} Job Status: ${job.status}
|
|
285
|
-
|
|
286
|
-
Job ID: ${job.id}
|
|
287
|
-
URL: ${job.url}
|
|
288
|
-
|
|
289
|
-
Timeline:
|
|
290
|
-
- Created: ${elapsed} minute${elapsed !== 1 ? 's' : ''} ago`;
|
|
291
|
-
if (job.claimedAt) {
|
|
292
|
-
const claimedElapsed = Math.floor((now.getTime() - new Date(job.claimedAt).getTime()) / 1000 / 60);
|
|
293
|
-
message += `\n- Claimed: ${claimedElapsed} minute${claimedElapsed !== 1 ? 's' : ''} ago`;
|
|
294
|
-
}
|
|
284
|
+
let message = `${emoji} Job Status: ${job.status}
|
|
285
|
+
|
|
286
|
+
Job ID: ${job.id}`;
|
|
295
287
|
if (job.status === 'pending') {
|
|
296
|
-
message +=
|
|
297
|
-
message += '\n\nWaiting for a tester to claim this job...';
|
|
288
|
+
message += '\n\nWaiting for a tester to claim this job...\nTypical completion time: 2-10 minutes';
|
|
298
289
|
}
|
|
299
290
|
else if (job.status === 'claimed' || job.status === 'in_progress') {
|
|
300
|
-
message +=
|
|
301
|
-
message += '\n\nThe tester is working on your test.';
|
|
291
|
+
message += '\n\nThe tester is working on your test...\nTypical completion time: 2-10 minutes';
|
|
302
292
|
}
|
|
303
293
|
else if (job.status === 'completed') {
|
|
304
294
|
message += '\n\n✅ Job is complete! Use get_job_result to retrieve the results.';
|
|
305
295
|
}
|
|
306
296
|
else if (job.status === 'failed') {
|
|
307
|
-
message += '\n\n❌ Job failed. Check the error with get_job_result.';
|
|
297
|
+
message += '\n\n❌ Job failed.' + (job.error ? ` Error: ${job.error}` : ' Check the error with get_job_result.');
|
|
308
298
|
}
|
|
309
299
|
else if (job.status === 'timeout') {
|
|
310
300
|
message += '\n\n⏰ Job timed out. The tester did not complete in time.';
|
|
@@ -320,8 +310,8 @@ Timeline:
|
|
|
320
310
|
return {
|
|
321
311
|
content: [{
|
|
322
312
|
type: 'text',
|
|
323
|
-
text: `❌ Error checking job status
|
|
324
|
-
|
|
313
|
+
text: `❌ Error checking job status
|
|
314
|
+
|
|
325
315
|
${error instanceof Error ? error.message : 'Unknown error'}`
|
|
326
316
|
}],
|
|
327
317
|
isError: true
|
|
@@ -329,7 +319,7 @@ ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
|
329
319
|
}
|
|
330
320
|
case 'get_job_result':
|
|
331
321
|
try {
|
|
332
|
-
const response = await fetch(`${API_URL}/api/
|
|
322
|
+
const response = await fetch(`${API_URL}/api/job/${args.jobId}`, {
|
|
333
323
|
headers: {
|
|
334
324
|
'Authorization': `Bearer ${API_KEY}`
|
|
335
325
|
}
|
|
@@ -339,10 +329,10 @@ ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
|
339
329
|
return {
|
|
340
330
|
content: [{
|
|
341
331
|
type: 'text',
|
|
342
|
-
text: `❌ Job not found
|
|
343
|
-
|
|
344
|
-
Job ID: ${args.jobId}
|
|
345
|
-
|
|
332
|
+
text: `❌ Job not found
|
|
333
|
+
|
|
334
|
+
Job ID: ${args.jobId}
|
|
335
|
+
|
|
346
336
|
The job does not exist or you don't have permission to access it.`
|
|
347
337
|
}],
|
|
348
338
|
isError: true
|
|
@@ -351,9 +341,9 @@ The job does not exist or you don't have permission to access it.`
|
|
|
351
341
|
return {
|
|
352
342
|
content: [{
|
|
353
343
|
type: 'text',
|
|
354
|
-
text: `❌ Failed to get job result
|
|
355
|
-
|
|
356
|
-
Status: ${response.status}
|
|
344
|
+
text: `❌ Failed to get job result
|
|
345
|
+
|
|
346
|
+
Status: ${response.status}
|
|
357
347
|
Error: ${response.statusText}`
|
|
358
348
|
}],
|
|
359
349
|
isError: true
|
|
@@ -364,11 +354,11 @@ Error: ${response.statusText}`
|
|
|
364
354
|
return {
|
|
365
355
|
content: [{
|
|
366
356
|
type: 'text',
|
|
367
|
-
text: `⏳ Job not yet completed
|
|
368
|
-
|
|
369
|
-
Job ID: ${job.id}
|
|
370
|
-
Current status: ${job.status}
|
|
371
|
-
|
|
357
|
+
text: `⏳ Job not yet completed
|
|
358
|
+
|
|
359
|
+
Job ID: ${job.id}
|
|
360
|
+
Current status: ${job.status}
|
|
361
|
+
|
|
372
362
|
${job.status === 'pending' ? 'Waiting for a tester to claim this job...' :
|
|
373
363
|
job.status === 'claimed' || job.status === 'in_progress' ? 'The tester is working on your test...' :
|
|
374
364
|
job.status === 'failed' ? '❌ Job failed. Error: ' + (job.error || 'Unknown error') :
|
|
@@ -378,15 +368,11 @@ ${job.status === 'pending' ? 'Waiting for a tester to claim this job...' :
|
|
|
378
368
|
};
|
|
379
369
|
}
|
|
380
370
|
// Job is completed, format results
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
Job ID: ${job.id}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
**Tester Response:**
|
|
387
|
-
"${job.testerResponse || 'No response recorded'}"
|
|
388
|
-
|
|
389
|
-
**Extracted Data:**`;
|
|
371
|
+
const message = `✅ Test completed!
|
|
372
|
+
|
|
373
|
+
Job ID: ${job.id}
|
|
374
|
+
|
|
375
|
+
**Test Results:**`;
|
|
390
376
|
const contents = [
|
|
391
377
|
{
|
|
392
378
|
type: 'text',
|
|
@@ -400,7 +386,7 @@ URL: ${job.url}
|
|
|
400
386
|
if (job.error) {
|
|
401
387
|
contents.push({
|
|
402
388
|
type: 'text',
|
|
403
|
-
text: `\n⚠️
|
|
389
|
+
text: `\n⚠️ Note: ${job.error}`
|
|
404
390
|
});
|
|
405
391
|
}
|
|
406
392
|
return { content: contents };
|
|
@@ -409,8 +395,8 @@ URL: ${job.url}
|
|
|
409
395
|
return {
|
|
410
396
|
content: [{
|
|
411
397
|
type: 'text',
|
|
412
|
-
text: `❌ Error getting job result
|
|
413
|
-
|
|
398
|
+
text: `❌ Error getting job result
|
|
399
|
+
|
|
414
400
|
${error instanceof Error ? error.message : 'Unknown error'}`
|
|
415
401
|
}],
|
|
416
402
|
isError: true
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,59 +1,62 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@runhuman/mcp-server",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Model Context Protocol (MCP) server for RunHuman - Human-powered QA testing for AI agents",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"runhuman-mcp": "dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"dist",
|
|
12
|
-
"README.md",
|
|
13
|
-
".env.example"
|
|
14
|
-
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"build": "tsc",
|
|
17
|
-
"dev": "tsx watch src/index.ts",
|
|
18
|
-
"start": "node dist/index.js",
|
|
19
|
-
"prepublishOnly": "npm run build",
|
|
20
|
-
"test": "node test-simple.cjs",
|
|
21
|
-
"test:all": "node test-all-tools.cjs",
|
|
22
|
-
"test:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@runhuman/mcp-server",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Model Context Protocol (MCP) server for RunHuman - Human-powered QA testing for AI agents",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"runhuman-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
".env.example"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsx watch src/index.ts",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"test": "node test-simple.cjs",
|
|
21
|
+
"test:all": "node test-all-tools.cjs",
|
|
22
|
+
"test:routes": "node test-route-fix.cjs",
|
|
23
|
+
"test:endpoints": "node test-api-endpoints.cjs",
|
|
24
|
+
"test:ci": "npm run test:endpoints && npm run test:routes",
|
|
25
|
+
"test:inspector": "npx @modelcontextprotocol/inspector node dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"mcp",
|
|
29
|
+
"model-context-protocol",
|
|
30
|
+
"qa",
|
|
31
|
+
"testing",
|
|
32
|
+
"human-in-the-loop",
|
|
33
|
+
"ai-agent",
|
|
34
|
+
"claude",
|
|
35
|
+
"anthropic",
|
|
36
|
+
"qa-testing",
|
|
37
|
+
"manual-testing"
|
|
38
|
+
],
|
|
39
|
+
"author": "RunHuman <hey@runhuman.com>",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/yueranyuan/qa-experiment.git",
|
|
43
|
+
"directory": "packages/mcp-server"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://runhuman.com",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/yueranyuan/qa-experiment/issues"
|
|
48
|
+
},
|
|
49
|
+
"license": "ISC",
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.0.0"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@modelcontextprotocol/sdk": "latest",
|
|
55
|
+
"dotenv": "^17.2.3"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "^20.11.17",
|
|
59
|
+
"tsx": "^4.7.1",
|
|
60
|
+
"typescript": "^5.3.3"
|
|
61
|
+
}
|
|
62
|
+
}
|