agent-orchestrator-mcp-server 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { IAgentOrchestratorClient } from '../orchestrator-client/orchestrator-client.js';
4
+ export declare const ManageEnqueuedMessagesSchema: z.ZodObject<{
5
+ session_id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
6
+ action: z.ZodEnum<["list", "get", "create", "update", "delete", "reorder", "interrupt"]>;
7
+ message_id: z.ZodOptional<z.ZodNumber>;
8
+ content: z.ZodOptional<z.ZodString>;
9
+ stop_condition: z.ZodOptional<z.ZodString>;
10
+ position: z.ZodOptional<z.ZodNumber>;
11
+ page: z.ZodOptional<z.ZodNumber>;
12
+ per_page: z.ZodOptional<z.ZodNumber>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ session_id: string | number;
15
+ action: "list" | "get" | "create" | "update" | "delete" | "reorder" | "interrupt";
16
+ per_page?: number | undefined;
17
+ page?: number | undefined;
18
+ content?: string | undefined;
19
+ stop_condition?: string | undefined;
20
+ message_id?: number | undefined;
21
+ position?: number | undefined;
22
+ }, {
23
+ session_id: string | number;
24
+ action: "list" | "get" | "create" | "update" | "delete" | "reorder" | "interrupt";
25
+ per_page?: number | undefined;
26
+ page?: number | undefined;
27
+ content?: string | undefined;
28
+ stop_condition?: string | undefined;
29
+ message_id?: number | undefined;
30
+ position?: number | undefined;
31
+ }>;
32
+ export declare function manageEnqueuedMessagesTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
33
+ name: string;
34
+ description: string;
35
+ inputSchema: {
36
+ type: "object";
37
+ properties: {
38
+ session_id: {
39
+ oneOf: {
40
+ type: string;
41
+ }[];
42
+ description: string;
43
+ };
44
+ action: {
45
+ type: string;
46
+ enum: readonly ["list", "get", "create", "update", "delete", "reorder", "interrupt"];
47
+ description: string;
48
+ };
49
+ message_id: {
50
+ type: string;
51
+ description: string;
52
+ };
53
+ content: {
54
+ type: string;
55
+ description: string;
56
+ };
57
+ stop_condition: {
58
+ type: string;
59
+ description: string;
60
+ };
61
+ position: {
62
+ type: string;
63
+ minimum: number;
64
+ description: string;
65
+ };
66
+ page: {
67
+ type: string;
68
+ minimum: number;
69
+ description: string;
70
+ };
71
+ per_page: {
72
+ type: string;
73
+ minimum: number;
74
+ maximum: number;
75
+ description: string;
76
+ };
77
+ };
78
+ required: string[];
79
+ };
80
+ handler: (args: unknown) => Promise<{
81
+ content: {
82
+ type: string;
83
+ text: string;
84
+ }[];
85
+ isError: boolean;
86
+ } | {
87
+ content: {
88
+ type: string;
89
+ text: string;
90
+ }[];
91
+ isError?: undefined;
92
+ }>;
93
+ };
94
+ //# sourceMappingURL=manage-enqueued-messages.d.ts.map
@@ -0,0 +1,259 @@
1
+ import { z } from 'zod';
2
+ const ACTION_ENUM = ['list', 'get', 'create', 'update', 'delete', 'reorder', 'interrupt'];
3
+ export const ManageEnqueuedMessagesSchema = z.object({
4
+ session_id: z.union([z.string(), z.number()]),
5
+ action: z.enum(ACTION_ENUM),
6
+ message_id: z.number().optional(),
7
+ content: z.string().optional(),
8
+ stop_condition: z.string().optional(),
9
+ position: z.number().min(1).optional(),
10
+ page: z.number().min(1).optional(),
11
+ per_page: z.number().min(1).max(100).optional(),
12
+ });
13
+ const TOOL_DESCRIPTION = `Manage the enqueued message queue for an agent session.
14
+
15
+ **Actions:**
16
+ - **list**: List all enqueued messages for a session (supports pagination)
17
+ - **get**: Get a specific enqueued message by ID
18
+ - **create**: Add a new message to the queue (requires "content")
19
+ - **update**: Update an existing message (requires "message_id")
20
+ - **delete**: Remove a message from the queue (requires "message_id")
21
+ - **reorder**: Change a message's position in the queue (requires "message_id" and "position")
22
+ - **interrupt**: Pause the session and send this message immediately (requires "message_id")
23
+
24
+ Enqueued messages are follow-up prompts queued to be sent to the agent in order.`;
25
+ export function manageEnqueuedMessagesTool(_server, clientFactory) {
26
+ return {
27
+ name: 'manage_enqueued_messages',
28
+ description: TOOL_DESCRIPTION,
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ session_id: {
33
+ oneOf: [{ type: 'string' }, { type: 'number' }],
34
+ description: 'Session ID (numeric) or slug (string).',
35
+ },
36
+ action: {
37
+ type: 'string',
38
+ enum: ACTION_ENUM,
39
+ description: 'Action to perform on enqueued messages.',
40
+ },
41
+ message_id: {
42
+ type: 'number',
43
+ description: 'Message ID. Required for get, update, delete, reorder, and interrupt.',
44
+ },
45
+ content: {
46
+ type: 'string',
47
+ description: 'Message content. Required for create. Optional for update.',
48
+ },
49
+ stop_condition: {
50
+ type: 'string',
51
+ description: 'Stop condition for this message. Optional for create and update.',
52
+ },
53
+ position: {
54
+ type: 'number',
55
+ minimum: 1,
56
+ description: 'New position in queue. Required for reorder.',
57
+ },
58
+ page: { type: 'number', minimum: 1, description: 'Page number for list. Default: 1' },
59
+ per_page: {
60
+ type: 'number',
61
+ minimum: 1,
62
+ maximum: 100,
63
+ description: 'Results per page for list. Default: 25',
64
+ },
65
+ },
66
+ required: ['session_id', 'action'],
67
+ },
68
+ handler: async (args) => {
69
+ try {
70
+ const validated = ManageEnqueuedMessagesSchema.parse(args);
71
+ const client = clientFactory();
72
+ const { session_id, action, message_id, content, stop_condition, position, page, per_page, } = validated;
73
+ let result;
74
+ switch (action) {
75
+ case 'list': {
76
+ const response = await client.listEnqueuedMessages(session_id, { page, per_page });
77
+ if (response.enqueued_messages.length === 0) {
78
+ result = '## Enqueued Messages\n\nNo enqueued messages found.';
79
+ }
80
+ else {
81
+ const lines = [
82
+ `## Enqueued Messages (${response.pagination.total_count} total, page ${response.pagination.page} of ${response.pagination.total_pages})`,
83
+ '',
84
+ ];
85
+ response.enqueued_messages.forEach((msg) => {
86
+ lines.push(`### Position ${msg.position} (ID: ${msg.id})`);
87
+ lines.push(`- **Status:** ${msg.status}`);
88
+ lines.push(`- **Content:** ${msg.content.substring(0, 200)}${msg.content.length > 200 ? '...' : ''}`);
89
+ if (msg.stop_condition)
90
+ lines.push(`- **Stop Condition:** ${msg.stop_condition}`);
91
+ lines.push('');
92
+ });
93
+ result = lines.join('\n');
94
+ }
95
+ break;
96
+ }
97
+ case 'get': {
98
+ if (!message_id) {
99
+ return {
100
+ content: [
101
+ { type: 'text', text: 'Error: "message_id" is required for the "get" action.' },
102
+ ],
103
+ isError: true,
104
+ };
105
+ }
106
+ const msg = await client.getEnqueuedMessage(session_id, message_id);
107
+ result = [
108
+ `## Enqueued Message #${msg.id}`,
109
+ '',
110
+ `- **Session ID:** ${msg.session_id}`,
111
+ `- **Position:** ${msg.position}`,
112
+ `- **Status:** ${msg.status}`,
113
+ `- **Content:** ${msg.content}`,
114
+ msg.stop_condition ? `- **Stop Condition:** ${msg.stop_condition}` : '',
115
+ `- **Created:** ${msg.created_at}`,
116
+ ]
117
+ .filter(Boolean)
118
+ .join('\n');
119
+ break;
120
+ }
121
+ case 'create': {
122
+ if (!content) {
123
+ return {
124
+ content: [
125
+ { type: 'text', text: 'Error: "content" is required for the "create" action.' },
126
+ ],
127
+ isError: true,
128
+ };
129
+ }
130
+ const msg = await client.createEnqueuedMessage(session_id, {
131
+ content,
132
+ stop_condition: stop_condition || undefined,
133
+ });
134
+ result = [
135
+ '## Message Enqueued',
136
+ '',
137
+ `- **ID:** ${msg.id}`,
138
+ `- **Position:** ${msg.position}`,
139
+ `- **Status:** ${msg.status}`,
140
+ `- **Content:** ${msg.content.substring(0, 200)}${msg.content.length > 200 ? '...' : ''}`,
141
+ ].join('\n');
142
+ break;
143
+ }
144
+ case 'update': {
145
+ if (!message_id) {
146
+ return {
147
+ content: [
148
+ {
149
+ type: 'text',
150
+ text: 'Error: "message_id" is required for the "update" action.',
151
+ },
152
+ ],
153
+ isError: true,
154
+ };
155
+ }
156
+ const msg = await client.updateEnqueuedMessage(session_id, message_id, {
157
+ content: content || undefined,
158
+ stop_condition: stop_condition || undefined,
159
+ });
160
+ result = [
161
+ '## Message Updated',
162
+ '',
163
+ `- **ID:** ${msg.id}`,
164
+ `- **Position:** ${msg.position}`,
165
+ `- **Content:** ${msg.content.substring(0, 200)}${msg.content.length > 200 ? '...' : ''}`,
166
+ ].join('\n');
167
+ break;
168
+ }
169
+ case 'delete': {
170
+ if (!message_id) {
171
+ return {
172
+ content: [
173
+ {
174
+ type: 'text',
175
+ text: 'Error: "message_id" is required for the "delete" action.',
176
+ },
177
+ ],
178
+ isError: true,
179
+ };
180
+ }
181
+ await client.deleteEnqueuedMessage(session_id, message_id);
182
+ result = `## Message Deleted\n\nEnqueued message ${message_id} has been removed from the queue.`;
183
+ break;
184
+ }
185
+ case 'reorder': {
186
+ if (!message_id) {
187
+ return {
188
+ content: [
189
+ {
190
+ type: 'text',
191
+ text: 'Error: "message_id" is required for the "reorder" action.',
192
+ },
193
+ ],
194
+ isError: true,
195
+ };
196
+ }
197
+ if (!position) {
198
+ return {
199
+ content: [
200
+ { type: 'text', text: 'Error: "position" is required for the "reorder" action.' },
201
+ ],
202
+ isError: true,
203
+ };
204
+ }
205
+ const msg = await client.reorderEnqueuedMessage(session_id, message_id, position);
206
+ result = [
207
+ '## Message Reordered',
208
+ '',
209
+ `- **ID:** ${msg.id}`,
210
+ `- **New Position:** ${msg.position}`,
211
+ ].join('\n');
212
+ break;
213
+ }
214
+ case 'interrupt': {
215
+ if (!message_id) {
216
+ return {
217
+ content: [
218
+ {
219
+ type: 'text',
220
+ text: 'Error: "message_id" is required for the "interrupt" action.',
221
+ },
222
+ ],
223
+ isError: true,
224
+ };
225
+ }
226
+ const response = await client.interruptEnqueuedMessage(session_id, message_id);
227
+ result = [
228
+ '## Message Sent as Interrupt',
229
+ '',
230
+ `- **Session ID:** ${response.session.id}`,
231
+ `- **Session Status:** ${response.session.status}`,
232
+ `- **Message:** ${response.message}`,
233
+ ].join('\n');
234
+ break;
235
+ }
236
+ default: {
237
+ const _exhaustiveCheck = action;
238
+ return {
239
+ content: [{ type: 'text', text: `Error: Unknown action "${_exhaustiveCheck}"` }],
240
+ isError: true,
241
+ };
242
+ }
243
+ }
244
+ return { content: [{ type: 'text', text: result }] };
245
+ }
246
+ catch (error) {
247
+ return {
248
+ content: [
249
+ {
250
+ type: 'text',
251
+ text: `Error managing enqueued messages: ${error instanceof Error ? error.message : 'Unknown error'}`,
252
+ },
253
+ ],
254
+ isError: true,
255
+ };
256
+ }
257
+ },
258
+ };
259
+ }
@@ -0,0 +1,78 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { IAgentOrchestratorClient } from '../orchestrator-client/orchestrator-client.js';
4
+ export declare const SearchTriggersSchema: z.ZodObject<{
5
+ id: z.ZodOptional<z.ZodNumber>;
6
+ trigger_type: z.ZodOptional<z.ZodEnum<["slack", "schedule"]>>;
7
+ status: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
8
+ include_channels: z.ZodOptional<z.ZodBoolean>;
9
+ page: z.ZodOptional<z.ZodNumber>;
10
+ per_page: z.ZodOptional<z.ZodNumber>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ per_page?: number | undefined;
13
+ status?: "enabled" | "disabled" | undefined;
14
+ page?: number | undefined;
15
+ trigger_type?: "slack" | "schedule" | undefined;
16
+ id?: number | undefined;
17
+ include_channels?: boolean | undefined;
18
+ }, {
19
+ per_page?: number | undefined;
20
+ status?: "enabled" | "disabled" | undefined;
21
+ page?: number | undefined;
22
+ trigger_type?: "slack" | "schedule" | undefined;
23
+ id?: number | undefined;
24
+ include_channels?: boolean | undefined;
25
+ }>;
26
+ export declare function searchTriggersTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
27
+ name: string;
28
+ description: string;
29
+ inputSchema: {
30
+ type: "object";
31
+ properties: {
32
+ id: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ trigger_type: {
37
+ type: string;
38
+ enum: string[];
39
+ description: string;
40
+ };
41
+ status: {
42
+ type: string;
43
+ enum: string[];
44
+ description: string;
45
+ };
46
+ include_channels: {
47
+ type: string;
48
+ description: string;
49
+ };
50
+ page: {
51
+ type: string;
52
+ minimum: number;
53
+ description: string;
54
+ };
55
+ per_page: {
56
+ type: string;
57
+ minimum: number;
58
+ maximum: number;
59
+ description: string;
60
+ };
61
+ };
62
+ required: never[];
63
+ };
64
+ handler: (args: unknown) => Promise<{
65
+ content: {
66
+ type: string;
67
+ text: string;
68
+ }[];
69
+ isError?: undefined;
70
+ } | {
71
+ content: {
72
+ type: string;
73
+ text: string;
74
+ }[];
75
+ isError: boolean;
76
+ }>;
77
+ };
78
+ //# sourceMappingURL=search-triggers.d.ts.map
@@ -0,0 +1,145 @@
1
+ import { z } from 'zod';
2
+ export const SearchTriggersSchema = z.object({
3
+ id: z.number().optional(),
4
+ trigger_type: z.enum(['slack', 'schedule']).optional(),
5
+ status: z.enum(['enabled', 'disabled']).optional(),
6
+ include_channels: z.boolean().optional(),
7
+ page: z.number().min(1).optional(),
8
+ per_page: z.number().min(1).max(100).optional(),
9
+ });
10
+ const TOOL_DESCRIPTION = `Search and list automation triggers.
11
+
12
+ **Modes:**
13
+ - **Get by ID**: Provide an id to get trigger details with recent sessions
14
+ - **List**: List triggers with optional filters (trigger_type, status, pagination)
15
+ - **Include channels**: Set include_channels=true to also list available Slack channels (useful when creating Slack triggers)
16
+
17
+ **Use cases:**
18
+ - View configured automations (scheduled tasks, Slack integrations)
19
+ - Check trigger status and execution history
20
+ - Discover available Slack channels for new triggers`;
21
+ export function searchTriggersTool(_server, clientFactory) {
22
+ return {
23
+ name: 'search_triggers',
24
+ description: TOOL_DESCRIPTION,
25
+ inputSchema: {
26
+ type: 'object',
27
+ properties: {
28
+ id: {
29
+ type: 'number',
30
+ description: 'Get a specific trigger by ID. Returns trigger details with recent sessions.',
31
+ },
32
+ trigger_type: {
33
+ type: 'string',
34
+ enum: ['slack', 'schedule'],
35
+ description: 'Filter by trigger type.',
36
+ },
37
+ status: {
38
+ type: 'string',
39
+ enum: ['enabled', 'disabled'],
40
+ description: 'Filter by status.',
41
+ },
42
+ include_channels: {
43
+ type: 'boolean',
44
+ description: 'Include available Slack channels. Default: false',
45
+ },
46
+ page: { type: 'number', minimum: 1, description: 'Page number. Default: 1' },
47
+ per_page: {
48
+ type: 'number',
49
+ minimum: 1,
50
+ maximum: 100,
51
+ description: 'Results per page. Default: 25',
52
+ },
53
+ },
54
+ required: [],
55
+ },
56
+ handler: async (args) => {
57
+ try {
58
+ const validated = SearchTriggersSchema.parse(args);
59
+ const client = clientFactory();
60
+ if (validated.id) {
61
+ const response = await client.getTrigger(validated.id);
62
+ const t = response.trigger;
63
+ const lines = [
64
+ `## Trigger: ${t.name}`,
65
+ '',
66
+ `- **ID:** ${t.id}`,
67
+ `- **Type:** ${t.trigger_type}`,
68
+ `- **Status:** ${t.status}`,
69
+ `- **Agent Root:** ${t.agent_root_name}`,
70
+ `- **Reuse Session:** ${t.reuse_session ? 'Yes' : 'No'}`,
71
+ `- **MCP Servers:** ${t.mcp_servers.length > 0 ? t.mcp_servers.join(', ') : '(none)'}`,
72
+ ];
73
+ if (t.stop_condition)
74
+ lines.push(`- **Stop Condition:** ${t.stop_condition}`);
75
+ if (t.schedule_description)
76
+ lines.push(`- **Schedule:** ${t.schedule_description}`);
77
+ lines.push(`- **Sessions Created:** ${t.sessions_created_count}`);
78
+ if (t.last_triggered_at)
79
+ lines.push(`- **Last Triggered:** ${t.last_triggered_at}`);
80
+ lines.push('', '### Prompt Template', '```', t.prompt_template, '```');
81
+ if (t.configuration && Object.keys(t.configuration).length > 0) {
82
+ lines.push('', '### Configuration', '```json', JSON.stringify(t.configuration, null, 2), '```');
83
+ }
84
+ if (response.recent_sessions && response.recent_sessions.length > 0) {
85
+ lines.push('', '### Recent Sessions');
86
+ response.recent_sessions.forEach((s) => {
87
+ lines.push(`- **#${s.id}** ${s.title} (${s.status})`);
88
+ });
89
+ }
90
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
91
+ }
92
+ // List triggers
93
+ const response = await client.listTriggers({
94
+ trigger_type: validated.trigger_type,
95
+ status: validated.status,
96
+ page: validated.page,
97
+ per_page: validated.per_page,
98
+ });
99
+ const lines = [];
100
+ if (response.triggers.length === 0) {
101
+ lines.push('## Triggers\n\nNo triggers found.');
102
+ }
103
+ else {
104
+ lines.push(`## Triggers (${response.pagination.total_count} total, page ${response.pagination.page} of ${response.pagination.total_pages})`, '');
105
+ response.triggers.forEach((t) => {
106
+ lines.push(`### ${t.name} (ID: ${t.id})`);
107
+ lines.push(`- **Type:** ${t.trigger_type} | **Status:** ${t.status} | **Sessions:** ${t.sessions_created_count}`);
108
+ if (t.schedule_description)
109
+ lines.push(`- **Schedule:** ${t.schedule_description}`);
110
+ lines.push('');
111
+ });
112
+ }
113
+ if (validated.include_channels) {
114
+ try {
115
+ const channels = await client.getTriggerChannels();
116
+ lines.push('', '## Available Slack Channels', '');
117
+ if (channels.channels.length === 0) {
118
+ lines.push('No Slack channels available.');
119
+ }
120
+ else {
121
+ channels.channels.forEach((ch) => {
122
+ lines.push(`- **#${ch.name}** (${ch.id}) - ${ch.num_members} members${ch.is_private ? ' [private]' : ''}`);
123
+ });
124
+ }
125
+ }
126
+ catch (error) {
127
+ lines.push('', `*Could not fetch Slack channels: ${error instanceof Error ? error.message : 'Unknown error'}*`);
128
+ }
129
+ }
130
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
131
+ }
132
+ catch (error) {
133
+ return {
134
+ content: [
135
+ {
136
+ type: 'text',
137
+ text: `Error searching triggers: ${error instanceof Error ? error.message : 'Unknown error'}`,
138
+ },
139
+ ],
140
+ isError: true,
141
+ };
142
+ }
143
+ },
144
+ };
145
+ }
package/shared/tools.d.ts CHANGED
@@ -1,15 +1,13 @@
1
1
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { ClientFactory } from './server.js';
3
3
  /**
4
- * Available tool groups for agent-orchestrator:
5
- * - 'readonly': Read-only operations (search_sessions, get_session)
6
- * - 'write': Write operations (start_session, action_session)
7
- * - 'admin': Administrative operations (reserved for future use)
4
+ * Available tool groups for agent-orchestrator.
5
+ * Each domain has a base group (full access) and a _readonly variant (read-only).
8
6
  */
9
- export type ToolGroup = 'readonly' | 'write' | 'admin';
7
+ export type ToolGroup = 'sessions' | 'sessions_readonly' | 'notifications' | 'notifications_readonly' | 'triggers' | 'triggers_readonly' | 'health' | 'health_readonly';
10
8
  /**
11
- * Parse enabled tool groups from environment variable.
12
- * @param enabledGroupsParam - Comma-separated list of groups (e.g., "readonly,write")
9
+ * Parse enabled tool groups from environment variable or parameter.
10
+ * @param enabledGroupsParam - Comma-separated list of groups (e.g., "sessions,notifications")
13
11
  * @returns Array of enabled tool groups
14
12
  */
15
13
  export declare function parseEnabledToolGroups(enabledGroupsParam?: string): ToolGroup[];
@@ -21,9 +19,9 @@ export declare function parseEnabledToolGroups(enabledGroupsParam?: string): Too
21
19
  * a factory pattern that accepts the server and clientFactory as parameters.
22
20
  *
23
21
  * @param clientFactory - Factory function that creates client instances
24
- * @param enabledGroups - Optional array of enabled tool groups (defaults to all)
22
+ * @param enabledGroups - Optional string of enabled tool groups (defaults to all)
25
23
  * @returns Function that registers all tools with a server
26
24
  */
27
- export declare function createRegisterTools(clientFactory: ClientFactory, enabledGroups?: ToolGroup[]): (server: Server) => void;
25
+ export declare function createRegisterTools(clientFactory: ClientFactory, enabledGroups?: string): (server: Server) => void;
28
26
  export declare function registerTools(server: Server): void;
29
27
  //# sourceMappingURL=tools.d.ts.map