@runhuman/mcp-server 2.0.0 → 2.0.2
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 +240 -219
- package/dist/index.js +193 -193
- package/dist/index.js.map +1 -1
- package/package.json +62 -62
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,219 +1,240 @@
|
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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://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
|
+
- `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
|
+
- Additional metadata (timestamps, tester info, etc.)
|
|
90
|
+
|
|
91
|
+
**Cost Calculation:**
|
|
92
|
+
- Costs are calculated as: `duration × $0.0018/second` (general-use tier)
|
|
93
|
+
- Duration is always rounded UP using Math.ceil (any partial second counts)
|
|
94
|
+
- Costs are never $0 unless the tester never actually worked on it
|
|
95
|
+
- Full precision maintained (not rounded to cents)
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
The MCP server needs to be configured with your RunHuman API credentials.
|
|
100
|
+
|
|
101
|
+
### 1. Get an API Key
|
|
102
|
+
|
|
103
|
+
**Option A: Via Dashboard**
|
|
104
|
+
1. Start the API server: `npm run dev --workspace=@runhuman/api`
|
|
105
|
+
2. Open http://localhost:3400/app.html
|
|
106
|
+
3. Go to "API Keys" tab
|
|
107
|
+
4. Click "Create API Key"
|
|
108
|
+
5. Copy the key (starts with `qa_live_`)
|
|
109
|
+
|
|
110
|
+
**Option B: Use Default Test Key**
|
|
111
|
+
- For local development, you can use: `qa_live_test_key_123`
|
|
112
|
+
- This key exists in `packages/api/data/api-keys.json`
|
|
113
|
+
|
|
114
|
+
### 2. Configure Environment Variables
|
|
115
|
+
|
|
116
|
+
Create a `.env` file in the MCP server directory:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# For local development
|
|
120
|
+
RUNHUMAN_API_URL=http://localhost:3400
|
|
121
|
+
RUNHUMAN_API_KEY=qa_live_test_key_123
|
|
122
|
+
|
|
123
|
+
# For production
|
|
124
|
+
RUNHUMAN_API_URL=https://api.runhuman.com
|
|
125
|
+
RUNHUMAN_API_KEY=qa_live_xxxxxxxxxxxxxxxxxxxxx
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Important:** Never commit `.env` files to git! They're already in `.gitignore`.
|
|
129
|
+
|
|
130
|
+
### 3. Verify Configuration
|
|
131
|
+
|
|
132
|
+
Test your API key works:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
curl http://localhost:3400/api/jobs \
|
|
136
|
+
-H "Authorization: Bearer qa_live_test_key_123" \
|
|
137
|
+
-H "Content-Type: application/json" \
|
|
138
|
+
-d '{"url":"https://example.com","description":"test","outputSchema":{}}'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Should return a job ID if authentication works.
|
|
142
|
+
|
|
143
|
+
For more details, see [docs/API-AUTHENTICATION.md](docs/API-AUTHENTICATION.md)
|
|
144
|
+
|
|
145
|
+
## Testing
|
|
146
|
+
|
|
147
|
+
The MCP server includes automated tests to verify it's working correctly:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Build first
|
|
151
|
+
npm run build --workspace=@runhuman/mcp-server
|
|
152
|
+
|
|
153
|
+
# Run simple automated test
|
|
154
|
+
npm run test --workspace=@runhuman/mcp-server
|
|
155
|
+
|
|
156
|
+
# Or use the MCP Inspector (interactive testing)
|
|
157
|
+
npm run test:inspector --workspace=@runhuman/mcp-server
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The test script will:
|
|
161
|
+
1. ✅ Initialize a connection to the MCP server
|
|
162
|
+
2. ✅ List all available tools (create_job, wait_for_result)
|
|
163
|
+
3. ✅ Test calling the create_job tool
|
|
164
|
+
|
|
165
|
+
### Expected Test Output
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
✅ Server initialized successfully
|
|
169
|
+
✅ Tools listed: create_job, wait_for_result
|
|
170
|
+
✅ create_job tool called successfully
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Development
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Watch mode (auto-rebuild on changes)
|
|
177
|
+
npm run dev --workspace=@runhuman/mcp-server
|
|
178
|
+
|
|
179
|
+
# Build
|
|
180
|
+
npm run build --workspace=@runhuman/mcp-server
|
|
181
|
+
|
|
182
|
+
# Test after building
|
|
183
|
+
npm run test --workspace=@runhuman/mcp-server
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Integration with Claude Desktop
|
|
187
|
+
|
|
188
|
+
To use this MCP server with Claude Desktop, add it to your configuration:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"mcpServers": {
|
|
193
|
+
"runhuman": {
|
|
194
|
+
"command": "node",
|
|
195
|
+
"args": ["/path/to/qa-experiment/packages/mcp-server/dist/index.js"]
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Example Usage
|
|
202
|
+
|
|
203
|
+
Once connected to an AI agent (like Claude), the agent can use these tools naturally:
|
|
204
|
+
|
|
205
|
+
**User:** "Can someone test my checkout page at https://myapp.com/checkout?"
|
|
206
|
+
|
|
207
|
+
**Agent uses create_job:**
|
|
208
|
+
```
|
|
209
|
+
✅ Job created successfully!
|
|
210
|
+
Job ID: job_abc123
|
|
211
|
+
Status: pending
|
|
212
|
+
...
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Agent calls wait_for_result repeatedly until complete:**
|
|
216
|
+
```
|
|
217
|
+
⏳ Job Status: in_progress
|
|
218
|
+
Waited 30s, job not complete yet.
|
|
219
|
+
💡 Suggestion: Call wait_for_result again with waitSeconds: 45
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Finally:**
|
|
223
|
+
```
|
|
224
|
+
✅ Test completed!
|
|
225
|
+
Results Summary:
|
|
226
|
+
- Checkout Flow: ✅ Working
|
|
227
|
+
- Payment Processing: ✅ Successful
|
|
228
|
+
...
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Developer Documentation
|
|
232
|
+
|
|
233
|
+
For developers working on this MCP server:
|
|
234
|
+
- [docs/HOW-AGENTS-USE-MCP.md](docs/HOW-AGENTS-USE-MCP.md) - How AI agents discover and use MCP servers
|
|
235
|
+
- [docs/TOOL-RESPONSE-BEST-PRACTICES.md](docs/TOOL-RESPONSE-BEST-PRACTICES.md) - Best practices for tool responses
|
|
236
|
+
|
|
237
|
+
## Learn More
|
|
238
|
+
|
|
239
|
+
- [Model Context Protocol Documentation](https://modelcontextprotocol.io/)
|
|
240
|
+
- [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
|
|
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.
|
|
92
|
-
3.
|
|
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 wait_for_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. wait_for_result → Checks status, waits, and retrieves results (takes 2-10 min total)
|
|
92
|
+
3. If not complete, call wait_for_result again with longer wait time
|
|
93
|
+
|
|
94
94
|
DO NOT treat job creation as completion. You MUST wait for and retrieve results.`,
|
|
95
95
|
inputSchema: {
|
|
96
96
|
type: 'object',
|
|
@@ -116,12 +116,24 @@ DO NOT treat job creation as completion. You MUST wait for and retrieve results.
|
|
|
116
116
|
},
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
|
-
name: '
|
|
120
|
-
description: `Check
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
name: 'wait_for_result',
|
|
120
|
+
description: `Check status, wait, and retrieve results for a QA job in a single call.
|
|
121
|
+
|
|
122
|
+
This tool combines status checking, waiting, and result retrieval into one convenient function:
|
|
123
|
+
- Checks status BEFORE waiting (returns immediately if already complete)
|
|
124
|
+
- Waits for the specified duration (default 30s, configurable 1-300s)
|
|
125
|
+
- Checks status AFTER waiting
|
|
126
|
+
- Returns results if complete, otherwise suggests calling again with longer wait
|
|
127
|
+
|
|
128
|
+
Jobs progress through states: pending → claimed → in_progress → completed (or failed/timeout)
|
|
129
|
+
Typical completion time: 2-10 minutes total
|
|
130
|
+
|
|
131
|
+
Use this tool repeatedly with increasing wait times until you get results:
|
|
132
|
+
- First call: wait_for_result(jobId, { waitSeconds: 30 })
|
|
133
|
+
- If not complete: wait_for_result(jobId, { waitSeconds: 45 })
|
|
134
|
+
- If still not complete: wait_for_result(jobId, { waitSeconds: 60 })
|
|
135
|
+
|
|
136
|
+
Returns immediately if job is already complete (no waiting needed).`,
|
|
125
137
|
inputSchema: {
|
|
126
138
|
type: 'object',
|
|
127
139
|
properties: {
|
|
@@ -129,23 +141,11 @@ Returns: { status: "pending" | "claimed" | "in_progress" | "completed" | "failed
|
|
|
129
141
|
type: 'string',
|
|
130
142
|
description: 'The job ID returned from create_job. Example: "550e8400-e29b-41d4-a716-446655440000"',
|
|
131
143
|
},
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
name: 'get_job_result',
|
|
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
|
-
|
|
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.`,
|
|
143
|
-
inputSchema: {
|
|
144
|
-
type: 'object',
|
|
145
|
-
properties: {
|
|
146
|
-
jobId: {
|
|
147
|
-
type: 'string',
|
|
148
|
-
description: 'The job ID of a completed job. Example: "550e8400-e29b-41d4-a716-446655440000"',
|
|
144
|
+
waitSeconds: {
|
|
145
|
+
type: 'number',
|
|
146
|
+
description: 'How long to wait (in seconds) before checking status again. Default: 30. Range: 1-300. Increase this on subsequent calls (30 → 45 → 60) for better efficiency.',
|
|
147
|
+
minimum: 1,
|
|
148
|
+
maximum: 300,
|
|
149
149
|
},
|
|
150
150
|
},
|
|
151
151
|
required: ['jobId'],
|
|
@@ -184,14 +184,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
184
184
|
return {
|
|
185
185
|
content: [{
|
|
186
186
|
type: 'text',
|
|
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}
|
|
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}
|
|
195
195
|
- Your API key has permission to create jobs`
|
|
196
196
|
}],
|
|
197
197
|
isError: true
|
|
@@ -203,21 +203,22 @@ Please check:
|
|
|
203
203
|
content: [
|
|
204
204
|
{
|
|
205
205
|
type: 'text',
|
|
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.
|
|
217
|
-
2.
|
|
218
|
-
3.
|
|
219
|
-
|
|
220
|
-
|
|
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. Call wait_for_result(jobId: "${data.jobId}", waitSeconds: 30)
|
|
217
|
+
2. If not complete, call wait_for_result again with waitSeconds: 45
|
|
218
|
+
3. Continue with increasing wait times (60, 90, etc.) until complete
|
|
219
|
+
|
|
220
|
+
Typical completion time: 2-10 minutes total.
|
|
221
|
+
|
|
221
222
|
DO NOT consider this task done until you have retrieved the results!`,
|
|
222
223
|
},
|
|
223
224
|
],
|
|
@@ -227,176 +228,175 @@ DO NOT consider this task done until you have retrieved the results!`,
|
|
|
227
228
|
return {
|
|
228
229
|
content: [{
|
|
229
230
|
type: 'text',
|
|
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
|
|
231
|
+
text: `❌ Error creating job
|
|
232
|
+
|
|
233
|
+
${error instanceof Error ? error.message : 'Unknown error'}
|
|
234
|
+
|
|
235
|
+
Please check:
|
|
236
|
+
- The API server is running at ${API_URL}
|
|
237
|
+
- Your network connection
|
|
237
238
|
- Your .env file configuration`
|
|
238
239
|
}],
|
|
239
240
|
isError: true
|
|
240
241
|
};
|
|
241
242
|
}
|
|
242
|
-
case '
|
|
243
|
+
case 'wait_for_result':
|
|
243
244
|
try {
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
const waitSeconds = Math.min(Math.max(args.waitSeconds || 30, 1), 300);
|
|
246
|
+
// Helper function to check job status
|
|
247
|
+
const checkJobStatus = async () => {
|
|
248
|
+
const response = await fetch(`${API_URL}/api/job/${args.jobId}`, {
|
|
249
|
+
headers: {
|
|
250
|
+
'Authorization': `Bearer ${API_KEY}`
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
if (!response.ok) {
|
|
254
|
+
if (response.status === 404) {
|
|
255
|
+
throw new Error(`Job not found: ${args.jobId}`);
|
|
256
|
+
}
|
|
257
|
+
throw new Error(`Failed to get job status: ${response.status} ${response.statusText}`);
|
|
247
258
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
259
|
+
return await response.json();
|
|
260
|
+
};
|
|
261
|
+
// Check status BEFORE waiting
|
|
262
|
+
console.error(`[wait_for_result] Checking initial status for job ${args.jobId}...`);
|
|
263
|
+
let job = await checkJobStatus();
|
|
264
|
+
// If already complete, return immediately
|
|
265
|
+
if (job.status === 'completed' || job.status === 'failed' || job.status === 'timeout') {
|
|
266
|
+
console.error(`[wait_for_result] Job already in terminal state: ${job.status}`);
|
|
267
|
+
if (job.status === 'completed') {
|
|
268
|
+
return {
|
|
269
|
+
content: [
|
|
270
|
+
{
|
|
271
|
+
type: 'text',
|
|
272
|
+
text: `✅ Test completed!
|
|
273
|
+
|
|
274
|
+
Job ID: ${job.id}
|
|
275
|
+
|
|
276
|
+
**Test Results:**`
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
type: 'text',
|
|
280
|
+
text: JSON.stringify({
|
|
281
|
+
result: job.result || {},
|
|
282
|
+
testerData: job.testerData
|
|
283
|
+
}, null, 2)
|
|
284
|
+
}
|
|
285
|
+
]
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
else if (job.status === 'failed') {
|
|
251
289
|
return {
|
|
252
290
|
content: [{
|
|
253
291
|
type: 'text',
|
|
254
|
-
text: `❌ Job
|
|
255
|
-
|
|
256
|
-
Job ID: ${
|
|
257
|
-
|
|
258
|
-
|
|
292
|
+
text: `❌ Job failed
|
|
293
|
+
|
|
294
|
+
Job ID: ${job.id}
|
|
295
|
+
Error: ${job.error || 'Unknown error'}`
|
|
296
|
+
}],
|
|
297
|
+
isError: true
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
else { // timeout
|
|
301
|
+
return {
|
|
302
|
+
content: [{
|
|
303
|
+
type: 'text',
|
|
304
|
+
text: `⏰ Job timed out
|
|
305
|
+
|
|
306
|
+
Job ID: ${job.id}
|
|
307
|
+
|
|
308
|
+
The tester did not complete the test in time.`
|
|
259
309
|
}],
|
|
260
310
|
isError: true
|
|
261
311
|
};
|
|
262
312
|
}
|
|
263
|
-
return {
|
|
264
|
-
content: [{
|
|
265
|
-
type: 'text',
|
|
266
|
-
text: `❌ Failed to get job status
|
|
267
|
-
|
|
268
|
-
Status: ${response.status}
|
|
269
|
-
Error: ${response.statusText}`
|
|
270
|
-
}],
|
|
271
|
-
isError: true
|
|
272
|
-
};
|
|
273
313
|
}
|
|
274
|
-
|
|
314
|
+
// Job not complete yet, wait and check again
|
|
315
|
+
console.error(`[wait_for_result] Job status: ${job.status}. Waiting ${waitSeconds} seconds...`);
|
|
275
316
|
const statusEmoji = {
|
|
276
317
|
pending: '⏳',
|
|
277
318
|
claimed: '👤',
|
|
278
|
-
in_progress: '🔄'
|
|
279
|
-
completed: '✅',
|
|
280
|
-
failed: '❌',
|
|
281
|
-
timeout: '⏰'
|
|
319
|
+
in_progress: '🔄'
|
|
282
320
|
};
|
|
283
321
|
const emoji = statusEmoji[job.status] || '📊';
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
322
|
+
await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
|
|
323
|
+
// Check status AFTER waiting
|
|
324
|
+
console.error(`[wait_for_result] Checking status after ${waitSeconds}s wait...`);
|
|
325
|
+
job = await checkJobStatus();
|
|
326
|
+
// Check if complete now
|
|
327
|
+
if (job.status === 'completed') {
|
|
328
|
+
return {
|
|
329
|
+
content: [
|
|
330
|
+
{
|
|
331
|
+
type: 'text',
|
|
332
|
+
text: `✅ Test completed!
|
|
333
|
+
|
|
334
|
+
Job ID: ${job.id}
|
|
335
|
+
|
|
336
|
+
**Test Results:**`
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
type: 'text',
|
|
340
|
+
text: JSON.stringify({
|
|
341
|
+
result: job.result || {},
|
|
342
|
+
testerData: job.testerData
|
|
343
|
+
}, null, 2)
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
};
|
|
295
347
|
}
|
|
296
348
|
else if (job.status === 'failed') {
|
|
297
|
-
message += '\n\n❌ Job failed.' + (job.error ? ` Error: ${job.error}` : ' Check the error with get_job_result.');
|
|
298
|
-
}
|
|
299
|
-
else if (job.status === 'timeout') {
|
|
300
|
-
message += '\n\n⏰ Job timed out. The tester did not complete in time.';
|
|
301
|
-
}
|
|
302
|
-
return {
|
|
303
|
-
content: [{
|
|
304
|
-
type: 'text',
|
|
305
|
-
text: message
|
|
306
|
-
}]
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
return {
|
|
311
|
-
content: [{
|
|
312
|
-
type: 'text',
|
|
313
|
-
text: `❌ Error checking job status
|
|
314
|
-
|
|
315
|
-
${error instanceof Error ? error.message : 'Unknown error'}`
|
|
316
|
-
}],
|
|
317
|
-
isError: true
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
case 'get_job_result':
|
|
321
|
-
try {
|
|
322
|
-
const response = await fetch(`${API_URL}/api/job/${args.jobId}`, {
|
|
323
|
-
headers: {
|
|
324
|
-
'Authorization': `Bearer ${API_KEY}`
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
if (!response.ok) {
|
|
328
|
-
if (response.status === 404) {
|
|
329
|
-
return {
|
|
330
|
-
content: [{
|
|
331
|
-
type: 'text',
|
|
332
|
-
text: `❌ Job not found
|
|
333
|
-
|
|
334
|
-
Job ID: ${args.jobId}
|
|
335
|
-
|
|
336
|
-
The job does not exist or you don't have permission to access it.`
|
|
337
|
-
}],
|
|
338
|
-
isError: true
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
349
|
return {
|
|
342
350
|
content: [{
|
|
343
351
|
type: 'text',
|
|
344
|
-
text: `❌
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
Error: ${
|
|
352
|
+
text: `❌ Job failed
|
|
353
|
+
|
|
354
|
+
Job ID: ${job.id}
|
|
355
|
+
Error: ${job.error || 'Unknown error'}`
|
|
348
356
|
}],
|
|
349
357
|
isError: true
|
|
350
358
|
};
|
|
351
359
|
}
|
|
352
|
-
|
|
353
|
-
if (job.status !== 'completed') {
|
|
360
|
+
else if (job.status === 'timeout') {
|
|
354
361
|
return {
|
|
355
362
|
content: [{
|
|
356
363
|
type: 'text',
|
|
357
|
-
text:
|
|
358
|
-
|
|
359
|
-
Job ID: ${job.id}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
job.status === 'failed' ? '❌ Job failed. Error: ' + (job.error || 'Unknown error') :
|
|
365
|
-
job.status === 'timeout' ? '⏰ Job timed out.' :
|
|
366
|
-
'Use get_job_status to check current status.'}`
|
|
367
|
-
}]
|
|
364
|
+
text: `⏰ Job timed out
|
|
365
|
+
|
|
366
|
+
Job ID: ${job.id}
|
|
367
|
+
|
|
368
|
+
The tester did not complete the test in time.`
|
|
369
|
+
}],
|
|
370
|
+
isError: true
|
|
368
371
|
};
|
|
369
372
|
}
|
|
370
|
-
//
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
return { content: contents };
|
|
373
|
+
// Still not complete, suggest calling again with longer wait
|
|
374
|
+
const nextWait = Math.min(waitSeconds + 15, 120);
|
|
375
|
+
const statusMessage = job.status === 'pending' ?
|
|
376
|
+
'Waiting for a tester to claim this job...' :
|
|
377
|
+
'The tester is working on your test...';
|
|
378
|
+
return {
|
|
379
|
+
content: [{
|
|
380
|
+
type: 'text',
|
|
381
|
+
text: `${emoji} Job Status: ${job.status}
|
|
382
|
+
|
|
383
|
+
Job ID: ${job.id}
|
|
384
|
+
|
|
385
|
+
${statusMessage}
|
|
386
|
+
|
|
387
|
+
⏰ Waited ${waitSeconds}s, job not complete yet.
|
|
388
|
+
|
|
389
|
+
💡 Suggestion: Call wait_for_result again with waitSeconds: ${nextWait}
|
|
390
|
+
Typical completion time: 2-10 minutes total.`
|
|
391
|
+
}]
|
|
392
|
+
};
|
|
393
393
|
}
|
|
394
394
|
catch (error) {
|
|
395
395
|
return {
|
|
396
396
|
content: [{
|
|
397
397
|
type: 'text',
|
|
398
|
-
text: `❌ Error
|
|
399
|
-
|
|
398
|
+
text: `❌ Error waiting for result
|
|
399
|
+
|
|
400
400
|
${error instanceof Error ? error.message : 'Unknown error'}`
|
|
401
401
|
}],
|
|
402
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,62 +1,62 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@runhuman/mcp-server",
|
|
3
|
-
"version": "2.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
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@runhuman/mcp-server",
|
|
3
|
+
"version": "2.0.2",
|
|
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
|
+
}
|