agent-pool-mcp 1.2.1 → 1.4.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 +1 -1
- package/package.json +1 -1
- package/src/scheduler/daemon.js +5 -5
- package/src/scheduler/pipeline.js +4 -4
- package/src/scheduler/scheduler.js +3 -3
- package/src/server.js +74 -2
- package/src/tool-definitions.js +21 -1
package/README.md
CHANGED
|
@@ -282,7 +282,7 @@ src/
|
|
|
282
282
|
- **Live Events**: Progress polling uses a ring buffer to show the latest activity without overwhelming context.
|
|
283
283
|
- **Depth Tracking**: Nested orchestration support with optional `AGENT_POOL_MAX_DEPTH` limit.
|
|
284
284
|
- **Adaptive Polling**: Pipeline daemon uses 3s intervals when active, 30s when idle.
|
|
285
|
-
- **File-Based Communication**: Pipeline agents communicate through `.
|
|
285
|
+
- **File-Based Communication**: Pipeline agents communicate through `.agents/runs/` JSON files — each Gemini process has its own MCP server instance but shares state via filesystem.
|
|
286
286
|
|
|
287
287
|
## License
|
|
288
288
|
|
package/package.json
CHANGED
package/src/scheduler/daemon.js
CHANGED
|
@@ -17,9 +17,9 @@ import { join, dirname } from 'node:path';
|
|
|
17
17
|
import { matchesCron } from './cron.js';
|
|
18
18
|
|
|
19
19
|
const POLL_INTERVAL_MS = 30_000; // Check schedules every 30 seconds
|
|
20
|
-
const PID_FILE = '.
|
|
21
|
-
const SCHEDULE_FILE = '.
|
|
22
|
-
const RESULTS_DIR = '.
|
|
20
|
+
const PID_FILE = '.agents/scheduler.pid';
|
|
21
|
+
const SCHEDULE_FILE = '.agents/schedule.json';
|
|
22
|
+
const RESULTS_DIR = '.agents/scheduled-results';
|
|
23
23
|
|
|
24
24
|
/** @type {string} */
|
|
25
25
|
const cwd = process.argv[2] || process.cwd();
|
|
@@ -163,8 +163,8 @@ function executeSchedule(schedule) {
|
|
|
163
163
|
|
|
164
164
|
import { readdirSync } from 'node:fs';
|
|
165
165
|
|
|
166
|
-
const PIPELINES_DIR = '.
|
|
167
|
-
const RUNS_DIR = '.
|
|
166
|
+
const PIPELINES_DIR = '.agents/pipelines';
|
|
167
|
+
const RUNS_DIR = '.agents/runs';
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* Spawn a Gemini CLI agent for a pipeline step.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pipeline management — CRUD for pipeline definitions and run state.
|
|
3
3
|
*
|
|
4
|
-
* Pipelines are stored as JSON templates in .
|
|
5
|
-
* Each execution creates a run state in .
|
|
4
|
+
* Pipelines are stored as JSON templates in .agents/pipelines/.
|
|
5
|
+
* Each execution creates a run state in .agents/runs/.
|
|
6
6
|
*
|
|
7
7
|
* @module agent-pool/scheduler/pipeline
|
|
8
8
|
*/
|
|
@@ -12,8 +12,8 @@ import { join, dirname } from 'node:path';
|
|
|
12
12
|
import { randomUUID } from 'node:crypto';
|
|
13
13
|
import { ensureDaemon } from './scheduler.js';
|
|
14
14
|
|
|
15
|
-
const PIPELINES_DIR = '.
|
|
16
|
-
const RUNS_DIR = '.
|
|
15
|
+
const PIPELINES_DIR = '.agents/pipelines';
|
|
16
|
+
const RUNS_DIR = '.agents/runs';
|
|
17
17
|
|
|
18
18
|
// ─── Helpers ────────────────────────────────────────────────
|
|
19
19
|
|
|
@@ -15,9 +15,9 @@ import { nextCronRun } from './cron.js';
|
|
|
15
15
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
16
|
const DAEMON_SCRIPT = join(__dirname, 'daemon.js');
|
|
17
17
|
|
|
18
|
-
const SCHEDULE_FILE = '.
|
|
19
|
-
const RESULTS_DIR = '.
|
|
20
|
-
const PID_FILE = '.
|
|
18
|
+
const SCHEDULE_FILE = '.agents/schedule.json';
|
|
19
|
+
const RESULTS_DIR = '.agents/scheduled-results';
|
|
20
|
+
const PID_FILE = '.agents/scheduler.pid';
|
|
21
21
|
|
|
22
22
|
// ─── Schedule CRUD ──────────────────────────────────────────
|
|
23
23
|
|
package/src/server.js
CHANGED
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
9
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
10
|
import {
|
|
10
11
|
ListToolsRequestSchema,
|
|
11
12
|
CallToolRequestSchema,
|
|
13
|
+
ListResourcesRequestSchema,
|
|
14
|
+
ReadResourceRequestSchema,
|
|
12
15
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
13
16
|
import { randomUUID } from 'node:crypto';
|
|
14
17
|
|
|
@@ -108,9 +111,33 @@ export function createServer() {
|
|
|
108
111
|
|
|
109
112
|
const server = new Server(
|
|
110
113
|
{ name: 'agent-pool', version: '1.2.1' },
|
|
111
|
-
{ capabilities: { tools: {} } },
|
|
114
|
+
{ capabilities: { tools: {}, resources: {} } },
|
|
112
115
|
);
|
|
113
116
|
|
|
117
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
118
|
+
resources: [{
|
|
119
|
+
uri: 'agent-pool://guide',
|
|
120
|
+
name: 'Usage Guide',
|
|
121
|
+
description: 'Comprehensive guide for agent-pool',
|
|
122
|
+
mimeType: 'text/markdown',
|
|
123
|
+
}],
|
|
124
|
+
}));
|
|
125
|
+
|
|
126
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
127
|
+
if (request.params.uri === 'agent-pool://guide') {
|
|
128
|
+
const guidePath = path.resolve(__dirname, '..', 'GUIDE.md');
|
|
129
|
+
const content = fs.readFileSync(guidePath, 'utf-8');
|
|
130
|
+
return {
|
|
131
|
+
contents: [{
|
|
132
|
+
uri: request.params.uri,
|
|
133
|
+
mimeType: 'text/markdown',
|
|
134
|
+
text: content,
|
|
135
|
+
}],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
throw new Error(`Resource not found: ${request.params.uri}`);
|
|
139
|
+
});
|
|
140
|
+
|
|
114
141
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
115
142
|
tools: TOOL_DEFINITIONS,
|
|
116
143
|
}));
|
|
@@ -155,6 +182,8 @@ export function createServer() {
|
|
|
155
182
|
response = handleCancelSchedule(args); break;
|
|
156
183
|
case 'get_scheduled_results':
|
|
157
184
|
response = handleGetScheduledResults(args); break;
|
|
185
|
+
case 'get_usage_guide':
|
|
186
|
+
response = handleGetUsageGuide(args); break;
|
|
158
187
|
case 'create_pipeline':
|
|
159
188
|
response = handleCreatePipeline(args); break;
|
|
160
189
|
case 'run_pipeline':
|
|
@@ -169,6 +198,8 @@ export function createServer() {
|
|
|
169
198
|
response = handleSignalStepComplete(args); break;
|
|
170
199
|
case 'bounce_back':
|
|
171
200
|
response = handleBounceBack(args); break;
|
|
201
|
+
case 'get_usage_guide':
|
|
202
|
+
response = handleGetUsageGuide(args); break;
|
|
172
203
|
default:
|
|
173
204
|
response = { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
|
|
174
205
|
}
|
|
@@ -391,7 +422,7 @@ function handleScheduleTask(args) {
|
|
|
391
422
|
return {
|
|
392
423
|
content: [{
|
|
393
424
|
type: 'text',
|
|
394
|
-
text: `⏰ Task scheduled.\n\n- **Schedule ID**: \`${result.scheduleId}\`\n- **Cron**: \`${args.cron}\`\n- **Next run**: ${result.nextRun || 'unknown'}\n- **Prompt**: ${args.prompt.substring(0, 100)}...\n\nDaemon is running in the background. Results will be saved to \`.
|
|
425
|
+
text: `⏰ Task scheduled.\n\n- **Schedule ID**: \`${result.scheduleId}\`\n- **Cron**: \`${args.cron}\`\n- **Next run**: ${result.nextRun || 'unknown'}\n- **Prompt**: ${args.prompt.substring(0, 100)}...\n\nDaemon is running in the background. Results will be saved to \`.agents/scheduled-results/\`.\nUse \`list_schedules\` to see all schedules, \`get_scheduled_results\` to read outputs.`,
|
|
395
426
|
}],
|
|
396
427
|
};
|
|
397
428
|
} catch (error) {
|
|
@@ -616,3 +647,44 @@ function handleBounceBack(args) {
|
|
|
616
647
|
}
|
|
617
648
|
}
|
|
618
649
|
|
|
650
|
+
/** @param {object} args */
|
|
651
|
+
function handleGetUsageGuide(args) {
|
|
652
|
+
const guidePath = path.resolve(__dirname, '..', 'GUIDE.md');
|
|
653
|
+
if (!fs.existsSync(guidePath)) {
|
|
654
|
+
return { content: [{ type: 'text', text: 'Guide not found.' }], isError: true };
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const fullContent = fs.readFileSync(guidePath, 'utf-8');
|
|
658
|
+
|
|
659
|
+
if (!args.topic) {
|
|
660
|
+
return { content: [{ type: 'text', text: fullContent }] };
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const topicLower = args.topic.toLowerCase();
|
|
664
|
+
const lines = fullContent.split('\n');
|
|
665
|
+
let inTopic = false;
|
|
666
|
+
let topicContent = [];
|
|
667
|
+
|
|
668
|
+
for (const line of lines) {
|
|
669
|
+
if (line.toLowerCase().startsWith(`## ${topicLower}`)) {
|
|
670
|
+
inTopic = true;
|
|
671
|
+
topicContent.push(line);
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if (inTopic && line.startsWith('## ')) {
|
|
676
|
+
break; // End of section
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (inTopic) {
|
|
680
|
+
topicContent.push(line);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
if (topicContent.length === 0) {
|
|
685
|
+
return { content: [{ type: 'text', text: `Topic '${args.topic}' not found in the guide.\n\nAvailable topics: delegation, pipelines, scheduling, skills, peer-review, sessions.` }] };
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return { content: [{ type: 'text', text: topicContent.join('\n').trim() }] };
|
|
689
|
+
}
|
|
690
|
+
|
package/src/tool-definitions.js
CHANGED
|
@@ -6,6 +6,26 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export const TOOL_DEFINITIONS = [
|
|
9
|
+
{
|
|
10
|
+
name: 'get_usage_guide',
|
|
11
|
+
description: [
|
|
12
|
+
'Get the comprehensive usage guide for agent-pool with examples and best practices.',
|
|
13
|
+
'Call this FIRST when planning how to use agent-pool tools for parallel work, pipelines, or scheduling.',
|
|
14
|
+
'Returns practical examples for each feature area.',
|
|
15
|
+
'',
|
|
16
|
+
'Available topics: delegation, pipelines, scheduling, skills, peer-review, sessions.',
|
|
17
|
+
'Omit topic to get the full guide.',
|
|
18
|
+
].join('\n'),
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: 'object',
|
|
21
|
+
properties: {
|
|
22
|
+
topic: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Optional topic filter: delegation, pipelines, scheduling, skills, peer-review, sessions',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
9
29
|
{
|
|
10
30
|
name: 'delegate_task',
|
|
11
31
|
description: [
|
|
@@ -179,7 +199,7 @@ export const TOOL_DEFINITIONS = [
|
|
|
179
199
|
description: [
|
|
180
200
|
'Schedule a Gemini CLI agent to run on a cron schedule or as a delayed one-shot.',
|
|
181
201
|
'Spawns a persistent daemon that survives IDE/CLI restarts.',
|
|
182
|
-
'Results are saved to .
|
|
202
|
+
'Results are saved to .agents/scheduled-results/ and can be retrieved with get_scheduled_results.',
|
|
183
203
|
'',
|
|
184
204
|
'Cron format: standard 5-field (minute hour day month weekday).',
|
|
185
205
|
'Examples: "*/30 * * * *" (every 30 min), "0 9 * * MON-FRI" (9am weekdays), "0 */2 * * *" (every 2 hours).',
|