flashq-mcp 0.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/README.md +159 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +153 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +18 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/admin.d.ts +7 -0
- package/dist/tools/admin.d.ts.map +1 -0
- package/dist/tools/admin.js +40 -0
- package/dist/tools/admin.js.map +1 -0
- package/dist/tools/dlq.d.ts +7 -0
- package/dist/tools/dlq.d.ts.map +1 -0
- package/dist/tools/dlq.js +49 -0
- package/dist/tools/dlq.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/jobs.d.ts +7 -0
- package/dist/tools/jobs.d.ts.map +1 -0
- package/dist/tools/jobs.js +176 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/monitoring.d.ts +7 -0
- package/dist/tools/monitoring.d.ts.map +1 -0
- package/dist/tools/monitoring.js +27 -0
- package/dist/tools/monitoring.js.map +1 -0
- package/dist/tools/queues.d.ts +7 -0
- package/dist/tools/queues.d.ts.map +1 -0
- package/dist/tools/queues.js +103 -0
- package/dist/tools/queues.js.map +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# flashQ MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/flashq-mcp)
|
|
4
|
+
|
|
5
|
+
MCP (Model Context Protocol) server that enables AI assistants like Claude to manage flashQ job queues.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g flashq-mcp
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or use directly with npx:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx flashq-mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
1. **Start flashQ server** with HTTP API enabled:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd engine
|
|
25
|
+
HTTP=1 cargo run --release
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. **Configure Claude Desktop** (`~/.config/claude/claude_desktop_config.json`):
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"flashq": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["flashq-mcp"],
|
|
36
|
+
"env": {
|
|
37
|
+
"FLASHQ_HOST": "localhost",
|
|
38
|
+
"FLASHQ_HTTP_PORT": "6790"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
3. **Restart Claude Desktop** and start managing queues!
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
Environment variables:
|
|
50
|
+
|
|
51
|
+
| Variable | Default | Description |
|
|
52
|
+
|----------|---------|-------------|
|
|
53
|
+
| `FLASHQ_HOST` | localhost | flashQ server host |
|
|
54
|
+
| `FLASHQ_HTTP_PORT` | 6790 | HTTP API port |
|
|
55
|
+
| `FLASHQ_TOKEN` | - | Auth token (optional) |
|
|
56
|
+
| `FLASHQ_TIMEOUT` | 30000 | Request timeout (ms) |
|
|
57
|
+
|
|
58
|
+
## Available Tools (25)
|
|
59
|
+
|
|
60
|
+
### Job Operations (10 tools)
|
|
61
|
+
|
|
62
|
+
| Tool | Description |
|
|
63
|
+
|------|-------------|
|
|
64
|
+
| `push_job` | Create a new job with priority, delay, retry options |
|
|
65
|
+
| `push_batch_jobs` | Create multiple jobs at once (max 1000) |
|
|
66
|
+
| `get_job` | Get job details with current state |
|
|
67
|
+
| `get_job_state` | Get only the job state |
|
|
68
|
+
| `get_job_result` | Get completed job result |
|
|
69
|
+
| `get_job_by_custom_id` | Find job by custom ID |
|
|
70
|
+
| `list_jobs` | List jobs with filtering and pagination |
|
|
71
|
+
| `get_job_counts` | Get job counts by state for a queue |
|
|
72
|
+
| `cancel_job` | Cancel a pending job |
|
|
73
|
+
| `get_job_progress` | Get progress for active job |
|
|
74
|
+
|
|
75
|
+
### Queue Management (8 tools)
|
|
76
|
+
|
|
77
|
+
| Tool | Description |
|
|
78
|
+
|------|-------------|
|
|
79
|
+
| `list_queues` | List all queues with status |
|
|
80
|
+
| `pause_queue` | Pause queue processing |
|
|
81
|
+
| `resume_queue` | Resume paused queue |
|
|
82
|
+
| `is_queue_paused` | Check if queue is paused |
|
|
83
|
+
| `drain_queue` | Remove all waiting jobs |
|
|
84
|
+
| `count_jobs` | Count waiting + delayed jobs |
|
|
85
|
+
| `set_rate_limit` | Set jobs/sec limit |
|
|
86
|
+
| `clear_rate_limit` | Remove rate limit |
|
|
87
|
+
|
|
88
|
+
### Dead Letter Queue (3 tools)
|
|
89
|
+
|
|
90
|
+
| Tool | Description |
|
|
91
|
+
|------|-------------|
|
|
92
|
+
| `get_dlq` | Get failed jobs from DLQ |
|
|
93
|
+
| `retry_dlq` | Retry DLQ jobs |
|
|
94
|
+
| `purge_dlq` | Remove all DLQ jobs |
|
|
95
|
+
|
|
96
|
+
### Monitoring (2 tools)
|
|
97
|
+
|
|
98
|
+
| Tool | Description |
|
|
99
|
+
|------|-------------|
|
|
100
|
+
| `get_stats` | Get overall queue statistics |
|
|
101
|
+
| `get_metrics` | Get detailed performance metrics |
|
|
102
|
+
|
|
103
|
+
### Admin (2 tools)
|
|
104
|
+
|
|
105
|
+
| Tool | Description |
|
|
106
|
+
|------|-------------|
|
|
107
|
+
| `list_crons` | List scheduled cron jobs |
|
|
108
|
+
| `clean_jobs` | Clean old jobs by age/state |
|
|
109
|
+
|
|
110
|
+
## Example Conversations
|
|
111
|
+
|
|
112
|
+
Once configured, you can ask Claude:
|
|
113
|
+
|
|
114
|
+
- "Push a job to the orders queue with priority 10"
|
|
115
|
+
- "How many jobs are waiting in the emails queue?"
|
|
116
|
+
- "Show me the failed jobs in the payments queue"
|
|
117
|
+
- "Retry all DLQ jobs for the notifications queue"
|
|
118
|
+
- "Pause the sync queue"
|
|
119
|
+
- "What's the current throughput?"
|
|
120
|
+
|
|
121
|
+
## Architecture
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
┌─────────────┐ MCP (stdio) ┌─────────────────┐ HTTP ┌─────────────┐
|
|
125
|
+
│ Claude │ ◄─────────────────► │ flashQ MCP │ ◄──────────► │ flashQ │
|
|
126
|
+
│ │ │ Server (TS) │ :6790 │ Engine │
|
|
127
|
+
└─────────────┘ └─────────────────┘ └─────────────┘
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Development
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Clone and install
|
|
134
|
+
git clone https://github.com/flashq/flashq.git
|
|
135
|
+
cd flashq/mcp
|
|
136
|
+
bun install
|
|
137
|
+
|
|
138
|
+
# Development
|
|
139
|
+
bun run dev
|
|
140
|
+
|
|
141
|
+
# Type check
|
|
142
|
+
bun run typecheck
|
|
143
|
+
|
|
144
|
+
# Lint
|
|
145
|
+
bun run lint
|
|
146
|
+
|
|
147
|
+
# Format
|
|
148
|
+
bun run format
|
|
149
|
+
|
|
150
|
+
# Build
|
|
151
|
+
bun run build
|
|
152
|
+
|
|
153
|
+
# Test
|
|
154
|
+
bun run test
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for flashQ API
|
|
3
|
+
* Reuses patterns from sdk/typescript/src/client/http/request.ts
|
|
4
|
+
*/
|
|
5
|
+
import type { FlashQConfig } from './config.js';
|
|
6
|
+
export declare class FlashQClient {
|
|
7
|
+
private baseUrl;
|
|
8
|
+
private headers;
|
|
9
|
+
private timeout;
|
|
10
|
+
constructor(config: FlashQConfig);
|
|
11
|
+
send<T>(cmd: string, params?: Record<string, unknown>): Promise<T>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoIhD,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,YAAY;IAM1B,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAsB7E"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for flashQ API
|
|
3
|
+
* Reuses patterns from sdk/typescript/src/client/http/request.ts
|
|
4
|
+
*/
|
|
5
|
+
import { FlashQError } from './errors.js';
|
|
6
|
+
function buildHeaders(token) {
|
|
7
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
8
|
+
if (token)
|
|
9
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
10
|
+
return headers;
|
|
11
|
+
}
|
|
12
|
+
const encodeQueue = (queue) => encodeURIComponent(String(queue));
|
|
13
|
+
function buildRequest(baseUrl, cmd, params) {
|
|
14
|
+
switch (cmd) {
|
|
15
|
+
// Core operations
|
|
16
|
+
case 'PUSH':
|
|
17
|
+
return {
|
|
18
|
+
url: `${baseUrl}/queues/${encodeQueue(params.queue)}/jobs`,
|
|
19
|
+
method: 'POST',
|
|
20
|
+
body: JSON.stringify({
|
|
21
|
+
data: params.data,
|
|
22
|
+
priority: params.priority,
|
|
23
|
+
delay: params.delay,
|
|
24
|
+
ttl: params.ttl,
|
|
25
|
+
timeout: params.timeout,
|
|
26
|
+
max_attempts: params.max_attempts,
|
|
27
|
+
backoff: params.backoff,
|
|
28
|
+
unique_key: params.unique_key,
|
|
29
|
+
depends_on: params.depends_on,
|
|
30
|
+
tags: params.tags,
|
|
31
|
+
job_id: params.job_id,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
case 'PUSHB':
|
|
35
|
+
return {
|
|
36
|
+
url: `${baseUrl}/queues/${encodeQueue(params.queue)}/jobs/batch`,
|
|
37
|
+
method: 'POST',
|
|
38
|
+
body: JSON.stringify({ jobs: params.jobs }),
|
|
39
|
+
};
|
|
40
|
+
// Job queries
|
|
41
|
+
case 'GETJOB':
|
|
42
|
+
return { url: `${baseUrl}/jobs/${params.id}`, method: 'GET' };
|
|
43
|
+
case 'GETSTATE':
|
|
44
|
+
return { url: `${baseUrl}/jobs/${params.id}/state`, method: 'GET' };
|
|
45
|
+
case 'GETRESULT':
|
|
46
|
+
return { url: `${baseUrl}/jobs/${params.id}/result`, method: 'GET' };
|
|
47
|
+
case 'GETJOBBYCUSTOMID':
|
|
48
|
+
return {
|
|
49
|
+
url: `${baseUrl}/jobs/custom/${encodeURIComponent(String(params.custom_id))}`,
|
|
50
|
+
method: 'GET',
|
|
51
|
+
};
|
|
52
|
+
case 'GETJOBS': {
|
|
53
|
+
const q = [];
|
|
54
|
+
if (params.queue)
|
|
55
|
+
q.push(`queue=${encodeQueue(params.queue)}`);
|
|
56
|
+
if (params.state)
|
|
57
|
+
q.push(`state=${params.state}`);
|
|
58
|
+
if (params.limit)
|
|
59
|
+
q.push(`limit=${params.limit}`);
|
|
60
|
+
if (params.offset)
|
|
61
|
+
q.push(`offset=${params.offset}`);
|
|
62
|
+
return { url: `${baseUrl}/jobs${q.length ? '?' + q.join('&') : ''}`, method: 'GET' };
|
|
63
|
+
}
|
|
64
|
+
case 'GETJOBCOUNTS':
|
|
65
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/counts`, method: 'GET' };
|
|
66
|
+
case 'COUNT':
|
|
67
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/count`, method: 'GET' };
|
|
68
|
+
case 'GETPROGRESS':
|
|
69
|
+
return { url: `${baseUrl}/jobs/${params.id}/progress`, method: 'GET' };
|
|
70
|
+
// Job management
|
|
71
|
+
case 'CANCEL':
|
|
72
|
+
return { url: `${baseUrl}/jobs/${params.id}/cancel`, method: 'POST' };
|
|
73
|
+
// Queue management
|
|
74
|
+
case 'LISTQUEUES':
|
|
75
|
+
return { url: `${baseUrl}/queues`, method: 'GET' };
|
|
76
|
+
case 'PAUSE':
|
|
77
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/pause`, method: 'POST' };
|
|
78
|
+
case 'RESUME':
|
|
79
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/resume`, method: 'POST' };
|
|
80
|
+
case 'ISPAUSED':
|
|
81
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/paused`, method: 'GET' };
|
|
82
|
+
case 'DRAIN':
|
|
83
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/drain`, method: 'POST' };
|
|
84
|
+
case 'RATELIMIT':
|
|
85
|
+
return {
|
|
86
|
+
url: `${baseUrl}/queues/${encodeQueue(params.queue)}/ratelimit`,
|
|
87
|
+
method: 'POST',
|
|
88
|
+
body: JSON.stringify({ limit: params.limit }),
|
|
89
|
+
};
|
|
90
|
+
case 'RATELIMITCLEAR':
|
|
91
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/ratelimit`, method: 'DELETE' };
|
|
92
|
+
// DLQ
|
|
93
|
+
case 'DLQ':
|
|
94
|
+
return {
|
|
95
|
+
url: `${baseUrl}/queues/${encodeQueue(params.queue)}/dlq?count=${params.count ?? 100}`,
|
|
96
|
+
method: 'GET',
|
|
97
|
+
};
|
|
98
|
+
case 'RETRYDLQ':
|
|
99
|
+
return params.id
|
|
100
|
+
? {
|
|
101
|
+
url: `${baseUrl}/queues/${encodeQueue(params.queue)}/dlq/${params.id}/retry`,
|
|
102
|
+
method: 'POST',
|
|
103
|
+
}
|
|
104
|
+
: { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/dlq/retry`, method: 'POST' };
|
|
105
|
+
case 'PURGEDLQ':
|
|
106
|
+
return { url: `${baseUrl}/queues/${encodeQueue(params.queue)}/dlq`, method: 'DELETE' };
|
|
107
|
+
// Monitoring
|
|
108
|
+
case 'STATS':
|
|
109
|
+
return { url: `${baseUrl}/stats`, method: 'GET' };
|
|
110
|
+
case 'METRICS':
|
|
111
|
+
return { url: `${baseUrl}/metrics`, method: 'GET' };
|
|
112
|
+
// Admin
|
|
113
|
+
case 'CRONLIST':
|
|
114
|
+
return { url: `${baseUrl}/crons`, method: 'GET' };
|
|
115
|
+
case 'CLEAN':
|
|
116
|
+
return {
|
|
117
|
+
url: `${baseUrl}/queues/${encodeQueue(params.queue)}/clean`,
|
|
118
|
+
method: 'POST',
|
|
119
|
+
body: JSON.stringify({ grace: params.grace, state: params.state, limit: params.limit }),
|
|
120
|
+
};
|
|
121
|
+
default:
|
|
122
|
+
throw new FlashQError(`Unknown command: ${cmd}`, 400, 'UNKNOWN_COMMAND');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export class FlashQClient {
|
|
126
|
+
baseUrl;
|
|
127
|
+
headers;
|
|
128
|
+
timeout;
|
|
129
|
+
constructor(config) {
|
|
130
|
+
this.baseUrl = `http://${config.host}:${config.httpPort}`;
|
|
131
|
+
this.headers = buildHeaders(config.token);
|
|
132
|
+
this.timeout = config.timeout;
|
|
133
|
+
}
|
|
134
|
+
async send(cmd, params = {}) {
|
|
135
|
+
const request = buildRequest(this.baseUrl, cmd, params);
|
|
136
|
+
const response = await fetch(request.url, {
|
|
137
|
+
method: request.method,
|
|
138
|
+
headers: this.headers,
|
|
139
|
+
body: request.body,
|
|
140
|
+
signal: AbortSignal.timeout(this.timeout),
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
const errorText = await response.text();
|
|
144
|
+
throw new FlashQError(errorText || response.statusText, response.status);
|
|
145
|
+
}
|
|
146
|
+
const data = (await response.json());
|
|
147
|
+
if (!data.ok) {
|
|
148
|
+
throw new FlashQError(data.error || 'Unknown error', 500);
|
|
149
|
+
}
|
|
150
|
+
return data;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loading from environment variables
|
|
3
|
+
*/
|
|
4
|
+
export interface FlashQConfig {
|
|
5
|
+
host: string;
|
|
6
|
+
httpPort: number;
|
|
7
|
+
token?: string;
|
|
8
|
+
timeout: number;
|
|
9
|
+
}
|
|
10
|
+
export interface Config {
|
|
11
|
+
flashq: FlashQConfig;
|
|
12
|
+
}
|
|
13
|
+
export declare function loadConfig(): Config;
|
|
14
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,UAAU,IAAI,MAAM,CASnC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loading from environment variables
|
|
3
|
+
*/
|
|
4
|
+
export function loadConfig() {
|
|
5
|
+
return {
|
|
6
|
+
flashq: {
|
|
7
|
+
host: process.env.FLASHQ_HOST || 'localhost',
|
|
8
|
+
httpPort: parseInt(process.env.FLASHQ_HTTP_PORT || '6790', 10),
|
|
9
|
+
token: process.env.FLASHQ_TOKEN,
|
|
10
|
+
timeout: parseInt(process.env.FLASHQ_TIMEOUT || '30000', 10),
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,WAAW;YAC5C,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,EAAE,EAAE,CAAC;YAC9D,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;YAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,EAAE,EAAE,CAAC;SAC7D;KACF,CAAC;AACJ,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for MCP responses
|
|
3
|
+
*/
|
|
4
|
+
export declare class FlashQError extends Error {
|
|
5
|
+
readonly statusCode: number;
|
|
6
|
+
readonly code?: string | undefined;
|
|
7
|
+
constructor(message: string, statusCode: number, code?: string | undefined);
|
|
8
|
+
}
|
|
9
|
+
export interface McpTextContent {
|
|
10
|
+
type: 'text';
|
|
11
|
+
text: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface McpResponse {
|
|
15
|
+
content: McpTextContent[];
|
|
16
|
+
isError?: boolean;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
export declare function formatError(error: unknown): McpResponse;
|
|
20
|
+
export declare function formatSuccess<T>(data: T): McpResponse;
|
|
21
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,WAAY,SAAQ,KAAK;aAGlB,UAAU,EAAE,MAAM;aAClB,IAAI,CAAC,EAAE,MAAM;gBAF7B,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAqCvD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CASrD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for MCP responses
|
|
3
|
+
*/
|
|
4
|
+
export class FlashQError extends Error {
|
|
5
|
+
statusCode;
|
|
6
|
+
code;
|
|
7
|
+
constructor(message, statusCode, code) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.statusCode = statusCode;
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = 'FlashQError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function formatError(error) {
|
|
15
|
+
if (error instanceof FlashQError) {
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: 'text',
|
|
20
|
+
text: JSON.stringify({
|
|
21
|
+
error: error.message,
|
|
22
|
+
code: error.code || 'FLASHQ_ERROR',
|
|
23
|
+
statusCode: error.statusCode,
|
|
24
|
+
}, null, 2),
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
isError: true,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: 'text',
|
|
34
|
+
text: JSON.stringify({
|
|
35
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
36
|
+
code: 'INTERNAL_ERROR',
|
|
37
|
+
}, null, 2),
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
isError: true,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function formatSuccess(data) {
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: 'text',
|
|
48
|
+
text: JSON.stringify(data, null, 2),
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAGlB;IACA;IAHlB,YACE,OAAe,EACC,UAAkB,EAClB,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAcD,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,KAAK,EAAE,KAAK,CAAC,OAAO;wBACpB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,cAAc;wBAClC,UAAU,EAAE,KAAK,CAAC,UAAU;qBAC7B,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;oBAC/D,IAAI,EAAE,gBAAgB;iBACvB,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAI,IAAO;IACtC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACpC;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* flashQ MCP Server - Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Enables AI assistants to manage flashQ job queues through the
|
|
6
|
+
* Model Context Protocol (MCP).
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* FLASHQ_HOST - Server host (default: localhost)
|
|
10
|
+
* FLASHQ_HTTP_PORT - HTTP API port (default: 6790)
|
|
11
|
+
* FLASHQ_TOKEN - Auth token (optional)
|
|
12
|
+
* FLASHQ_TIMEOUT - Request timeout in ms (default: 30000)
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* flashQ MCP Server - Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Enables AI assistants to manage flashQ job queues through the
|
|
6
|
+
* Model Context Protocol (MCP).
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* FLASHQ_HOST - Server host (default: localhost)
|
|
10
|
+
* FLASHQ_HTTP_PORT - HTTP API port (default: 6790)
|
|
11
|
+
* FLASHQ_TOKEN - Auth token (optional)
|
|
12
|
+
* FLASHQ_TIMEOUT - Request timeout in ms (default: 30000)
|
|
13
|
+
*/
|
|
14
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
15
|
+
import { createServer } from './server.js';
|
|
16
|
+
async function main() {
|
|
17
|
+
const server = createServer();
|
|
18
|
+
const transport = new StdioServerTransport();
|
|
19
|
+
await server.connect(transport);
|
|
20
|
+
// Log to stderr (stdout is reserved for MCP protocol)
|
|
21
|
+
console.error('flashQ MCP server started');
|
|
22
|
+
}
|
|
23
|
+
main().catch((error) => {
|
|
24
|
+
console.error('Failed to start flashQ MCP server:', error);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,sDAAsD;IACtD,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAC7C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,YAAY,IAAI,SAAS,CAaxC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server setup and configuration
|
|
3
|
+
*/
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { FlashQClient } from './client.js';
|
|
6
|
+
import { loadConfig } from './config.js';
|
|
7
|
+
import { registerAllTools } from './tools/index.js';
|
|
8
|
+
export function createServer() {
|
|
9
|
+
const config = loadConfig();
|
|
10
|
+
const client = new FlashQClient(config.flashq);
|
|
11
|
+
const server = new McpServer({
|
|
12
|
+
name: 'flashq',
|
|
13
|
+
version: '0.1.0',
|
|
14
|
+
});
|
|
15
|
+
registerAllTools(server, client);
|
|
16
|
+
return server;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { FlashQClient } from '../client.js';
|
|
6
|
+
export declare function registerAdminTools(server: McpServer, client: FlashQClient): void;
|
|
7
|
+
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/tools/admin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA0ChF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { formatSuccess, formatError } from '../errors.js';
|
|
6
|
+
export function registerAdminTools(server, client) {
|
|
7
|
+
// list_crons
|
|
8
|
+
server.tool('list_crons', 'List all scheduled cron jobs with their schedules, next run times, target queues, and execution counts.', {}, async () => {
|
|
9
|
+
try {
|
|
10
|
+
const result = await client.send('CRONLIST');
|
|
11
|
+
return formatSuccess(result);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
return formatError(error);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
// clean_jobs
|
|
18
|
+
server.tool('clean_jobs', 'Remove old jobs from a queue based on age and state. Useful for maintenance and cleaning up completed or failed jobs.', {
|
|
19
|
+
queue: z.string().describe('Queue name'),
|
|
20
|
+
grace_ms: z.number().describe('Remove jobs older than this many milliseconds'),
|
|
21
|
+
state: z
|
|
22
|
+
.enum(['waiting', 'delayed', 'completed', 'failed'])
|
|
23
|
+
.describe('State of jobs to clean'),
|
|
24
|
+
limit: z.number().optional().describe('Maximum number of jobs to remove'),
|
|
25
|
+
}, async (args) => {
|
|
26
|
+
try {
|
|
27
|
+
const result = await client.send('CLEAN', {
|
|
28
|
+
queue: args.queue,
|
|
29
|
+
grace: args.grace_ms,
|
|
30
|
+
state: args.state,
|
|
31
|
+
limit: args.limit,
|
|
32
|
+
});
|
|
33
|
+
return formatSuccess(result);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return formatError(error);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/tools/admin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAoB;IACxE,aAAa;IACb,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,yGAAyG,EACzG,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7C,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,aAAa;IACb,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,uHAAuH,EACvH;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QAC9E,KAAK,EAAE,CAAC;aACL,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;aACnD,QAAQ,CAAC,wBAAwB,CAAC;QACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KAC1E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;gBACxC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,QAAQ;gBACpB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YACH,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead Letter Queue (DLQ) tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { FlashQClient } from '../client.js';
|
|
6
|
+
export declare function registerDlqTools(server: McpServer, client: FlashQClient): void;
|
|
7
|
+
//# sourceMappingURL=dlq.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlq.d.ts","sourceRoot":"","sources":["../../src/tools/dlq.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAwD9E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead Letter Queue (DLQ) tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { formatSuccess, formatError } from '../errors.js';
|
|
6
|
+
export function registerDlqTools(server, client) {
|
|
7
|
+
// get_dlq
|
|
8
|
+
server.tool('get_dlq', 'Get jobs from the Dead Letter Queue (DLQ) for a specific queue. These are jobs that failed after exhausting all retry attempts.', {
|
|
9
|
+
queue: z.string().describe('Queue name'),
|
|
10
|
+
count: z.number().max(100).default(20).describe('Maximum jobs to return (max 100)'),
|
|
11
|
+
}, async (args) => {
|
|
12
|
+
try {
|
|
13
|
+
const result = await client.send('DLQ', { queue: args.queue, count: args.count });
|
|
14
|
+
return formatSuccess(result);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return formatError(error);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
// retry_dlq
|
|
21
|
+
server.tool('retry_dlq', 'Retry jobs from the Dead Letter Queue. Can retry all jobs in the queue or a specific job by ID. Jobs are moved back to waiting state.', {
|
|
22
|
+
queue: z.string().describe('Queue name'),
|
|
23
|
+
job_id: z
|
|
24
|
+
.number()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Specific job ID to retry, or omit to retry all DLQ jobs'),
|
|
27
|
+
}, async (args) => {
|
|
28
|
+
try {
|
|
29
|
+
const result = await client.send('RETRYDLQ', { queue: args.queue, id: args.job_id });
|
|
30
|
+
return formatSuccess(result);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return formatError(error);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
// purge_dlq
|
|
37
|
+
server.tool('purge_dlq', 'Permanently remove all jobs from the Dead Letter Queue for a specific queue. This action cannot be undone.', {
|
|
38
|
+
queue: z.string().describe('Queue name'),
|
|
39
|
+
}, async (args) => {
|
|
40
|
+
try {
|
|
41
|
+
const result = await client.send('PURGEDLQ', { queue: args.queue });
|
|
42
|
+
return formatSuccess(result);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return formatError(error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=dlq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlq.js","sourceRoot":"","sources":["../../src/tools/dlq.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAoB;IACtE,UAAU;IACV,MAAM,CAAC,IAAI,CACT,SAAS,EACT,iIAAiI,EACjI;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KACpF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAClF,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,YAAY;IACZ,MAAM,CAAC,IAAI,CACT,WAAW,EACX,uIAAuI,EACvI;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxC,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,yDAAyD,CAAC;KACvE,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrF,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,YAAY;IACZ,MAAM,CAAC,IAAI,CACT,WAAW,EACX,4GAA4G,EAC5G;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;KACzC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACpE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool registration aggregator
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { FlashQClient } from '../client.js';
|
|
6
|
+
export declare function registerAllTools(server: McpServer, client: FlashQClient): void;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAOjD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAM9E"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool registration aggregator
|
|
3
|
+
*/
|
|
4
|
+
import { registerJobTools } from './jobs.js';
|
|
5
|
+
import { registerQueueTools } from './queues.js';
|
|
6
|
+
import { registerDlqTools } from './dlq.js';
|
|
7
|
+
import { registerMonitoringTools } from './monitoring.js';
|
|
8
|
+
import { registerAdminTools } from './admin.js';
|
|
9
|
+
export function registerAllTools(server, client) {
|
|
10
|
+
registerJobTools(server, client);
|
|
11
|
+
registerQueueTools(server, client);
|
|
12
|
+
registerDlqTools(server, client);
|
|
13
|
+
registerMonitoringTools(server, client);
|
|
14
|
+
registerAdminTools(server, client);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAoB;IACtE,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job operation tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { FlashQClient } from '../client.js';
|
|
6
|
+
export declare function registerJobTools(server: McpServer, client: FlashQClient): void;
|
|
7
|
+
//# sourceMappingURL=jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../src/tools/jobs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA4N9E"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job operation tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { formatSuccess, formatError } from '../errors.js';
|
|
6
|
+
export function registerJobTools(server, client) {
|
|
7
|
+
// push_job
|
|
8
|
+
server.tool('push_job', 'Create a new job in a flashQ queue. Use this to add work items that workers will process. Returns the created job ID.', {
|
|
9
|
+
queue: z.string().describe('Queue name (alphanumeric, underscore, hyphen, dot)'),
|
|
10
|
+
data: z.any().describe('Job payload data (JSON object)'),
|
|
11
|
+
priority: z
|
|
12
|
+
.number()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe('Job priority (higher = processed first, default: 0)'),
|
|
15
|
+
delay: z.number().optional().describe('Delay in milliseconds before job is available'),
|
|
16
|
+
max_attempts: z
|
|
17
|
+
.number()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Maximum retry attempts (default: 0 = no retry)'),
|
|
20
|
+
timeout: z.number().optional().describe('Job processing timeout in milliseconds'),
|
|
21
|
+
ttl: z.number().optional().describe('Time-to-live in milliseconds (job expires after)'),
|
|
22
|
+
unique_key: z.string().optional().describe('Unique key for deduplication'),
|
|
23
|
+
jobId: z.string().optional().describe('Custom job ID for idempotent operations'),
|
|
24
|
+
tags: z.array(z.string()).optional().describe('Tags for filtering'),
|
|
25
|
+
}, async (args) => {
|
|
26
|
+
try {
|
|
27
|
+
const result = await client.send('PUSH', {
|
|
28
|
+
queue: args.queue,
|
|
29
|
+
data: args.data,
|
|
30
|
+
priority: args.priority,
|
|
31
|
+
delay: args.delay,
|
|
32
|
+
max_attempts: args.max_attempts,
|
|
33
|
+
timeout: args.timeout,
|
|
34
|
+
ttl: args.ttl,
|
|
35
|
+
unique_key: args.unique_key,
|
|
36
|
+
job_id: args.jobId,
|
|
37
|
+
tags: args.tags,
|
|
38
|
+
});
|
|
39
|
+
return formatSuccess(result);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return formatError(error);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// push_batch_jobs
|
|
46
|
+
server.tool('push_batch_jobs', 'Create multiple jobs at once for efficient bulk operations. Maximum 1000 jobs per batch.', {
|
|
47
|
+
queue: z.string().describe('Queue name'),
|
|
48
|
+
jobs: z
|
|
49
|
+
.array(z.object({
|
|
50
|
+
data: z.any().describe('Job payload'),
|
|
51
|
+
priority: z.number().optional().describe('Job priority'),
|
|
52
|
+
delay: z.number().optional().describe('Delay in milliseconds'),
|
|
53
|
+
}))
|
|
54
|
+
.max(1000)
|
|
55
|
+
.describe('Array of jobs to create (max 1000)'),
|
|
56
|
+
}, async (args) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await client.send('PUSHB', {
|
|
59
|
+
queue: args.queue,
|
|
60
|
+
jobs: args.jobs,
|
|
61
|
+
});
|
|
62
|
+
return formatSuccess(result);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return formatError(error);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// get_job
|
|
69
|
+
server.tool('get_job', 'Get detailed information about a specific job including its current state, data, and metadata.', {
|
|
70
|
+
job_id: z.number().describe('Numeric job ID'),
|
|
71
|
+
}, async (args) => {
|
|
72
|
+
try {
|
|
73
|
+
const result = await client.send('GETJOB', { id: args.job_id });
|
|
74
|
+
return formatSuccess(result);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return formatError(error);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// get_job_state
|
|
81
|
+
server.tool('get_job_state', 'Get only the current state of a job. Returns: waiting, delayed, active, completed, or failed.', {
|
|
82
|
+
job_id: z.number().describe('Numeric job ID'),
|
|
83
|
+
}, async (args) => {
|
|
84
|
+
try {
|
|
85
|
+
const result = await client.send('GETSTATE', { id: args.job_id });
|
|
86
|
+
return formatSuccess(result);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return formatError(error);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// get_job_result
|
|
93
|
+
server.tool('get_job_result', 'Get the result data from a completed job. Returns null if job is not completed or result was not stored.', {
|
|
94
|
+
job_id: z.number().describe('Numeric job ID'),
|
|
95
|
+
}, async (args) => {
|
|
96
|
+
try {
|
|
97
|
+
const result = await client.send('GETRESULT', { id: args.job_id });
|
|
98
|
+
return formatSuccess(result);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
return formatError(error);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
// get_job_by_custom_id
|
|
105
|
+
server.tool('get_job_by_custom_id', 'Find a job using its custom ID (set via jobId option during push). Useful for idempotent operations and tracking.', {
|
|
106
|
+
custom_id: z.string().describe('Custom job ID'),
|
|
107
|
+
}, async (args) => {
|
|
108
|
+
try {
|
|
109
|
+
const result = await client.send('GETJOBBYCUSTOMID', { custom_id: args.custom_id });
|
|
110
|
+
return formatSuccess(result);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return formatError(error);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// list_jobs
|
|
117
|
+
server.tool('list_jobs', 'List jobs with optional filtering by queue and state. Supports pagination for large result sets.', {
|
|
118
|
+
queue: z.string().optional().describe('Filter by queue name'),
|
|
119
|
+
state: z
|
|
120
|
+
.enum(['waiting', 'delayed', 'active', 'completed', 'failed'])
|
|
121
|
+
.optional()
|
|
122
|
+
.describe('Filter by job state'),
|
|
123
|
+
limit: z.number().max(100).default(20).describe('Maximum jobs to return (max 100)'),
|
|
124
|
+
offset: z.number().default(0).describe('Offset for pagination'),
|
|
125
|
+
}, async (args) => {
|
|
126
|
+
try {
|
|
127
|
+
const result = await client.send('GETJOBS', {
|
|
128
|
+
queue: args.queue,
|
|
129
|
+
state: args.state,
|
|
130
|
+
limit: args.limit,
|
|
131
|
+
offset: args.offset,
|
|
132
|
+
});
|
|
133
|
+
return formatSuccess(result);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return formatError(error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// get_job_counts
|
|
140
|
+
server.tool('get_job_counts', 'Get the count of jobs in each state (waiting, active, delayed, completed, failed) for a specific queue.', {
|
|
141
|
+
queue: z.string().describe('Queue name'),
|
|
142
|
+
}, async (args) => {
|
|
143
|
+
try {
|
|
144
|
+
const result = await client.send('GETJOBCOUNTS', { queue: args.queue });
|
|
145
|
+
return formatSuccess(result);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
return formatError(error);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// cancel_job
|
|
152
|
+
server.tool('cancel_job', 'Cancel a job that is waiting or delayed. Cannot cancel jobs that are already being processed (active).', {
|
|
153
|
+
job_id: z.number().describe('Numeric job ID to cancel'),
|
|
154
|
+
}, async (args) => {
|
|
155
|
+
try {
|
|
156
|
+
const result = await client.send('CANCEL', { id: args.job_id });
|
|
157
|
+
return formatSuccess(result);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
return formatError(error);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
// get_job_progress
|
|
164
|
+
server.tool('get_job_progress', 'Get the progress percentage and message for an active job. Used for long-running tasks that report progress.', {
|
|
165
|
+
job_id: z.number().describe('Numeric job ID'),
|
|
166
|
+
}, async (args) => {
|
|
167
|
+
try {
|
|
168
|
+
const result = await client.send('GETPROGRESS', { id: args.job_id });
|
|
169
|
+
return formatSuccess(result);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
return formatError(error);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/tools/jobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitoring and metrics tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { FlashQClient } from '../client.js';
|
|
6
|
+
export declare function registerMonitoringTools(server: McpServer, client: FlashQClient): void;
|
|
7
|
+
//# sourceMappingURL=monitoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitoring.d.ts","sourceRoot":"","sources":["../../src/tools/monitoring.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA8BrF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitoring and metrics tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import { formatSuccess, formatError } from '../errors.js';
|
|
5
|
+
export function registerMonitoringTools(server, client) {
|
|
6
|
+
// get_stats
|
|
7
|
+
server.tool('get_stats', 'Get overall statistics for the flashQ server including total queued jobs, processing count, delayed count, and DLQ count across all queues.', {}, async () => {
|
|
8
|
+
try {
|
|
9
|
+
const result = await client.send('STATS');
|
|
10
|
+
return formatSuccess(result);
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return formatError(error);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
// get_metrics
|
|
17
|
+
server.tool('get_metrics', 'Get detailed performance metrics including throughput (jobs/sec), average latency, total pushed/completed/failed counts, and per-queue breakdown.', {}, async () => {
|
|
18
|
+
try {
|
|
19
|
+
const result = await client.send('METRICS');
|
|
20
|
+
return formatSuccess(result);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return formatError(error);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=monitoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitoring.js","sourceRoot":"","sources":["../../src/tools/monitoring.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAoB;IAC7E,YAAY;IACZ,MAAM,CAAC,IAAI,CACT,WAAW,EACX,6IAA6I,EAC7I,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1C,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,cAAc;IACd,MAAM,CAAC,IAAI,CACT,aAAa,EACb,mJAAmJ,EACnJ,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5C,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue management tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { FlashQClient } from '../client.js';
|
|
6
|
+
export declare function registerQueueTools(server: McpServer, client: FlashQClient): void;
|
|
7
|
+
//# sourceMappingURL=queues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queues.d.ts","sourceRoot":"","sources":["../../src/tools/queues.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAuIhF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue management tools for MCP server
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { formatSuccess, formatError } from '../errors.js';
|
|
6
|
+
export function registerQueueTools(server, client) {
|
|
7
|
+
// list_queues
|
|
8
|
+
server.tool('list_queues', 'List all queues in the flashQ server with their current status including pending count, processing count, DLQ count, and paused state.', {}, async () => {
|
|
9
|
+
try {
|
|
10
|
+
const result = await client.send('LISTQUEUES');
|
|
11
|
+
return formatSuccess(result);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
return formatError(error);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
// pause_queue
|
|
18
|
+
server.tool('pause_queue', 'Pause a queue to temporarily stop workers from pulling new jobs. Existing active jobs will continue processing until completion.', {
|
|
19
|
+
queue: z.string().describe('Queue name to pause'),
|
|
20
|
+
}, async (args) => {
|
|
21
|
+
try {
|
|
22
|
+
const result = await client.send('PAUSE', { queue: args.queue });
|
|
23
|
+
return formatSuccess(result);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return formatError(error);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// resume_queue
|
|
30
|
+
server.tool('resume_queue', 'Resume a paused queue to allow workers to pull jobs again.', {
|
|
31
|
+
queue: z.string().describe('Queue name to resume'),
|
|
32
|
+
}, async (args) => {
|
|
33
|
+
try {
|
|
34
|
+
const result = await client.send('RESUME', { queue: args.queue });
|
|
35
|
+
return formatSuccess(result);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return formatError(error);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
// is_queue_paused
|
|
42
|
+
server.tool('is_queue_paused', 'Check whether a specific queue is currently paused.', {
|
|
43
|
+
queue: z.string().describe('Queue name to check'),
|
|
44
|
+
}, async (args) => {
|
|
45
|
+
try {
|
|
46
|
+
const result = await client.send('ISPAUSED', { queue: args.queue });
|
|
47
|
+
return formatSuccess(result);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return formatError(error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// drain_queue
|
|
54
|
+
server.tool('drain_queue', 'Remove all waiting jobs from a queue. Active (processing) jobs are not affected. Returns the number of jobs removed.', {
|
|
55
|
+
queue: z.string().describe('Queue name to drain'),
|
|
56
|
+
}, async (args) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await client.send('DRAIN', { queue: args.queue });
|
|
59
|
+
return formatSuccess(result);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return formatError(error);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// count_jobs
|
|
66
|
+
server.tool('count_jobs', 'Get the total count of jobs (waiting + delayed) in a queue. Does not include active, completed, or failed jobs.', {
|
|
67
|
+
queue: z.string().describe('Queue name'),
|
|
68
|
+
}, async (args) => {
|
|
69
|
+
try {
|
|
70
|
+
const result = await client.send('COUNT', { queue: args.queue });
|
|
71
|
+
return formatSuccess(result);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return formatError(error);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// set_rate_limit
|
|
78
|
+
server.tool('set_rate_limit', 'Set a rate limit (jobs per second) for a queue to control processing speed. Useful for external API rate limiting.', {
|
|
79
|
+
queue: z.string().describe('Queue name'),
|
|
80
|
+
limit: z.number().positive().describe('Maximum jobs per second'),
|
|
81
|
+
}, async (args) => {
|
|
82
|
+
try {
|
|
83
|
+
const result = await client.send('RATELIMIT', { queue: args.queue, limit: args.limit });
|
|
84
|
+
return formatSuccess(result);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return formatError(error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
// clear_rate_limit
|
|
91
|
+
server.tool('clear_rate_limit', 'Remove the rate limit from a queue, allowing unlimited processing speed.', {
|
|
92
|
+
queue: z.string().describe('Queue name'),
|
|
93
|
+
}, async (args) => {
|
|
94
|
+
try {
|
|
95
|
+
const result = await client.send('RATELIMITCLEAR', { queue: args.queue });
|
|
96
|
+
return formatSuccess(result);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
return formatError(error);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=queues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queues.js","sourceRoot":"","sources":["../../src/tools/queues.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flashq-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP (Model Context Protocol) server for flashQ job queue - enables AI assistants like Claude to manage job queues",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"flashq-mcp": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"dev": "tsx src/index.ts",
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"lint": "eslint src/",
|
|
22
|
+
"lint:fix": "eslint src/ --fix",
|
|
23
|
+
"format": "prettier --write src/",
|
|
24
|
+
"format:check": "prettier --check src/",
|
|
25
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm run build"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
29
|
+
"zod": "^3.25.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@eslint/js": "^9.0.0",
|
|
33
|
+
"@types/node": "^22.0.0",
|
|
34
|
+
"eslint": "^9.0.0",
|
|
35
|
+
"prettier": "^3.0.0",
|
|
36
|
+
"tsx": "^4.0.0",
|
|
37
|
+
"typescript": "^5.0.0",
|
|
38
|
+
"typescript-eslint": "^8.0.0",
|
|
39
|
+
"vitest": "^2.0.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.0.0"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"flashq",
|
|
46
|
+
"mcp",
|
|
47
|
+
"model-context-protocol",
|
|
48
|
+
"job-queue",
|
|
49
|
+
"claude",
|
|
50
|
+
"ai",
|
|
51
|
+
"anthropic",
|
|
52
|
+
"queue",
|
|
53
|
+
"worker"
|
|
54
|
+
],
|
|
55
|
+
"author": "flashQ Team",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/flashq/flashq.git",
|
|
60
|
+
"directory": "mcp"
|
|
61
|
+
},
|
|
62
|
+
"homepage": "https://github.com/flashq/flashq/tree/main/mcp#readme",
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://github.com/flashq/flashq/issues"
|
|
65
|
+
}
|
|
66
|
+
}
|