@defai.digital/mcp-server 13.0.3
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/LICENSE +214 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/bootstrap.d.ts +89 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +161 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/rate-limiter.d.ts +136 -0
- package/dist/middleware/rate-limiter.d.ts.map +1 -0
- package/dist/middleware/rate-limiter.js +262 -0
- package/dist/middleware/rate-limiter.js.map +1 -0
- package/dist/prompts/agent-guide.d.ts +16 -0
- package/dist/prompts/agent-guide.d.ts.map +1 -0
- package/dist/prompts/agent-guide.js +391 -0
- package/dist/prompts/agent-guide.js.map +1 -0
- package/dist/prompts/explain-workflow.d.ts +15 -0
- package/dist/prompts/explain-workflow.d.ts.map +1 -0
- package/dist/prompts/explain-workflow.js +157 -0
- package/dist/prompts/explain-workflow.js.map +1 -0
- package/dist/prompts/index.d.ts +39 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +83 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/review-changes.d.ts +15 -0
- package/dist/prompts/review-changes.d.ts.map +1 -0
- package/dist/prompts/review-changes.js +102 -0
- package/dist/prompts/review-changes.js.map +1 -0
- package/dist/prompts/troubleshoot-session.d.ts +15 -0
- package/dist/prompts/troubleshoot-session.d.ts.map +1 -0
- package/dist/prompts/troubleshoot-session.js +156 -0
- package/dist/prompts/troubleshoot-session.js.map +1 -0
- package/dist/registry-accessor.d.ts +83 -0
- package/dist/registry-accessor.d.ts.map +1 -0
- package/dist/registry-accessor.js +153 -0
- package/dist/registry-accessor.js.map +1 -0
- package/dist/resources/agents.d.ts +40 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +123 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/config.d.ts +57 -0
- package/dist/resources/config.d.ts.map +1 -0
- package/dist/resources/config.js +222 -0
- package/dist/resources/config.js.map +1 -0
- package/dist/resources/index.d.ts +38 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +132 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/policies.d.ts +40 -0
- package/dist/resources/policies.d.ts.map +1 -0
- package/dist/resources/policies.js +122 -0
- package/dist/resources/policies.js.map +1 -0
- package/dist/resources/sessions.d.ts +30 -0
- package/dist/resources/sessions.d.ts.map +1 -0
- package/dist/resources/sessions.js +64 -0
- package/dist/resources/sessions.js.map +1 -0
- package/dist/resources/workflows.d.ts +40 -0
- package/dist/resources/workflows.d.ts.map +1 -0
- package/dist/resources/workflows.js +143 -0
- package/dist/resources/workflows.js.map +1 -0
- package/dist/schema-registry.d.ts +23 -0
- package/dist/schema-registry.d.ts.map +1 -0
- package/dist/schema-registry.js +225 -0
- package/dist/schema-registry.js.map +1 -0
- package/dist/server.d.ts +63 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +393 -0
- package/dist/server.js.map +1 -0
- package/dist/session-accessor.d.ts +23 -0
- package/dist/session-accessor.d.ts.map +1 -0
- package/dist/session-accessor.js +39 -0
- package/dist/session-accessor.js.map +1 -0
- package/dist/shared-registry.d.ts +23 -0
- package/dist/shared-registry.d.ts.map +1 -0
- package/dist/shared-registry.js +235 -0
- package/dist/shared-registry.js.map +1 -0
- package/dist/stdio.d.ts +6 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +152 -0
- package/dist/stdio.js.map +1 -0
- package/dist/tool-namespacing.d.ts +28 -0
- package/dist/tool-namespacing.d.ts.map +1 -0
- package/dist/tool-namespacing.js +80 -0
- package/dist/tool-namespacing.js.map +1 -0
- package/dist/tools/ability.d.ts +55 -0
- package/dist/tools/ability.d.ts.map +1 -0
- package/dist/tools/ability.js +560 -0
- package/dist/tools/ability.js.map +1 -0
- package/dist/tools/agent.d.ts +73 -0
- package/dist/tools/agent.d.ts.map +1 -0
- package/dist/tools/agent.js +895 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/config.d.ts +36 -0
- package/dist/tools/config.d.ts.map +1 -0
- package/dist/tools/config.js +265 -0
- package/dist/tools/config.js.map +1 -0
- package/dist/tools/design.d.ts +42 -0
- package/dist/tools/design.d.ts.map +1 -0
- package/dist/tools/design.js +736 -0
- package/dist/tools/design.js.map +1 -0
- package/dist/tools/discuss.d.ts +40 -0
- package/dist/tools/discuss.d.ts.map +1 -0
- package/dist/tools/discuss.js +331 -0
- package/dist/tools/discuss.js.map +1 -0
- package/dist/tools/file-system.d.ts +63 -0
- package/dist/tools/file-system.d.ts.map +1 -0
- package/dist/tools/file-system.js +513 -0
- package/dist/tools/file-system.js.map +1 -0
- package/dist/tools/guard.d.ts +29 -0
- package/dist/tools/guard.d.ts.map +1 -0
- package/dist/tools/guard.js +311 -0
- package/dist/tools/guard.js.map +1 -0
- package/dist/tools/index.d.ts +35 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +178 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory.d.ts +101 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +704 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/orchestration.d.ts +58 -0
- package/dist/tools/orchestration.d.ts.map +1 -0
- package/dist/tools/orchestration.js +714 -0
- package/dist/tools/orchestration.js.map +1 -0
- package/dist/tools/review.d.ts +40 -0
- package/dist/tools/review.d.ts.map +1 -0
- package/dist/tools/review.js +319 -0
- package/dist/tools/review.js.map +1 -0
- package/dist/tools/scaffold.d.ts +27 -0
- package/dist/tools/scaffold.d.ts.map +1 -0
- package/dist/tools/scaffold.js +495 -0
- package/dist/tools/scaffold.js.map +1 -0
- package/dist/tools/session.d.ts +75 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +749 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/telemetry.d.ts +58 -0
- package/dist/tools/telemetry.d.ts.map +1 -0
- package/dist/tools/telemetry.js +638 -0
- package/dist/tools/telemetry.js.map +1 -0
- package/dist/tools/trace.d.ts +29 -0
- package/dist/tools/trace.d.ts.map +1 -0
- package/dist/tools/trace.js +191 -0
- package/dist/tools/trace.js.map +1 -0
- package/dist/tools/workflow.d.ts +26 -0
- package/dist/tools/workflow.d.ts.map +1 -0
- package/dist/tools/workflow.js +269 -0
- package/dist/tools/workflow.js.map +1 -0
- package/dist/trace-wrapper.d.ts +79 -0
- package/dist/trace-wrapper.d.ts.map +1 -0
- package/dist/trace-wrapper.js +151 -0
- package/dist/trace-wrapper.js.map +1 -0
- package/dist/types.d.ts +185 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/artifact-store.d.ts +49 -0
- package/dist/utils/artifact-store.d.ts.map +1 -0
- package/dist/utils/artifact-store.js +102 -0
- package/dist/utils/artifact-store.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/response.d.ts +139 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +293 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/validation.d.ts +223 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +372 -0
- package/dist/validation.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
import { createSessionStore, createSessionManager, DEFAULT_SESSION_DOMAIN_CONFIG, } from '@defai.digital/session-domain';
|
|
2
|
+
import { LIMIT_SESSIONS } from '@defai.digital/contracts';
|
|
3
|
+
// Create shared store and manager instances
|
|
4
|
+
const store = createSessionStore();
|
|
5
|
+
const manager = createSessionManager(store, DEFAULT_SESSION_DOMAIN_CONFIG);
|
|
6
|
+
/**
|
|
7
|
+
* Session create tool definition
|
|
8
|
+
* INV-MCP-004: Non-idempotent - creates new session each call
|
|
9
|
+
* INV-MCP-002: Side effects - creates session in store
|
|
10
|
+
*/
|
|
11
|
+
export const sessionCreateTool = {
|
|
12
|
+
name: 'session_create',
|
|
13
|
+
description: 'Create a new collaboration session. SIDE EFFECTS: Creates new session in store with unique ID.',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
initiator: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Identifier of the agent creating the session',
|
|
20
|
+
},
|
|
21
|
+
task: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'Description of the session task/objective',
|
|
24
|
+
},
|
|
25
|
+
workspace: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'Optional workspace path for the session',
|
|
28
|
+
},
|
|
29
|
+
metadata: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
description: 'Optional metadata for the session',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: ['initiator', 'task'],
|
|
35
|
+
},
|
|
36
|
+
outputSchema: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
sessionId: { type: 'string', description: 'Unique session identifier' },
|
|
40
|
+
initiator: { type: 'string', description: 'Session initiator' },
|
|
41
|
+
task: { type: 'string', description: 'Session task' },
|
|
42
|
+
status: { type: 'string', description: 'Session status' },
|
|
43
|
+
createdAt: { type: 'string', description: 'Creation timestamp' },
|
|
44
|
+
workspace: { type: 'string', description: 'Workspace path' },
|
|
45
|
+
},
|
|
46
|
+
required: ['sessionId', 'initiator', 'task', 'status', 'createdAt'],
|
|
47
|
+
},
|
|
48
|
+
idempotent: false,
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Session status tool definition
|
|
52
|
+
* INV-MCP-004: Idempotent - read-only operation
|
|
53
|
+
*/
|
|
54
|
+
export const sessionStatusTool = {
|
|
55
|
+
name: 'session_status',
|
|
56
|
+
description: 'Get the current status of a session. Read-only, no side effects.',
|
|
57
|
+
inputSchema: {
|
|
58
|
+
type: 'object',
|
|
59
|
+
properties: {
|
|
60
|
+
sessionId: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'The ID of the session to check',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ['sessionId'],
|
|
66
|
+
},
|
|
67
|
+
outputSchema: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
sessionId: { type: 'string' },
|
|
71
|
+
status: { type: 'string', enum: ['active', 'completed', 'failed'] },
|
|
72
|
+
initiator: { type: 'string' },
|
|
73
|
+
task: { type: 'string' },
|
|
74
|
+
participants: {
|
|
75
|
+
type: 'array',
|
|
76
|
+
items: {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
agentId: { type: 'string' },
|
|
80
|
+
role: { type: 'string' },
|
|
81
|
+
joinedAt: { type: 'string' },
|
|
82
|
+
taskCount: { type: 'number' },
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
createdAt: { type: 'string' },
|
|
87
|
+
updatedAt: { type: 'string' },
|
|
88
|
+
completedAt: { type: 'string' },
|
|
89
|
+
},
|
|
90
|
+
required: ['sessionId', 'status', 'initiator', 'task', 'participants', 'createdAt'],
|
|
91
|
+
},
|
|
92
|
+
idempotent: true,
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Session complete tool definition
|
|
96
|
+
* INV-MCP-004: Idempotent - completing already completed session is safe
|
|
97
|
+
* INV-MCP-002: Side effects - updates session status to completed
|
|
98
|
+
*/
|
|
99
|
+
export const sessionCompleteTool = {
|
|
100
|
+
name: 'session_complete',
|
|
101
|
+
description: 'Complete a session. SIDE EFFECTS: Updates session status to completed. Idempotent for already-completed sessions.',
|
|
102
|
+
inputSchema: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
sessionId: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: 'The ID of the session to complete',
|
|
108
|
+
},
|
|
109
|
+
summary: {
|
|
110
|
+
type: 'string',
|
|
111
|
+
description: 'Optional summary of what was accomplished',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
required: ['sessionId'],
|
|
115
|
+
},
|
|
116
|
+
outputSchema: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
sessionId: { type: 'string' },
|
|
120
|
+
status: { type: 'string' },
|
|
121
|
+
completedAt: { type: 'string' },
|
|
122
|
+
summary: { type: 'string' },
|
|
123
|
+
},
|
|
124
|
+
required: ['sessionId', 'status', 'completedAt'],
|
|
125
|
+
},
|
|
126
|
+
idempotent: true,
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Session list tool definition
|
|
130
|
+
* INV-MCP-004: Idempotent - read-only operation
|
|
131
|
+
*/
|
|
132
|
+
export const sessionListTool = {
|
|
133
|
+
name: 'session_list',
|
|
134
|
+
description: 'List sessions with optional filtering. Read-only, no side effects.',
|
|
135
|
+
inputSchema: {
|
|
136
|
+
type: 'object',
|
|
137
|
+
properties: {
|
|
138
|
+
status: {
|
|
139
|
+
type: 'string',
|
|
140
|
+
description: 'Filter by session status',
|
|
141
|
+
enum: ['active', 'completed', 'failed'],
|
|
142
|
+
},
|
|
143
|
+
initiator: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Filter by initiator',
|
|
146
|
+
},
|
|
147
|
+
limit: {
|
|
148
|
+
type: 'number',
|
|
149
|
+
description: 'Maximum number of sessions to return',
|
|
150
|
+
default: LIMIT_SESSIONS,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
outputSchema: {
|
|
155
|
+
type: 'object',
|
|
156
|
+
properties: {
|
|
157
|
+
sessions: {
|
|
158
|
+
type: 'array',
|
|
159
|
+
items: {
|
|
160
|
+
type: 'object',
|
|
161
|
+
properties: {
|
|
162
|
+
sessionId: { type: 'string' },
|
|
163
|
+
initiator: { type: 'string' },
|
|
164
|
+
task: { type: 'string' },
|
|
165
|
+
status: { type: 'string' },
|
|
166
|
+
participantCount: { type: 'number' },
|
|
167
|
+
createdAt: { type: 'string' },
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
total: { type: 'number' },
|
|
172
|
+
},
|
|
173
|
+
required: ['sessions', 'total'],
|
|
174
|
+
},
|
|
175
|
+
idempotent: true,
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Session join tool definition
|
|
179
|
+
* INV-MCP-004: Idempotent - joining twice returns existing participation
|
|
180
|
+
* INV-MCP-002: Side effects - adds participant to session
|
|
181
|
+
*/
|
|
182
|
+
export const sessionJoinTool = {
|
|
183
|
+
name: 'session_join',
|
|
184
|
+
description: 'Join an existing session as a participant. SIDE EFFECTS: Adds agent to session participants. Idempotent - joining twice returns existing participation.',
|
|
185
|
+
inputSchema: {
|
|
186
|
+
type: 'object',
|
|
187
|
+
properties: {
|
|
188
|
+
sessionId: {
|
|
189
|
+
type: 'string',
|
|
190
|
+
description: 'The ID of the session to join',
|
|
191
|
+
},
|
|
192
|
+
agentId: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
description: 'The ID of the agent joining',
|
|
195
|
+
},
|
|
196
|
+
role: {
|
|
197
|
+
type: 'string',
|
|
198
|
+
description: 'Role in the session',
|
|
199
|
+
enum: ['collaborator', 'delegate'],
|
|
200
|
+
default: 'collaborator',
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
required: ['sessionId', 'agentId'],
|
|
204
|
+
},
|
|
205
|
+
outputSchema: {
|
|
206
|
+
type: 'object',
|
|
207
|
+
properties: {
|
|
208
|
+
sessionId: { type: 'string' },
|
|
209
|
+
agentId: { type: 'string' },
|
|
210
|
+
role: { type: 'string' },
|
|
211
|
+
joinedAt: { type: 'string' },
|
|
212
|
+
participantCount: { type: 'number' },
|
|
213
|
+
},
|
|
214
|
+
required: ['sessionId', 'agentId', 'role', 'joinedAt', 'participantCount'],
|
|
215
|
+
},
|
|
216
|
+
idempotent: true,
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Session leave tool definition
|
|
220
|
+
* INV-MCP-004: Non-idempotent - fails if not a participant
|
|
221
|
+
* INV-MCP-002: Side effects - removes participant from session
|
|
222
|
+
*/
|
|
223
|
+
export const sessionLeaveTool = {
|
|
224
|
+
name: 'session_leave',
|
|
225
|
+
description: 'Leave a session. SIDE EFFECTS: Removes agent from session participants. Fails if not currently a participant.',
|
|
226
|
+
inputSchema: {
|
|
227
|
+
type: 'object',
|
|
228
|
+
properties: {
|
|
229
|
+
sessionId: {
|
|
230
|
+
type: 'string',
|
|
231
|
+
description: 'The ID of the session to leave',
|
|
232
|
+
},
|
|
233
|
+
agentId: {
|
|
234
|
+
type: 'string',
|
|
235
|
+
description: 'The ID of the agent leaving',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
required: ['sessionId', 'agentId'],
|
|
239
|
+
},
|
|
240
|
+
outputSchema: {
|
|
241
|
+
type: 'object',
|
|
242
|
+
properties: {
|
|
243
|
+
sessionId: { type: 'string' },
|
|
244
|
+
agentId: { type: 'string' },
|
|
245
|
+
leftAt: { type: 'string' },
|
|
246
|
+
remainingParticipants: { type: 'number' },
|
|
247
|
+
},
|
|
248
|
+
required: ['sessionId', 'agentId', 'leftAt', 'remainingParticipants'],
|
|
249
|
+
},
|
|
250
|
+
idempotent: false,
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Session fail tool definition
|
|
254
|
+
* INV-MCP-004: Non-idempotent - only active sessions can be failed
|
|
255
|
+
* INV-MCP-002: Side effects - updates session status to failed
|
|
256
|
+
*/
|
|
257
|
+
export const sessionFailTool = {
|
|
258
|
+
name: 'session_fail',
|
|
259
|
+
description: 'Mark a session as failed with error details. SIDE EFFECTS: Updates session status to failed. Only active sessions can be failed.',
|
|
260
|
+
inputSchema: {
|
|
261
|
+
type: 'object',
|
|
262
|
+
properties: {
|
|
263
|
+
sessionId: {
|
|
264
|
+
type: 'string',
|
|
265
|
+
description: 'The ID of the session to mark as failed',
|
|
266
|
+
},
|
|
267
|
+
error: {
|
|
268
|
+
type: 'object',
|
|
269
|
+
description: 'Error details object with code and message properties',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
required: ['sessionId', 'error'],
|
|
273
|
+
},
|
|
274
|
+
outputSchema: {
|
|
275
|
+
type: 'object',
|
|
276
|
+
properties: {
|
|
277
|
+
sessionId: { type: 'string' },
|
|
278
|
+
status: { type: 'string' },
|
|
279
|
+
failedAt: { type: 'string' },
|
|
280
|
+
error: {
|
|
281
|
+
type: 'object',
|
|
282
|
+
properties: {
|
|
283
|
+
code: { type: 'string' },
|
|
284
|
+
message: { type: 'string' },
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
required: ['sessionId', 'status', 'failedAt', 'error'],
|
|
289
|
+
},
|
|
290
|
+
idempotent: false,
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Handler for session_create tool
|
|
294
|
+
*/
|
|
295
|
+
export const handleSessionCreate = async (args) => {
|
|
296
|
+
const initiator = args.initiator;
|
|
297
|
+
const task = args.task;
|
|
298
|
+
const workspace = args.workspace;
|
|
299
|
+
const metadata = args.metadata;
|
|
300
|
+
try {
|
|
301
|
+
const session = await manager.createSession({
|
|
302
|
+
initiator,
|
|
303
|
+
task,
|
|
304
|
+
workspace,
|
|
305
|
+
metadata,
|
|
306
|
+
});
|
|
307
|
+
return {
|
|
308
|
+
content: [
|
|
309
|
+
{
|
|
310
|
+
type: 'text',
|
|
311
|
+
text: JSON.stringify({
|
|
312
|
+
sessionId: session.sessionId,
|
|
313
|
+
initiator: session.initiator,
|
|
314
|
+
task: session.task,
|
|
315
|
+
status: session.status,
|
|
316
|
+
createdAt: session.createdAt,
|
|
317
|
+
workspace: session.workspace,
|
|
318
|
+
}, null, 2),
|
|
319
|
+
},
|
|
320
|
+
],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
325
|
+
return {
|
|
326
|
+
content: [
|
|
327
|
+
{
|
|
328
|
+
type: 'text',
|
|
329
|
+
text: JSON.stringify({
|
|
330
|
+
error: 'SESSION_CREATE_FAILED',
|
|
331
|
+
message,
|
|
332
|
+
}),
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
isError: true,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
/**
|
|
340
|
+
* Handler for session_status tool
|
|
341
|
+
*/
|
|
342
|
+
export const handleSessionStatus = async (args) => {
|
|
343
|
+
const sessionId = args.sessionId;
|
|
344
|
+
try {
|
|
345
|
+
const session = await manager.getSession(sessionId);
|
|
346
|
+
if (session === undefined) {
|
|
347
|
+
return {
|
|
348
|
+
content: [
|
|
349
|
+
{
|
|
350
|
+
type: 'text',
|
|
351
|
+
text: JSON.stringify({
|
|
352
|
+
error: 'SESSION_NOT_FOUND',
|
|
353
|
+
message: `Session "${sessionId}" not found`,
|
|
354
|
+
}),
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
isError: true,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
// Build participant summaries
|
|
361
|
+
const participants = session.participants.map((p) => ({
|
|
362
|
+
agentId: p.agentId,
|
|
363
|
+
role: p.role,
|
|
364
|
+
joinedAt: p.joinedAt,
|
|
365
|
+
taskCount: p.tasks.length,
|
|
366
|
+
}));
|
|
367
|
+
return {
|
|
368
|
+
content: [
|
|
369
|
+
{
|
|
370
|
+
type: 'text',
|
|
371
|
+
text: JSON.stringify({
|
|
372
|
+
sessionId: session.sessionId,
|
|
373
|
+
status: session.status,
|
|
374
|
+
initiator: session.initiator,
|
|
375
|
+
task: session.task,
|
|
376
|
+
participants,
|
|
377
|
+
createdAt: session.createdAt,
|
|
378
|
+
updatedAt: session.updatedAt,
|
|
379
|
+
completedAt: session.completedAt,
|
|
380
|
+
}, null, 2),
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
387
|
+
return {
|
|
388
|
+
content: [
|
|
389
|
+
{
|
|
390
|
+
type: 'text',
|
|
391
|
+
text: JSON.stringify({
|
|
392
|
+
error: 'SESSION_STATUS_FAILED',
|
|
393
|
+
message,
|
|
394
|
+
}),
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
isError: true,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* Handler for session_complete tool
|
|
403
|
+
*/
|
|
404
|
+
export const handleSessionComplete = async (args) => {
|
|
405
|
+
const sessionId = args.sessionId;
|
|
406
|
+
const summary = args.summary;
|
|
407
|
+
try {
|
|
408
|
+
const session = await manager.completeSession(sessionId, summary);
|
|
409
|
+
return {
|
|
410
|
+
content: [
|
|
411
|
+
{
|
|
412
|
+
type: 'text',
|
|
413
|
+
text: JSON.stringify({
|
|
414
|
+
sessionId: session.sessionId,
|
|
415
|
+
status: session.status,
|
|
416
|
+
completedAt: session.completedAt,
|
|
417
|
+
summary,
|
|
418
|
+
}, null, 2),
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
425
|
+
const code = error.code ?? 'SESSION_COMPLETE_FAILED';
|
|
426
|
+
return {
|
|
427
|
+
content: [
|
|
428
|
+
{
|
|
429
|
+
type: 'text',
|
|
430
|
+
text: JSON.stringify({
|
|
431
|
+
error: code,
|
|
432
|
+
message,
|
|
433
|
+
}),
|
|
434
|
+
},
|
|
435
|
+
],
|
|
436
|
+
isError: true,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
/**
|
|
441
|
+
* Handler for session_list tool
|
|
442
|
+
*/
|
|
443
|
+
export const handleSessionList = async (args) => {
|
|
444
|
+
const status = args.status;
|
|
445
|
+
const initiator = args.initiator;
|
|
446
|
+
const limit = args.limit ?? 20;
|
|
447
|
+
try {
|
|
448
|
+
// Build filter only with defined properties
|
|
449
|
+
const filter = {};
|
|
450
|
+
if (status !== undefined) {
|
|
451
|
+
filter.status = status;
|
|
452
|
+
}
|
|
453
|
+
if (initiator !== undefined) {
|
|
454
|
+
filter.initiator = initiator;
|
|
455
|
+
}
|
|
456
|
+
const sessions = await manager.listSessions(Object.keys(filter).length > 0 ? filter : undefined);
|
|
457
|
+
const sessionSummaries = sessions.slice(0, limit).map((s) => ({
|
|
458
|
+
sessionId: s.sessionId,
|
|
459
|
+
initiator: s.initiator,
|
|
460
|
+
task: s.task,
|
|
461
|
+
status: s.status,
|
|
462
|
+
participantCount: s.participants.length,
|
|
463
|
+
createdAt: s.createdAt,
|
|
464
|
+
}));
|
|
465
|
+
return {
|
|
466
|
+
content: [
|
|
467
|
+
{
|
|
468
|
+
type: 'text',
|
|
469
|
+
text: JSON.stringify({
|
|
470
|
+
sessions: sessionSummaries,
|
|
471
|
+
total: sessions.length,
|
|
472
|
+
}, null, 2),
|
|
473
|
+
},
|
|
474
|
+
],
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
479
|
+
return {
|
|
480
|
+
content: [
|
|
481
|
+
{
|
|
482
|
+
type: 'text',
|
|
483
|
+
text: JSON.stringify({
|
|
484
|
+
error: 'SESSION_LIST_FAILED',
|
|
485
|
+
message,
|
|
486
|
+
}),
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
isError: true,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
/**
|
|
494
|
+
* Handler for session_join tool
|
|
495
|
+
* INV-MCP-SES-001: Cannot join completed/failed session
|
|
496
|
+
* INV-MCP-SES-002: Joining twice returns existing participation (idempotent)
|
|
497
|
+
* INV-MCP-SES-003: Max participants enforced (default: 10)
|
|
498
|
+
*/
|
|
499
|
+
export const handleSessionJoin = async (args) => {
|
|
500
|
+
const sessionId = args.sessionId;
|
|
501
|
+
const agentId = args.agentId;
|
|
502
|
+
const role = args.role ?? 'collaborator';
|
|
503
|
+
try {
|
|
504
|
+
const session = await manager.getSession(sessionId);
|
|
505
|
+
if (session === undefined) {
|
|
506
|
+
return {
|
|
507
|
+
content: [
|
|
508
|
+
{
|
|
509
|
+
type: 'text',
|
|
510
|
+
text: JSON.stringify({
|
|
511
|
+
error: 'SESSION_NOT_FOUND',
|
|
512
|
+
message: `Session "${sessionId}" not found`,
|
|
513
|
+
}),
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
isError: true,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
// INV-MCP-SES-001: Cannot join completed/failed session
|
|
520
|
+
if (session.status !== 'active') {
|
|
521
|
+
return {
|
|
522
|
+
content: [
|
|
523
|
+
{
|
|
524
|
+
type: 'text',
|
|
525
|
+
text: JSON.stringify({
|
|
526
|
+
error: 'SESSION_INVALID_TRANSITION',
|
|
527
|
+
message: `Cannot join session with status "${session.status}"`,
|
|
528
|
+
}),
|
|
529
|
+
},
|
|
530
|
+
],
|
|
531
|
+
isError: true,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
// INV-MCP-SES-003: Max participants check
|
|
535
|
+
const MAX_PARTICIPANTS = 10;
|
|
536
|
+
if (session.participants.length >= MAX_PARTICIPANTS) {
|
|
537
|
+
// Check if already a participant (INV-MCP-SES-002)
|
|
538
|
+
const existing = session.participants.find((p) => p.agentId === agentId);
|
|
539
|
+
if (existing === undefined) {
|
|
540
|
+
return {
|
|
541
|
+
content: [
|
|
542
|
+
{
|
|
543
|
+
type: 'text',
|
|
544
|
+
text: JSON.stringify({
|
|
545
|
+
error: 'SESSION_MAX_PARTICIPANTS',
|
|
546
|
+
message: `Session has reached maximum participants (${MAX_PARTICIPANTS})`,
|
|
547
|
+
}),
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
isError: true,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// Join the session (joinSession handles idempotency - INV-MCP-SES-002)
|
|
555
|
+
const updatedSession = await manager.joinSession({ sessionId, agentId, role });
|
|
556
|
+
const participant = updatedSession.participants.find((p) => p.agentId === agentId);
|
|
557
|
+
return {
|
|
558
|
+
content: [
|
|
559
|
+
{
|
|
560
|
+
type: 'text',
|
|
561
|
+
text: JSON.stringify({
|
|
562
|
+
sessionId: updatedSession.sessionId,
|
|
563
|
+
agentId,
|
|
564
|
+
role: participant?.role ?? role,
|
|
565
|
+
joinedAt: participant?.joinedAt ?? new Date().toISOString(),
|
|
566
|
+
participantCount: updatedSession.participants.length,
|
|
567
|
+
}, null, 2),
|
|
568
|
+
},
|
|
569
|
+
],
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
catch (error) {
|
|
573
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
574
|
+
const code = error.code ?? 'SESSION_JOIN_FAILED';
|
|
575
|
+
return {
|
|
576
|
+
content: [
|
|
577
|
+
{
|
|
578
|
+
type: 'text',
|
|
579
|
+
text: JSON.stringify({
|
|
580
|
+
error: code,
|
|
581
|
+
message,
|
|
582
|
+
}),
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
isError: true,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
/**
|
|
590
|
+
* Handler for session_leave tool
|
|
591
|
+
* INV-MCP-SES-004: Cannot leave if not a participant
|
|
592
|
+
* INV-MCP-SES-005: Initiator cannot leave active session
|
|
593
|
+
*/
|
|
594
|
+
export const handleSessionLeave = async (args) => {
|
|
595
|
+
const sessionId = args.sessionId;
|
|
596
|
+
const agentId = args.agentId;
|
|
597
|
+
try {
|
|
598
|
+
const session = await manager.getSession(sessionId);
|
|
599
|
+
if (session === undefined) {
|
|
600
|
+
return {
|
|
601
|
+
content: [
|
|
602
|
+
{
|
|
603
|
+
type: 'text',
|
|
604
|
+
text: JSON.stringify({
|
|
605
|
+
error: 'SESSION_NOT_FOUND',
|
|
606
|
+
message: `Session "${sessionId}" not found`,
|
|
607
|
+
}),
|
|
608
|
+
},
|
|
609
|
+
],
|
|
610
|
+
isError: true,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
// INV-MCP-SES-004: Cannot leave if not a participant
|
|
614
|
+
const isParticipant = session.participants.some((p) => p.agentId === agentId);
|
|
615
|
+
if (!isParticipant) {
|
|
616
|
+
return {
|
|
617
|
+
content: [
|
|
618
|
+
{
|
|
619
|
+
type: 'text',
|
|
620
|
+
text: JSON.stringify({
|
|
621
|
+
error: 'SESSION_AGENT_NOT_PARTICIPANT',
|
|
622
|
+
message: `Agent "${agentId}" is not a participant in this session`,
|
|
623
|
+
}),
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
isError: true,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
// INV-MCP-SES-005: Initiator cannot leave active session
|
|
630
|
+
if (session.initiator === agentId && session.status === 'active') {
|
|
631
|
+
return {
|
|
632
|
+
content: [
|
|
633
|
+
{
|
|
634
|
+
type: 'text',
|
|
635
|
+
text: JSON.stringify({
|
|
636
|
+
error: 'SESSION_INITIATOR_CANNOT_LEAVE',
|
|
637
|
+
message: 'Session initiator cannot leave an active session. Complete or fail the session first.',
|
|
638
|
+
}),
|
|
639
|
+
},
|
|
640
|
+
],
|
|
641
|
+
isError: true,
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
// Leave the session
|
|
645
|
+
const updatedSession = await manager.leaveSession(sessionId, agentId);
|
|
646
|
+
return {
|
|
647
|
+
content: [
|
|
648
|
+
{
|
|
649
|
+
type: 'text',
|
|
650
|
+
text: JSON.stringify({
|
|
651
|
+
sessionId: updatedSession.sessionId,
|
|
652
|
+
agentId,
|
|
653
|
+
leftAt: new Date().toISOString(),
|
|
654
|
+
remainingParticipants: updatedSession.participants.length,
|
|
655
|
+
}, null, 2),
|
|
656
|
+
},
|
|
657
|
+
],
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
662
|
+
const code = error.code ?? 'SESSION_LEAVE_FAILED';
|
|
663
|
+
return {
|
|
664
|
+
content: [
|
|
665
|
+
{
|
|
666
|
+
type: 'text',
|
|
667
|
+
text: JSON.stringify({
|
|
668
|
+
error: code,
|
|
669
|
+
message,
|
|
670
|
+
}),
|
|
671
|
+
},
|
|
672
|
+
],
|
|
673
|
+
isError: true,
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
/**
|
|
678
|
+
* Handler for session_fail tool
|
|
679
|
+
*/
|
|
680
|
+
export const handleSessionFail = async (args) => {
|
|
681
|
+
const sessionId = args.sessionId;
|
|
682
|
+
const error = args.error;
|
|
683
|
+
try {
|
|
684
|
+
const session = await manager.getSession(sessionId);
|
|
685
|
+
if (session === undefined) {
|
|
686
|
+
return {
|
|
687
|
+
content: [
|
|
688
|
+
{
|
|
689
|
+
type: 'text',
|
|
690
|
+
text: JSON.stringify({
|
|
691
|
+
error: 'SESSION_NOT_FOUND',
|
|
692
|
+
message: `Session "${sessionId}" not found`,
|
|
693
|
+
}),
|
|
694
|
+
},
|
|
695
|
+
],
|
|
696
|
+
isError: true,
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
if (session.status !== 'active') {
|
|
700
|
+
return {
|
|
701
|
+
content: [
|
|
702
|
+
{
|
|
703
|
+
type: 'text',
|
|
704
|
+
text: JSON.stringify({
|
|
705
|
+
error: 'SESSION_INVALID_TRANSITION',
|
|
706
|
+
message: `Cannot fail session with status "${session.status}"`,
|
|
707
|
+
}),
|
|
708
|
+
},
|
|
709
|
+
],
|
|
710
|
+
isError: true,
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
// Fail the session
|
|
714
|
+
const updatedSession = await manager.failSession(sessionId, error);
|
|
715
|
+
return {
|
|
716
|
+
content: [
|
|
717
|
+
{
|
|
718
|
+
type: 'text',
|
|
719
|
+
text: JSON.stringify({
|
|
720
|
+
sessionId: updatedSession.sessionId,
|
|
721
|
+
status: 'failed',
|
|
722
|
+
failedAt: updatedSession.completedAt ?? new Date().toISOString(),
|
|
723
|
+
error: {
|
|
724
|
+
code: error.code,
|
|
725
|
+
message: error.message,
|
|
726
|
+
},
|
|
727
|
+
}, null, 2),
|
|
728
|
+
},
|
|
729
|
+
],
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
catch (err) {
|
|
733
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
734
|
+
const code = err.code ?? 'SESSION_FAIL_FAILED';
|
|
735
|
+
return {
|
|
736
|
+
content: [
|
|
737
|
+
{
|
|
738
|
+
type: 'text',
|
|
739
|
+
text: JSON.stringify({
|
|
740
|
+
error: code,
|
|
741
|
+
message,
|
|
742
|
+
}),
|
|
743
|
+
},
|
|
744
|
+
],
|
|
745
|
+
isError: true,
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
//# sourceMappingURL=session.js.map
|