agent-orchestrator-mcp-server 0.2.4 → 0.3.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 +125 -30
- package/build/index.js +4 -4
- package/package.json +1 -1
- package/shared/orchestrator-client/orchestrator-client.d.ts +128 -3
- package/shared/orchestrator-client/orchestrator-client.integration-mock.js +313 -1
- package/shared/orchestrator-client/orchestrator-client.js +205 -0
- package/shared/resources.js +9 -4
- package/shared/tools/action-health.d.ts +58 -0
- package/shared/tools/action-health.js +101 -0
- package/shared/tools/action-notification.d.ts +46 -0
- package/shared/tools/action-notification.js +99 -0
- package/shared/tools/action-session.d.ts +33 -9
- package/shared/tools/action-session.js +177 -15
- package/shared/tools/action-trigger.d.ts +114 -0
- package/shared/tools/action-trigger.js +177 -0
- package/shared/tools/get-notifications.d.ts +70 -0
- package/shared/tools/get-notifications.js +113 -0
- package/shared/tools/get-session.d.ts +8 -0
- package/shared/tools/get-session.js +21 -2
- package/shared/tools/get-system-health.d.ts +38 -0
- package/shared/tools/get-system-health.js +69 -0
- package/shared/tools/get-transcript-archive.d.ts +27 -0
- package/shared/tools/get-transcript-archive.js +64 -0
- package/shared/tools/manage-enqueued-messages.d.ts +94 -0
- package/shared/tools/manage-enqueued-messages.js +259 -0
- package/shared/tools/search-sessions.d.ts +3 -10
- package/shared/tools/search-sessions.js +10 -15
- package/shared/tools/search-triggers.d.ts +78 -0
- package/shared/tools/search-triggers.js +145 -0
- package/shared/tools.d.ts +7 -9
- package/shared/tools.js +105 -32
- package/shared/types.d.ts +162 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const ACTION_ENUM = [
|
|
3
|
+
'cleanup_processes',
|
|
4
|
+
'retry_sessions',
|
|
5
|
+
'archive_old',
|
|
6
|
+
'cli_refresh',
|
|
7
|
+
'cli_clear_cache',
|
|
8
|
+
];
|
|
9
|
+
export const ActionHealthSchema = z.object({
|
|
10
|
+
action: z.enum(ACTION_ENUM),
|
|
11
|
+
session_ids: z.array(z.number()).optional(),
|
|
12
|
+
days: z.number().min(1).max(365).optional(),
|
|
13
|
+
});
|
|
14
|
+
const TOOL_DESCRIPTION = `Perform system health and maintenance actions.
|
|
15
|
+
|
|
16
|
+
**Actions:**
|
|
17
|
+
- **cleanup_processes**: Terminate orphaned agent processes
|
|
18
|
+
- **retry_sessions**: Retry failed sessions (optionally specify session_ids)
|
|
19
|
+
- **archive_old**: Archive sessions older than N days (requires "days", default 7)
|
|
20
|
+
- **cli_refresh**: Trigger a background refresh of CLI tool installations
|
|
21
|
+
- **cli_clear_cache**: Clear npm/pip caches and reinstall MCP packages
|
|
22
|
+
|
|
23
|
+
Note: Health actions are rate-limited (30s cooldown between calls).`;
|
|
24
|
+
export function actionHealthTool(_server, clientFactory) {
|
|
25
|
+
return {
|
|
26
|
+
name: 'action_health',
|
|
27
|
+
description: TOOL_DESCRIPTION,
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
action: { type: 'string', enum: ACTION_ENUM, description: 'Health action to perform.' },
|
|
32
|
+
session_ids: {
|
|
33
|
+
type: 'array',
|
|
34
|
+
items: { type: 'number' },
|
|
35
|
+
description: 'Session IDs to retry. For retry_sessions action.',
|
|
36
|
+
},
|
|
37
|
+
days: {
|
|
38
|
+
type: 'number',
|
|
39
|
+
minimum: 1,
|
|
40
|
+
maximum: 365,
|
|
41
|
+
description: 'Archive sessions older than this many days. For archive_old action. Default: 7',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
required: ['action'],
|
|
45
|
+
},
|
|
46
|
+
handler: async (args) => {
|
|
47
|
+
try {
|
|
48
|
+
const validated = ActionHealthSchema.parse(args);
|
|
49
|
+
const client = clientFactory();
|
|
50
|
+
const { action } = validated;
|
|
51
|
+
let result;
|
|
52
|
+
switch (action) {
|
|
53
|
+
case 'cleanup_processes': {
|
|
54
|
+
const response = await client.cleanupProcesses();
|
|
55
|
+
result = `## Processes Cleaned Up\n\n\`\`\`json\n${JSON.stringify(response, null, 2)}\n\`\`\``;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case 'retry_sessions': {
|
|
59
|
+
const response = await client.retrySessions(validated.session_ids);
|
|
60
|
+
result = `## Sessions Retried\n\n\`\`\`json\n${JSON.stringify(response, null, 2)}\n\`\`\``;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case 'archive_old': {
|
|
64
|
+
const response = await client.archiveOldSessions(validated.days);
|
|
65
|
+
result = `## Old Sessions Archived\n\n\`\`\`json\n${JSON.stringify(response, null, 2)}\n\`\`\``;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case 'cli_refresh': {
|
|
69
|
+
const response = await client.refreshCli();
|
|
70
|
+
result = `## CLI Refresh Queued\n\n- **Message:** ${response.message}`;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case 'cli_clear_cache': {
|
|
74
|
+
const response = await client.clearCliCache();
|
|
75
|
+
result = `## CLI Cache Clear Queued\n\n- **Message:** ${response.message}`;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
default: {
|
|
79
|
+
const _exhaustiveCheck = action;
|
|
80
|
+
return {
|
|
81
|
+
content: [{ type: 'text', text: `Error: Unknown action "${_exhaustiveCheck}"` }],
|
|
82
|
+
isError: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { content: [{ type: 'text', text: result }] };
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: 'text',
|
|
93
|
+
text: `Error performing health action: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
isError: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
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 ActionNotificationSchema: z.ZodObject<{
|
|
5
|
+
action: z.ZodEnum<["mark_read", "mark_all_read", "dismiss", "dismiss_all_read"]>;
|
|
6
|
+
id: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
action: "mark_read" | "mark_all_read" | "dismiss" | "dismiss_all_read";
|
|
9
|
+
id?: number | undefined;
|
|
10
|
+
}, {
|
|
11
|
+
action: "mark_read" | "mark_all_read" | "dismiss" | "dismiss_all_read";
|
|
12
|
+
id?: number | undefined;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function actionNotificationTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object";
|
|
19
|
+
properties: {
|
|
20
|
+
action: {
|
|
21
|
+
type: string;
|
|
22
|
+
enum: readonly ["mark_read", "mark_all_read", "dismiss", "dismiss_all_read"];
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
id: {
|
|
26
|
+
type: string;
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
required: string[];
|
|
31
|
+
};
|
|
32
|
+
handler: (args: unknown) => Promise<{
|
|
33
|
+
content: {
|
|
34
|
+
type: string;
|
|
35
|
+
text: string;
|
|
36
|
+
}[];
|
|
37
|
+
isError: boolean;
|
|
38
|
+
} | {
|
|
39
|
+
content: {
|
|
40
|
+
type: string;
|
|
41
|
+
text: string;
|
|
42
|
+
}[];
|
|
43
|
+
isError?: undefined;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=action-notification.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const ACTION_ENUM = ['mark_read', 'mark_all_read', 'dismiss', 'dismiss_all_read'];
|
|
3
|
+
export const ActionNotificationSchema = z.object({
|
|
4
|
+
action: z.enum(ACTION_ENUM),
|
|
5
|
+
id: z.number().optional(),
|
|
6
|
+
});
|
|
7
|
+
const TOOL_DESCRIPTION = `Manage notifications in the Agent Orchestrator.
|
|
8
|
+
|
|
9
|
+
**Actions:**
|
|
10
|
+
- **mark_read**: Mark a specific notification as read (requires "id")
|
|
11
|
+
- **mark_all_read**: Mark all notifications as read
|
|
12
|
+
- **dismiss**: Delete a notification (requires "id", must be read first)
|
|
13
|
+
- **dismiss_all_read**: Delete all read notifications`;
|
|
14
|
+
export function actionNotificationTool(_server, clientFactory) {
|
|
15
|
+
return {
|
|
16
|
+
name: 'action_notification',
|
|
17
|
+
description: TOOL_DESCRIPTION,
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
action: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
enum: ACTION_ENUM,
|
|
24
|
+
description: 'Action to perform.',
|
|
25
|
+
},
|
|
26
|
+
id: {
|
|
27
|
+
type: 'number',
|
|
28
|
+
description: 'Notification ID. Required for mark_read and dismiss.',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: ['action'],
|
|
32
|
+
},
|
|
33
|
+
handler: async (args) => {
|
|
34
|
+
try {
|
|
35
|
+
const validated = ActionNotificationSchema.parse(args);
|
|
36
|
+
const client = clientFactory();
|
|
37
|
+
const { action, id } = validated;
|
|
38
|
+
let result;
|
|
39
|
+
switch (action) {
|
|
40
|
+
case 'mark_read': {
|
|
41
|
+
if (!id) {
|
|
42
|
+
return {
|
|
43
|
+
content: [
|
|
44
|
+
{ type: 'text', text: 'Error: "id" is required for the "mark_read" action.' },
|
|
45
|
+
],
|
|
46
|
+
isError: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const notification = await client.markNotificationRead(id);
|
|
50
|
+
result = `## Notification Marked Read\n\n- **ID:** ${notification.id}\n- **Type:** ${notification.notification_type}`;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case 'mark_all_read': {
|
|
54
|
+
const response = await client.markAllNotificationsRead();
|
|
55
|
+
result = `## All Notifications Marked Read\n\n- **Marked:** ${response.marked_count}\n- **Remaining Pending:** ${response.pending_count}`;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case 'dismiss': {
|
|
59
|
+
if (!id) {
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{ type: 'text', text: 'Error: "id" is required for the "dismiss" action.' },
|
|
63
|
+
],
|
|
64
|
+
isError: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
await client.dismissNotification(id);
|
|
68
|
+
result = `## Notification Dismissed\n\nNotification ${id} has been deleted.`;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'dismiss_all_read': {
|
|
72
|
+
const response = await client.dismissAllReadNotifications();
|
|
73
|
+
result = `## Read Notifications Dismissed\n\n- **Dismissed:** ${response.dismissed_count}\n- **Remaining Pending:** ${response.pending_count}`;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
default: {
|
|
77
|
+
const _exhaustiveCheck = action;
|
|
78
|
+
return {
|
|
79
|
+
content: [{ type: 'text', text: `Error: Unknown action "${_exhaustiveCheck}"` }],
|
|
80
|
+
isError: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { content: [{ type: 'text', text: result }] };
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return {
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: 'text',
|
|
91
|
+
text: `Error managing notification: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
isError: true,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -2,20 +2,29 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { IAgentOrchestratorClient } from '../orchestrator-client/orchestrator-client.js';
|
|
4
4
|
export declare const ActionSessionSchema: z.ZodObject<{
|
|
5
|
-
session_id: z.ZodUnion<[z.ZodString, z.ZodNumber]
|
|
6
|
-
action: z.ZodEnum<["follow_up", "pause", "restart", "archive", "unarchive", "change_mcp_servers"]>;
|
|
5
|
+
session_id: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
|
|
6
|
+
action: z.ZodEnum<["follow_up", "pause", "restart", "archive", "unarchive", "change_mcp_servers", "fork", "refresh", "refresh_all", "update_notes", "toggle_favorite", "bulk_archive"]>;
|
|
7
7
|
prompt: z.ZodOptional<z.ZodString>;
|
|
8
8
|
mcp_servers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
message_index: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
session_notes: z.ZodOptional<z.ZodString>;
|
|
11
|
+
session_ids: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
9
12
|
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
|
|
11
|
-
action: "follow_up" | "pause" | "restart" | "archive" | "unarchive" | "change_mcp_servers";
|
|
13
|
+
action: "follow_up" | "pause" | "restart" | "archive" | "unarchive" | "change_mcp_servers" | "fork" | "refresh" | "refresh_all" | "update_notes" | "toggle_favorite" | "bulk_archive";
|
|
12
14
|
mcp_servers?: string[] | undefined;
|
|
13
15
|
prompt?: string | undefined;
|
|
16
|
+
session_id?: string | number | undefined;
|
|
17
|
+
message_index?: number | undefined;
|
|
18
|
+
session_notes?: string | undefined;
|
|
19
|
+
session_ids?: number[] | undefined;
|
|
14
20
|
}, {
|
|
15
|
-
|
|
16
|
-
action: "follow_up" | "pause" | "restart" | "archive" | "unarchive" | "change_mcp_servers";
|
|
21
|
+
action: "follow_up" | "pause" | "restart" | "archive" | "unarchive" | "change_mcp_servers" | "fork" | "refresh" | "refresh_all" | "update_notes" | "toggle_favorite" | "bulk_archive";
|
|
17
22
|
mcp_servers?: string[] | undefined;
|
|
18
23
|
prompt?: string | undefined;
|
|
24
|
+
session_id?: string | number | undefined;
|
|
25
|
+
message_index?: number | undefined;
|
|
26
|
+
session_notes?: string | undefined;
|
|
27
|
+
session_ids?: number[] | undefined;
|
|
19
28
|
}>;
|
|
20
29
|
export declare function actionSessionTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
|
|
21
30
|
name: string;
|
|
@@ -27,12 +36,12 @@ export declare function actionSessionTool(_server: Server, clientFactory: () =>
|
|
|
27
36
|
oneOf: {
|
|
28
37
|
type: string;
|
|
29
38
|
}[];
|
|
30
|
-
description: "Session ID (numeric) or slug (string)
|
|
39
|
+
description: "Session ID (numeric) or slug (string). Required for most actions. Not required for \"refresh_all\" and \"bulk_archive\".";
|
|
31
40
|
};
|
|
32
41
|
action: {
|
|
33
42
|
type: string;
|
|
34
|
-
enum: readonly ["follow_up", "pause", "restart", "archive", "unarchive", "change_mcp_servers"];
|
|
35
|
-
description: "Action to perform: \"follow_up\"
|
|
43
|
+
enum: readonly ["follow_up", "pause", "restart", "archive", "unarchive", "change_mcp_servers", "fork", "refresh", "refresh_all", "update_notes", "toggle_favorite", "bulk_archive"];
|
|
44
|
+
description: "Action to perform: \"follow_up\", \"pause\", \"restart\", \"archive\", \"unarchive\", \"change_mcp_servers\", \"fork\", \"refresh\", \"refresh_all\", \"update_notes\", \"toggle_favorite\", \"bulk_archive\"";
|
|
36
45
|
};
|
|
37
46
|
prompt: {
|
|
38
47
|
type: string;
|
|
@@ -45,6 +54,21 @@ export declare function actionSessionTool(_server: Server, clientFactory: () =>
|
|
|
45
54
|
};
|
|
46
55
|
description: "Required for \"change_mcp_servers\" action. Array of MCP server names to set for the session.";
|
|
47
56
|
};
|
|
57
|
+
message_index: {
|
|
58
|
+
type: string;
|
|
59
|
+
description: "Required for \"fork\" action. The transcript message index to fork from.";
|
|
60
|
+
};
|
|
61
|
+
session_notes: {
|
|
62
|
+
type: string;
|
|
63
|
+
description: "Required for \"update_notes\" action. The notes text to set on the session.";
|
|
64
|
+
};
|
|
65
|
+
session_ids: {
|
|
66
|
+
type: string;
|
|
67
|
+
items: {
|
|
68
|
+
type: string;
|
|
69
|
+
};
|
|
70
|
+
description: "Required for \"bulk_archive\" action. Array of session IDs to archive.";
|
|
71
|
+
};
|
|
48
72
|
};
|
|
49
73
|
required: string[];
|
|
50
74
|
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const PARAM_DESCRIPTIONS = {
|
|
3
|
-
session_id: 'Session ID (numeric) or slug (string)
|
|
4
|
-
action: 'Action to perform: "follow_up"
|
|
3
|
+
session_id: 'Session ID (numeric) or slug (string). Required for most actions. Not required for "refresh_all" and "bulk_archive".',
|
|
4
|
+
action: 'Action to perform: "follow_up", "pause", "restart", "archive", "unarchive", "change_mcp_servers", "fork", "refresh", "refresh_all", "update_notes", "toggle_favorite", "bulk_archive"',
|
|
5
5
|
prompt: 'Required for "follow_up" action. The prompt to send to the agent. Not used for other actions.',
|
|
6
6
|
mcp_servers: 'Required for "change_mcp_servers" action. Array of MCP server names to set for the session.',
|
|
7
|
+
message_index: 'Required for "fork" action. The transcript message index to fork from.',
|
|
8
|
+
session_notes: 'Required for "update_notes" action. The notes text to set on the session.',
|
|
9
|
+
session_ids: 'Required for "bulk_archive" action. Array of session IDs to archive.',
|
|
7
10
|
};
|
|
8
11
|
const ACTION_ENUM = [
|
|
9
12
|
'follow_up',
|
|
@@ -12,12 +15,21 @@ const ACTION_ENUM = [
|
|
|
12
15
|
'archive',
|
|
13
16
|
'unarchive',
|
|
14
17
|
'change_mcp_servers',
|
|
18
|
+
'fork',
|
|
19
|
+
'refresh',
|
|
20
|
+
'refresh_all',
|
|
21
|
+
'update_notes',
|
|
22
|
+
'toggle_favorite',
|
|
23
|
+
'bulk_archive',
|
|
15
24
|
];
|
|
16
25
|
export const ActionSessionSchema = z.object({
|
|
17
|
-
session_id: z.union([z.string(), z.number()]).describe(PARAM_DESCRIPTIONS.session_id),
|
|
26
|
+
session_id: z.union([z.string(), z.number()]).optional().describe(PARAM_DESCRIPTIONS.session_id),
|
|
18
27
|
action: z.enum(ACTION_ENUM).describe(PARAM_DESCRIPTIONS.action),
|
|
19
28
|
prompt: z.string().optional().describe(PARAM_DESCRIPTIONS.prompt),
|
|
20
29
|
mcp_servers: z.array(z.string()).optional().describe(PARAM_DESCRIPTIONS.mcp_servers),
|
|
30
|
+
message_index: z.number().optional().describe(PARAM_DESCRIPTIONS.message_index),
|
|
31
|
+
session_notes: z.string().optional().describe(PARAM_DESCRIPTIONS.session_notes),
|
|
32
|
+
session_ids: z.array(z.number()).optional().describe(PARAM_DESCRIPTIONS.session_ids),
|
|
21
33
|
});
|
|
22
34
|
const TOOL_DESCRIPTION = `Perform an action on an agent session.
|
|
23
35
|
|
|
@@ -28,19 +40,17 @@ const TOOL_DESCRIPTION = `Perform an action on an agent session.
|
|
|
28
40
|
- **archive**: Archive a session (marks as completed)
|
|
29
41
|
- **unarchive**: Restore an archived session to "needs_input" status
|
|
30
42
|
- **change_mcp_servers**: Update the MCP servers for a session (requires "mcp_servers" parameter)
|
|
31
|
-
|
|
32
|
-
**
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- unarchive: Session must be "archived"
|
|
38
|
-
- change_mcp_servers: Session can be in any status except "archived"
|
|
43
|
+
- **fork**: Fork a session from a specific transcript message (requires "message_index")
|
|
44
|
+
- **refresh**: Refresh a single session's status from the execution provider
|
|
45
|
+
- **refresh_all**: Refresh all active sessions (no session_id needed)
|
|
46
|
+
- **update_notes**: Update the notes on a session (requires "session_notes")
|
|
47
|
+
- **toggle_favorite**: Toggle favorite status on a session
|
|
48
|
+
- **bulk_archive**: Archive multiple sessions at once (requires "session_ids", no session_id needed)
|
|
39
49
|
|
|
40
50
|
**Use cases:**
|
|
41
51
|
- Provide additional instructions to an agent
|
|
42
|
-
- Control session lifecycle (pause, restart)
|
|
43
|
-
- Organize sessions (archive, unarchive)
|
|
52
|
+
- Control session lifecycle (pause, restart, fork, refresh)
|
|
53
|
+
- Organize sessions (archive, unarchive, bulk_archive, toggle_favorite, update_notes)
|
|
44
54
|
- Reconfigure session MCP server access`;
|
|
45
55
|
export function actionSessionTool(_server, clientFactory) {
|
|
46
56
|
return {
|
|
@@ -67,14 +77,51 @@ export function actionSessionTool(_server, clientFactory) {
|
|
|
67
77
|
items: { type: 'string' },
|
|
68
78
|
description: PARAM_DESCRIPTIONS.mcp_servers,
|
|
69
79
|
},
|
|
80
|
+
message_index: {
|
|
81
|
+
type: 'number',
|
|
82
|
+
description: PARAM_DESCRIPTIONS.message_index,
|
|
83
|
+
},
|
|
84
|
+
session_notes: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: PARAM_DESCRIPTIONS.session_notes,
|
|
87
|
+
},
|
|
88
|
+
session_ids: {
|
|
89
|
+
type: 'array',
|
|
90
|
+
items: { type: 'number' },
|
|
91
|
+
description: PARAM_DESCRIPTIONS.session_ids,
|
|
92
|
+
},
|
|
70
93
|
},
|
|
71
|
-
required: ['
|
|
94
|
+
required: ['action'],
|
|
72
95
|
},
|
|
73
96
|
handler: async (args) => {
|
|
74
97
|
try {
|
|
75
98
|
const validatedArgs = ActionSessionSchema.parse(args);
|
|
76
99
|
const client = clientFactory();
|
|
77
|
-
const { session_id, action, prompt, mcp_servers } = validatedArgs;
|
|
100
|
+
const { session_id, action, prompt, mcp_servers, message_index, session_notes, session_ids, } = validatedArgs;
|
|
101
|
+
// Actions that require session_id
|
|
102
|
+
const requiresSessionId = [
|
|
103
|
+
'follow_up',
|
|
104
|
+
'pause',
|
|
105
|
+
'restart',
|
|
106
|
+
'archive',
|
|
107
|
+
'unarchive',
|
|
108
|
+
'change_mcp_servers',
|
|
109
|
+
'fork',
|
|
110
|
+
'refresh',
|
|
111
|
+
'update_notes',
|
|
112
|
+
'toggle_favorite',
|
|
113
|
+
];
|
|
114
|
+
if (requiresSessionId.includes(action) && !session_id) {
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: `Error: The "session_id" parameter is required for the "${action}" action.`,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
isError: true,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
78
125
|
// Validate that prompt is provided for follow_up action
|
|
79
126
|
if (action === 'follow_up' && !prompt) {
|
|
80
127
|
return {
|
|
@@ -99,6 +146,42 @@ export function actionSessionTool(_server, clientFactory) {
|
|
|
99
146
|
isError: true,
|
|
100
147
|
};
|
|
101
148
|
}
|
|
149
|
+
// Validate fork requires message_index
|
|
150
|
+
if (action === 'fork' && message_index === undefined) {
|
|
151
|
+
return {
|
|
152
|
+
content: [
|
|
153
|
+
{
|
|
154
|
+
type: 'text',
|
|
155
|
+
text: 'Error: The "message_index" parameter is required for the "fork" action.',
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
isError: true,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Validate update_notes requires session_notes
|
|
162
|
+
if (action === 'update_notes' && session_notes === undefined) {
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: 'text',
|
|
167
|
+
text: 'Error: The "session_notes" parameter is required for the "update_notes" action.',
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
isError: true,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Validate bulk_archive requires session_ids
|
|
174
|
+
if (action === 'bulk_archive' && (!session_ids || session_ids.length === 0)) {
|
|
175
|
+
return {
|
|
176
|
+
content: [
|
|
177
|
+
{
|
|
178
|
+
type: 'text',
|
|
179
|
+
text: 'Error: The "session_ids" parameter is required for the "bulk_archive" action.',
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
isError: true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
102
185
|
let result;
|
|
103
186
|
switch (action) {
|
|
104
187
|
case 'follow_up': {
|
|
@@ -189,6 +272,85 @@ export function actionSessionTool(_server, clientFactory) {
|
|
|
189
272
|
result = lines.join('\n');
|
|
190
273
|
break;
|
|
191
274
|
}
|
|
275
|
+
case 'fork': {
|
|
276
|
+
const response = await client.forkSession(session_id, message_index);
|
|
277
|
+
const lines = [
|
|
278
|
+
`## Session Forked`,
|
|
279
|
+
'',
|
|
280
|
+
`- **New Session ID:** ${response.session.id}`,
|
|
281
|
+
`- **Title:** ${response.session.title}`,
|
|
282
|
+
`- **Status:** ${response.session.status}`,
|
|
283
|
+
`- **Message:** ${response.message}`,
|
|
284
|
+
];
|
|
285
|
+
result = lines.join('\n');
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case 'refresh': {
|
|
289
|
+
const response = await client.refreshSession(session_id);
|
|
290
|
+
const lines = [
|
|
291
|
+
`## Session Refreshed`,
|
|
292
|
+
'',
|
|
293
|
+
`- **Session ID:** ${response.session.id}`,
|
|
294
|
+
`- **Title:** ${response.session.title}`,
|
|
295
|
+
`- **Status:** ${response.session.status}`,
|
|
296
|
+
`- **Message:** ${response.message}`,
|
|
297
|
+
];
|
|
298
|
+
result = lines.join('\n');
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
case 'refresh_all': {
|
|
302
|
+
const response = await client.refreshAllSessions();
|
|
303
|
+
const lines = [
|
|
304
|
+
`## All Sessions Refreshed`,
|
|
305
|
+
'',
|
|
306
|
+
`- **Message:** ${response.message}`,
|
|
307
|
+
`- **Refreshed:** ${response.refreshed}`,
|
|
308
|
+
`- **Restarted:** ${response.restarted}`,
|
|
309
|
+
`- **Continued:** ${response.continued}`,
|
|
310
|
+
`- **Errors:** ${response.errors}`,
|
|
311
|
+
];
|
|
312
|
+
result = lines.join('\n');
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
case 'update_notes': {
|
|
316
|
+
const session = await client.updateSessionNotes(session_id, session_notes);
|
|
317
|
+
const lines = [
|
|
318
|
+
`## Session Notes Updated`,
|
|
319
|
+
'',
|
|
320
|
+
`- **Session ID:** ${session.id}`,
|
|
321
|
+
`- **Title:** ${session.title}`,
|
|
322
|
+
];
|
|
323
|
+
result = lines.join('\n');
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
case 'toggle_favorite': {
|
|
327
|
+
const session = await client.toggleFavorite(session_id);
|
|
328
|
+
const lines = [
|
|
329
|
+
`## Favorite Toggled`,
|
|
330
|
+
'',
|
|
331
|
+
`- **Session ID:** ${session.id}`,
|
|
332
|
+
`- **Title:** ${session.title}`,
|
|
333
|
+
`- **Favorited:** ${session.favorited ? 'Yes' : 'No'}`,
|
|
334
|
+
];
|
|
335
|
+
result = lines.join('\n');
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
case 'bulk_archive': {
|
|
339
|
+
const response = await client.bulkArchiveSessions(session_ids);
|
|
340
|
+
const lines = [
|
|
341
|
+
`## Bulk Archive Complete`,
|
|
342
|
+
'',
|
|
343
|
+
`- **Archived:** ${response.archived_count}`,
|
|
344
|
+
];
|
|
345
|
+
if (response.errors.length > 0) {
|
|
346
|
+
lines.push(`- **Errors:** ${response.errors.length}`);
|
|
347
|
+
response.errors.forEach((err) => {
|
|
348
|
+
lines.push(` - Session ${err.id}: ${err.error}`);
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
result = lines.join('\n');
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
192
354
|
default: {
|
|
193
355
|
// This should never happen due to Zod validation
|
|
194
356
|
const _exhaustiveCheck = action;
|