@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,895 @@
|
|
|
1
|
+
import { LIMIT_AGENTS } from '@defai.digital/contracts';
|
|
2
|
+
import { getAvailableTemplates, createWorkflowFromTemplate, isValidTemplateName, createAgentSelectionService, } from '@defai.digital/agent-domain';
|
|
3
|
+
// Import from registry-accessor to avoid circular dependencies
|
|
4
|
+
import { getSharedRegistry, getSharedExecutor, } from '../registry-accessor.js';
|
|
5
|
+
/**
|
|
6
|
+
* Agent list tool definition
|
|
7
|
+
* INV-MCP-004: Idempotent - read-only operation
|
|
8
|
+
*/
|
|
9
|
+
export const agentListTool = {
|
|
10
|
+
name: 'agent_list',
|
|
11
|
+
description: 'List available agents with optional filtering. Read-only, no side effects.',
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
team: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'Filter by team name',
|
|
18
|
+
},
|
|
19
|
+
enabled: {
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
description: 'Filter by enabled status',
|
|
22
|
+
},
|
|
23
|
+
limit: {
|
|
24
|
+
type: 'number',
|
|
25
|
+
description: 'Maximum number of agents to return',
|
|
26
|
+
default: LIMIT_AGENTS,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
outputSchema: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
agents: {
|
|
34
|
+
type: 'array',
|
|
35
|
+
description: 'List of agent summaries',
|
|
36
|
+
items: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
agentId: { type: 'string' },
|
|
40
|
+
displayName: { type: 'string' },
|
|
41
|
+
description: { type: 'string' },
|
|
42
|
+
team: { type: 'string' },
|
|
43
|
+
enabled: { type: 'boolean' },
|
|
44
|
+
capabilities: { type: 'array', items: { type: 'string' } },
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
total: { type: 'number', description: 'Total number of agents' },
|
|
49
|
+
},
|
|
50
|
+
required: ['agents', 'total'],
|
|
51
|
+
},
|
|
52
|
+
idempotent: true,
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Agent run tool definition
|
|
56
|
+
* INV-MCP-004: Non-idempotent - creates new execution each call
|
|
57
|
+
* INV-MCP-002: Side effects - executes agent workflow, may modify state
|
|
58
|
+
*/
|
|
59
|
+
export const agentRunTool = {
|
|
60
|
+
name: 'agent_run',
|
|
61
|
+
description: 'Execute an agent with the given input. SIDE EFFECTS: Creates new agent execution, may modify session state and emit trace events.',
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
agentId: {
|
|
66
|
+
type: 'string',
|
|
67
|
+
description: 'The ID of the agent to run',
|
|
68
|
+
},
|
|
69
|
+
input: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
description: 'Input data for the agent',
|
|
72
|
+
},
|
|
73
|
+
sessionId: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'Optional session ID to associate with the run',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
required: ['agentId'],
|
|
79
|
+
},
|
|
80
|
+
outputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
success: { type: 'boolean', description: 'Whether execution succeeded' },
|
|
84
|
+
agentId: { type: 'string', description: 'Agent that was executed' },
|
|
85
|
+
sessionId: { type: 'string', description: 'Session ID (if provided)' },
|
|
86
|
+
output: { type: 'object', description: 'Agent output data' },
|
|
87
|
+
stepResults: {
|
|
88
|
+
type: 'array',
|
|
89
|
+
description: 'Results from each step',
|
|
90
|
+
items: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
stepId: { type: 'string' },
|
|
94
|
+
success: { type: 'boolean' },
|
|
95
|
+
durationMs: { type: 'number' },
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
totalDurationMs: { type: 'number', description: 'Total execution time' },
|
|
100
|
+
error: { type: 'object', description: 'Error details if failed' },
|
|
101
|
+
},
|
|
102
|
+
required: ['success', 'agentId', 'totalDurationMs'],
|
|
103
|
+
},
|
|
104
|
+
idempotent: false,
|
|
105
|
+
retryableErrors: ['AGENT_EXECUTION_FAILED'],
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Agent get tool definition
|
|
109
|
+
* INV-MCP-004: Idempotent - read-only operation
|
|
110
|
+
*/
|
|
111
|
+
export const agentGetTool = {
|
|
112
|
+
name: 'agent_get',
|
|
113
|
+
description: 'Get detailed information about a specific agent. Read-only, no side effects.',
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
agentId: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
description: 'The ID of the agent to retrieve',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
required: ['agentId'],
|
|
123
|
+
},
|
|
124
|
+
outputSchema: {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
agentId: { type: 'string' },
|
|
128
|
+
displayName: { type: 'string' },
|
|
129
|
+
version: { type: 'string' },
|
|
130
|
+
description: { type: 'string' },
|
|
131
|
+
role: { type: 'string' },
|
|
132
|
+
expertise: { type: 'string' },
|
|
133
|
+
capabilities: { type: 'array', items: { type: 'string' } },
|
|
134
|
+
team: { type: 'string' },
|
|
135
|
+
tags: { type: 'array', items: { type: 'string' } },
|
|
136
|
+
enabled: { type: 'boolean' },
|
|
137
|
+
workflow: {
|
|
138
|
+
type: 'array',
|
|
139
|
+
items: {
|
|
140
|
+
type: 'object',
|
|
141
|
+
properties: {
|
|
142
|
+
stepId: { type: 'string' },
|
|
143
|
+
name: { type: 'string' },
|
|
144
|
+
type: { type: 'string' },
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
orchestration: {
|
|
149
|
+
type: 'object',
|
|
150
|
+
properties: {
|
|
151
|
+
maxDelegationDepth: { type: 'number' },
|
|
152
|
+
canReadWorkspaces: { type: 'boolean' },
|
|
153
|
+
canWriteToShared: { type: 'boolean' },
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
required: ['agentId', 'description', 'enabled'],
|
|
158
|
+
},
|
|
159
|
+
idempotent: true,
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Agent register tool definition
|
|
163
|
+
* INV-MCP-004: Non-idempotent - creates new agent profile
|
|
164
|
+
* INV-MCP-002: Side effects - modifies agent registry
|
|
165
|
+
*/
|
|
166
|
+
export const agentRegisterTool = {
|
|
167
|
+
name: 'agent_register',
|
|
168
|
+
description: 'Register a new agent profile. SIDE EFFECTS: Creates new agent in registry. Fails if agent already exists.',
|
|
169
|
+
inputSchema: {
|
|
170
|
+
type: 'object',
|
|
171
|
+
properties: {
|
|
172
|
+
agentId: {
|
|
173
|
+
type: 'string',
|
|
174
|
+
description: 'Unique identifier for the agent (must start with letter, alphanumeric/dash/underscore only)',
|
|
175
|
+
},
|
|
176
|
+
description: {
|
|
177
|
+
type: 'string',
|
|
178
|
+
description: 'Description of the agent capabilities',
|
|
179
|
+
},
|
|
180
|
+
displayName: {
|
|
181
|
+
type: 'string',
|
|
182
|
+
description: 'Human-readable display name',
|
|
183
|
+
},
|
|
184
|
+
systemPrompt: {
|
|
185
|
+
type: 'string',
|
|
186
|
+
description: 'System prompt for the agent (instructions for how to behave)',
|
|
187
|
+
},
|
|
188
|
+
team: {
|
|
189
|
+
type: 'string',
|
|
190
|
+
description: 'Team the agent belongs to',
|
|
191
|
+
},
|
|
192
|
+
capabilities: {
|
|
193
|
+
type: 'array',
|
|
194
|
+
items: { type: 'string' },
|
|
195
|
+
description: 'List of agent capabilities',
|
|
196
|
+
},
|
|
197
|
+
tags: {
|
|
198
|
+
type: 'array',
|
|
199
|
+
items: { type: 'string' },
|
|
200
|
+
description: 'Tags for categorization',
|
|
201
|
+
},
|
|
202
|
+
workflowTemplate: {
|
|
203
|
+
type: 'string',
|
|
204
|
+
enum: ['prompt-response', 'research', 'code-review', 'multi-step', 'delegate-chain', 'agent-selection'],
|
|
205
|
+
description: 'Use a predefined workflow template instead of custom workflow steps',
|
|
206
|
+
},
|
|
207
|
+
workflow: {
|
|
208
|
+
type: 'array',
|
|
209
|
+
items: {
|
|
210
|
+
type: 'object',
|
|
211
|
+
properties: {
|
|
212
|
+
stepId: { type: 'string', description: 'Unique step identifier' },
|
|
213
|
+
name: { type: 'string', description: 'Step name' },
|
|
214
|
+
type: {
|
|
215
|
+
type: 'string',
|
|
216
|
+
enum: ['prompt', 'tool', 'conditional', 'loop', 'parallel', 'delegate'],
|
|
217
|
+
description: 'Step type'
|
|
218
|
+
},
|
|
219
|
+
config: { type: 'object', description: 'Step configuration' },
|
|
220
|
+
},
|
|
221
|
+
required: ['stepId', 'name', 'type'],
|
|
222
|
+
},
|
|
223
|
+
description: 'Workflow steps to execute when agent runs (ignored if workflowTemplate is provided)',
|
|
224
|
+
},
|
|
225
|
+
enabled: {
|
|
226
|
+
type: 'boolean',
|
|
227
|
+
description: 'Whether the agent is enabled',
|
|
228
|
+
default: true,
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
required: ['agentId', 'description'],
|
|
232
|
+
},
|
|
233
|
+
outputSchema: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
properties: {
|
|
236
|
+
registered: { type: 'boolean', description: 'Whether registration succeeded' },
|
|
237
|
+
agentId: { type: 'string', description: 'Registered agent ID' },
|
|
238
|
+
message: { type: 'string', description: 'Result message' },
|
|
239
|
+
createdAt: { type: 'string', description: 'Creation timestamp' },
|
|
240
|
+
},
|
|
241
|
+
required: ['registered', 'agentId', 'message'],
|
|
242
|
+
},
|
|
243
|
+
idempotent: false,
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Agent remove tool definition
|
|
247
|
+
* INV-MCP-004: Idempotent - removing non-existent agent returns removed=false
|
|
248
|
+
* INV-MCP-002: Side effects - deletes agent from registry
|
|
249
|
+
*/
|
|
250
|
+
export const agentRemoveTool = {
|
|
251
|
+
name: 'agent_remove',
|
|
252
|
+
description: 'Remove an agent from the registry. SIDE EFFECTS: Deletes agent profile. Idempotent - removing non-existent agent returns removed=false.',
|
|
253
|
+
inputSchema: {
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: {
|
|
256
|
+
agentId: {
|
|
257
|
+
type: 'string',
|
|
258
|
+
description: 'The ID of the agent to remove',
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
required: ['agentId'],
|
|
262
|
+
},
|
|
263
|
+
outputSchema: {
|
|
264
|
+
type: 'object',
|
|
265
|
+
properties: {
|
|
266
|
+
removed: { type: 'boolean', description: 'Whether agent was removed' },
|
|
267
|
+
agentId: { type: 'string', description: 'Agent ID' },
|
|
268
|
+
message: { type: 'string', description: 'Result message' },
|
|
269
|
+
},
|
|
270
|
+
required: ['removed', 'agentId', 'message'],
|
|
271
|
+
},
|
|
272
|
+
idempotent: true,
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* Handler for agent_list tool
|
|
276
|
+
*/
|
|
277
|
+
export const handleAgentList = async (args) => {
|
|
278
|
+
const team = args.team;
|
|
279
|
+
const enabled = args.enabled;
|
|
280
|
+
const limit = args.limit ?? 50;
|
|
281
|
+
try {
|
|
282
|
+
// Build filter only with defined properties
|
|
283
|
+
const filter = {};
|
|
284
|
+
if (team !== undefined) {
|
|
285
|
+
filter.team = team;
|
|
286
|
+
}
|
|
287
|
+
if (enabled !== undefined) {
|
|
288
|
+
filter.enabled = enabled;
|
|
289
|
+
}
|
|
290
|
+
const registry = await getSharedRegistry();
|
|
291
|
+
const agents = await registry.list(Object.keys(filter).length > 0 ? filter : undefined);
|
|
292
|
+
const agentSummaries = agents.slice(0, limit).map((a) => ({
|
|
293
|
+
agentId: a.agentId,
|
|
294
|
+
displayName: a.displayName,
|
|
295
|
+
description: a.description,
|
|
296
|
+
team: a.team,
|
|
297
|
+
enabled: a.enabled,
|
|
298
|
+
capabilities: a.capabilities,
|
|
299
|
+
}));
|
|
300
|
+
return {
|
|
301
|
+
content: [
|
|
302
|
+
{
|
|
303
|
+
type: 'text',
|
|
304
|
+
text: JSON.stringify({
|
|
305
|
+
agents: agentSummaries,
|
|
306
|
+
total: agents.length,
|
|
307
|
+
}, null, 2),
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
314
|
+
return {
|
|
315
|
+
content: [
|
|
316
|
+
{
|
|
317
|
+
type: 'text',
|
|
318
|
+
text: JSON.stringify({
|
|
319
|
+
error: 'AGENT_LIST_FAILED',
|
|
320
|
+
message,
|
|
321
|
+
}),
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
isError: true,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Handler for agent_run tool
|
|
330
|
+
*/
|
|
331
|
+
export const handleAgentRun = async (args) => {
|
|
332
|
+
const agentId = args.agentId;
|
|
333
|
+
const input = args.input ?? {};
|
|
334
|
+
const sessionId = args.sessionId;
|
|
335
|
+
const startTime = Date.now();
|
|
336
|
+
try {
|
|
337
|
+
// Check if agent exists
|
|
338
|
+
const registry = await getSharedRegistry();
|
|
339
|
+
const agent = await registry.get(agentId);
|
|
340
|
+
if (agent === undefined) {
|
|
341
|
+
return {
|
|
342
|
+
content: [
|
|
343
|
+
{
|
|
344
|
+
type: 'text',
|
|
345
|
+
text: JSON.stringify({
|
|
346
|
+
success: false,
|
|
347
|
+
agentId,
|
|
348
|
+
error: {
|
|
349
|
+
code: 'AGENT_NOT_FOUND',
|
|
350
|
+
message: `Agent "${agentId}" not found`,
|
|
351
|
+
},
|
|
352
|
+
totalDurationMs: Date.now() - startTime,
|
|
353
|
+
}),
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
isError: true,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
// Execute agent - note: execute takes (agentId, input, options)
|
|
360
|
+
const executor = await getSharedExecutor();
|
|
361
|
+
const result = await executor.execute(agentId, input, {
|
|
362
|
+
sessionId,
|
|
363
|
+
});
|
|
364
|
+
return {
|
|
365
|
+
content: [
|
|
366
|
+
{
|
|
367
|
+
type: 'text',
|
|
368
|
+
text: JSON.stringify({
|
|
369
|
+
success: result.success,
|
|
370
|
+
agentId: result.agentId,
|
|
371
|
+
sessionId,
|
|
372
|
+
output: result.output,
|
|
373
|
+
stepResults: result.stepResults?.map((s) => ({
|
|
374
|
+
stepId: s.stepId,
|
|
375
|
+
success: s.success,
|
|
376
|
+
durationMs: s.durationMs,
|
|
377
|
+
})),
|
|
378
|
+
totalDurationMs: result.totalDurationMs,
|
|
379
|
+
error: result.error,
|
|
380
|
+
}, null, 2),
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
isError: !result.success,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
388
|
+
return {
|
|
389
|
+
content: [
|
|
390
|
+
{
|
|
391
|
+
type: 'text',
|
|
392
|
+
text: JSON.stringify({
|
|
393
|
+
success: false,
|
|
394
|
+
agentId,
|
|
395
|
+
error: {
|
|
396
|
+
code: 'AGENT_EXECUTION_FAILED',
|
|
397
|
+
message,
|
|
398
|
+
},
|
|
399
|
+
totalDurationMs: Date.now() - startTime,
|
|
400
|
+
}),
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
isError: true,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
/**
|
|
408
|
+
* Handler for agent_get tool
|
|
409
|
+
*/
|
|
410
|
+
export const handleAgentGet = async (args) => {
|
|
411
|
+
const agentId = args.agentId;
|
|
412
|
+
try {
|
|
413
|
+
const registry = await getSharedRegistry();
|
|
414
|
+
const agent = await registry.get(agentId);
|
|
415
|
+
if (agent === undefined) {
|
|
416
|
+
return {
|
|
417
|
+
content: [
|
|
418
|
+
{
|
|
419
|
+
type: 'text',
|
|
420
|
+
text: JSON.stringify({
|
|
421
|
+
error: 'AGENT_NOT_FOUND',
|
|
422
|
+
message: `Agent "${agentId}" not found`,
|
|
423
|
+
}),
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
isError: true,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
content: [
|
|
431
|
+
{
|
|
432
|
+
type: 'text',
|
|
433
|
+
text: JSON.stringify({
|
|
434
|
+
agentId: agent.agentId,
|
|
435
|
+
displayName: agent.displayName,
|
|
436
|
+
version: agent.version,
|
|
437
|
+
description: agent.description,
|
|
438
|
+
role: agent.role,
|
|
439
|
+
expertise: agent.expertise,
|
|
440
|
+
capabilities: agent.capabilities,
|
|
441
|
+
team: agent.team,
|
|
442
|
+
tags: agent.tags,
|
|
443
|
+
enabled: agent.enabled,
|
|
444
|
+
workflow: agent.workflow?.map((s) => ({
|
|
445
|
+
stepId: s.stepId,
|
|
446
|
+
name: s.name,
|
|
447
|
+
type: s.type,
|
|
448
|
+
})),
|
|
449
|
+
orchestration: agent.orchestration
|
|
450
|
+
? {
|
|
451
|
+
maxDelegationDepth: agent.orchestration.maxDelegationDepth,
|
|
452
|
+
canReadWorkspaces: agent.orchestration.canReadWorkspaces,
|
|
453
|
+
canWriteToShared: agent.orchestration.canWriteToShared,
|
|
454
|
+
}
|
|
455
|
+
: undefined,
|
|
456
|
+
}, null, 2),
|
|
457
|
+
},
|
|
458
|
+
],
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
catch (error) {
|
|
462
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
463
|
+
return {
|
|
464
|
+
content: [
|
|
465
|
+
{
|
|
466
|
+
type: 'text',
|
|
467
|
+
text: JSON.stringify({
|
|
468
|
+
error: 'AGENT_GET_FAILED',
|
|
469
|
+
message,
|
|
470
|
+
}),
|
|
471
|
+
},
|
|
472
|
+
],
|
|
473
|
+
isError: true,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
/**
|
|
478
|
+
* Handler for agent_register tool
|
|
479
|
+
*/
|
|
480
|
+
export const handleAgentRegister = async (args) => {
|
|
481
|
+
const agentId = args.agentId;
|
|
482
|
+
const description = args.description;
|
|
483
|
+
const displayName = args.displayName;
|
|
484
|
+
const systemPrompt = args.systemPrompt;
|
|
485
|
+
const team = args.team;
|
|
486
|
+
const capabilities = args.capabilities;
|
|
487
|
+
const tags = args.tags;
|
|
488
|
+
const workflowTemplate = args.workflowTemplate;
|
|
489
|
+
const workflow = args.workflow;
|
|
490
|
+
const enabled = args.enabled ?? true;
|
|
491
|
+
try {
|
|
492
|
+
const registry = await getSharedRegistry();
|
|
493
|
+
// Check if agent already exists
|
|
494
|
+
const existing = await registry.get(agentId);
|
|
495
|
+
if (existing !== undefined) {
|
|
496
|
+
return {
|
|
497
|
+
content: [
|
|
498
|
+
{
|
|
499
|
+
type: 'text',
|
|
500
|
+
text: JSON.stringify({
|
|
501
|
+
error: 'AGENT_ALREADY_EXISTS',
|
|
502
|
+
message: `Agent "${agentId}" already exists`,
|
|
503
|
+
}),
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
isError: true,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
// Validate agentId format
|
|
510
|
+
const agentIdPattern = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
|
511
|
+
if (!agentIdPattern.test(agentId)) {
|
|
512
|
+
return {
|
|
513
|
+
content: [
|
|
514
|
+
{
|
|
515
|
+
type: 'text',
|
|
516
|
+
text: JSON.stringify({
|
|
517
|
+
error: 'INVALID_AGENT_ID',
|
|
518
|
+
message: 'Agent ID must start with letter and contain only alphanumeric, dash, underscore',
|
|
519
|
+
}),
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
isError: true,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
// Resolve workflow: template takes precedence over custom workflow
|
|
526
|
+
let resolvedWorkflow;
|
|
527
|
+
if (workflowTemplate !== undefined) {
|
|
528
|
+
// Validate template name
|
|
529
|
+
if (!isValidTemplateName(workflowTemplate)) {
|
|
530
|
+
const availableTemplates = getAvailableTemplates();
|
|
531
|
+
return {
|
|
532
|
+
content: [
|
|
533
|
+
{
|
|
534
|
+
type: 'text',
|
|
535
|
+
text: JSON.stringify({
|
|
536
|
+
error: 'INVALID_WORKFLOW_TEMPLATE',
|
|
537
|
+
message: `Unknown workflow template "${workflowTemplate}". Available templates: ${availableTemplates.join(', ')}`,
|
|
538
|
+
}),
|
|
539
|
+
},
|
|
540
|
+
],
|
|
541
|
+
isError: true,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
// Create workflow from template
|
|
545
|
+
const templateWorkflow = createWorkflowFromTemplate(workflowTemplate);
|
|
546
|
+
if (templateWorkflow !== undefined) {
|
|
547
|
+
resolvedWorkflow = templateWorkflow.map(step => ({
|
|
548
|
+
stepId: step.stepId,
|
|
549
|
+
name: step.name,
|
|
550
|
+
type: step.type,
|
|
551
|
+
config: step.config ?? {},
|
|
552
|
+
}));
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
else if (workflow !== undefined && workflow.length > 0) {
|
|
556
|
+
// Use custom workflow
|
|
557
|
+
resolvedWorkflow = workflow.map(step => ({
|
|
558
|
+
stepId: step.stepId,
|
|
559
|
+
name: step.name,
|
|
560
|
+
type: step.type,
|
|
561
|
+
config: step.config ?? {},
|
|
562
|
+
}));
|
|
563
|
+
}
|
|
564
|
+
// Register the agent with resolved workflow
|
|
565
|
+
const profile = {
|
|
566
|
+
agentId,
|
|
567
|
+
description,
|
|
568
|
+
displayName,
|
|
569
|
+
systemPrompt,
|
|
570
|
+
team,
|
|
571
|
+
capabilities: capabilities ?? [],
|
|
572
|
+
tags: tags ?? [],
|
|
573
|
+
workflow: resolvedWorkflow,
|
|
574
|
+
enabled,
|
|
575
|
+
};
|
|
576
|
+
await registry.register(profile);
|
|
577
|
+
// Build response message
|
|
578
|
+
const responseMessage = workflowTemplate !== undefined
|
|
579
|
+
? `Agent "${agentId}" registered successfully with "${workflowTemplate}" workflow template`
|
|
580
|
+
: resolvedWorkflow !== undefined
|
|
581
|
+
? `Agent "${agentId}" registered successfully with ${resolvedWorkflow.length} workflow step(s)`
|
|
582
|
+
: `Agent "${agentId}" registered successfully`;
|
|
583
|
+
return {
|
|
584
|
+
content: [
|
|
585
|
+
{
|
|
586
|
+
type: 'text',
|
|
587
|
+
text: JSON.stringify({
|
|
588
|
+
registered: true,
|
|
589
|
+
agentId,
|
|
590
|
+
message: responseMessage,
|
|
591
|
+
workflowTemplate: workflowTemplate ?? null,
|
|
592
|
+
workflowSteps: resolvedWorkflow?.length ?? 0,
|
|
593
|
+
createdAt: new Date().toISOString(),
|
|
594
|
+
}, null, 2),
|
|
595
|
+
},
|
|
596
|
+
],
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
catch (error) {
|
|
600
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
601
|
+
return {
|
|
602
|
+
content: [
|
|
603
|
+
{
|
|
604
|
+
type: 'text',
|
|
605
|
+
text: JSON.stringify({
|
|
606
|
+
error: 'AGENT_REGISTER_FAILED',
|
|
607
|
+
message,
|
|
608
|
+
}),
|
|
609
|
+
},
|
|
610
|
+
],
|
|
611
|
+
isError: true,
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
/**
|
|
616
|
+
* Handler for agent_remove tool
|
|
617
|
+
*/
|
|
618
|
+
export const handleAgentRemove = async (args) => {
|
|
619
|
+
const agentId = args.agentId;
|
|
620
|
+
try {
|
|
621
|
+
const registry = await getSharedRegistry();
|
|
622
|
+
// Check if agent exists
|
|
623
|
+
const existing = await registry.get(agentId);
|
|
624
|
+
if (existing === undefined) {
|
|
625
|
+
return {
|
|
626
|
+
content: [
|
|
627
|
+
{
|
|
628
|
+
type: 'text',
|
|
629
|
+
text: JSON.stringify({
|
|
630
|
+
removed: false,
|
|
631
|
+
agentId,
|
|
632
|
+
message: `Agent "${agentId}" not found`,
|
|
633
|
+
}),
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
// Remove the agent
|
|
639
|
+
await registry.remove(agentId);
|
|
640
|
+
return {
|
|
641
|
+
content: [
|
|
642
|
+
{
|
|
643
|
+
type: 'text',
|
|
644
|
+
text: JSON.stringify({
|
|
645
|
+
removed: true,
|
|
646
|
+
agentId,
|
|
647
|
+
message: `Agent "${agentId}" removed successfully`,
|
|
648
|
+
}, null, 2),
|
|
649
|
+
},
|
|
650
|
+
],
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
catch (error) {
|
|
654
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
655
|
+
return {
|
|
656
|
+
content: [
|
|
657
|
+
{
|
|
658
|
+
type: 'text',
|
|
659
|
+
text: JSON.stringify({
|
|
660
|
+
error: 'AGENT_REMOVE_FAILED',
|
|
661
|
+
message,
|
|
662
|
+
}),
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
isError: true,
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
// ============================================================================
|
|
670
|
+
// Agent Recommendation Tool (INV-AGT-SEL-001 through INV-AGT-SEL-006)
|
|
671
|
+
// ============================================================================
|
|
672
|
+
/**
|
|
673
|
+
* Agent recommend tool definition
|
|
674
|
+
* INV-MCP-004: Idempotent - read-only operation
|
|
675
|
+
* INV-AGT-SEL-001: Selection is deterministic
|
|
676
|
+
* INV-AGT-SEL-004: Always returns at least one result
|
|
677
|
+
*/
|
|
678
|
+
export const agentRecommendTool = {
|
|
679
|
+
name: 'agent_recommend',
|
|
680
|
+
description: 'Recommend the best agent for a given task. Returns ranked matches with confidence scores. Use this to auto-route tasks to appropriate agents. Read-only, no side effects.',
|
|
681
|
+
inputSchema: {
|
|
682
|
+
type: 'object',
|
|
683
|
+
properties: {
|
|
684
|
+
task: {
|
|
685
|
+
type: 'string',
|
|
686
|
+
description: 'Task description to match against agents (max 2000 chars)',
|
|
687
|
+
},
|
|
688
|
+
team: {
|
|
689
|
+
type: 'string',
|
|
690
|
+
description: 'Filter by team name',
|
|
691
|
+
},
|
|
692
|
+
requiredCapabilities: {
|
|
693
|
+
type: 'array',
|
|
694
|
+
items: { type: 'string' },
|
|
695
|
+
description: 'Required capabilities the agent must have',
|
|
696
|
+
},
|
|
697
|
+
excludeAgents: {
|
|
698
|
+
type: 'array',
|
|
699
|
+
items: { type: 'string' },
|
|
700
|
+
description: 'Agent IDs to exclude from matching',
|
|
701
|
+
},
|
|
702
|
+
maxResults: {
|
|
703
|
+
type: 'number',
|
|
704
|
+
description: 'Maximum number of recommendations (default 3)',
|
|
705
|
+
default: 3,
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
required: ['task'],
|
|
709
|
+
},
|
|
710
|
+
outputSchema: {
|
|
711
|
+
type: 'object',
|
|
712
|
+
properties: {
|
|
713
|
+
recommended: { type: 'string', description: 'Best matching agent ID' },
|
|
714
|
+
confidence: { type: 'number', description: 'Match confidence 0-1' },
|
|
715
|
+
reason: { type: 'string', description: 'Why this agent was selected' },
|
|
716
|
+
alternatives: {
|
|
717
|
+
type: 'array',
|
|
718
|
+
description: 'Alternative agent matches',
|
|
719
|
+
items: {
|
|
720
|
+
type: 'object',
|
|
721
|
+
properties: {
|
|
722
|
+
agentId: { type: 'string' },
|
|
723
|
+
confidence: { type: 'number' },
|
|
724
|
+
reason: { type: 'string' },
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
},
|
|
728
|
+
},
|
|
729
|
+
required: ['recommended', 'confidence', 'reason', 'alternatives'],
|
|
730
|
+
},
|
|
731
|
+
idempotent: true,
|
|
732
|
+
};
|
|
733
|
+
/**
|
|
734
|
+
* Handler for agent_recommend tool
|
|
735
|
+
* Implements INV-AGT-SEL-001 through INV-AGT-SEL-006
|
|
736
|
+
* Uses AgentSelectionService domain module for proper separation
|
|
737
|
+
*/
|
|
738
|
+
export const handleAgentRecommend = async (args) => {
|
|
739
|
+
const task = args.task;
|
|
740
|
+
const team = args.team;
|
|
741
|
+
const requiredCapabilities = args.requiredCapabilities;
|
|
742
|
+
const excludeAgents = args.excludeAgents;
|
|
743
|
+
const maxResults = args.maxResults ?? 3;
|
|
744
|
+
try {
|
|
745
|
+
const registry = await getSharedRegistry();
|
|
746
|
+
// Use domain service for agent selection (INV-AGT-SEL-001 through INV-AGT-SEL-006)
|
|
747
|
+
const selectionService = createAgentSelectionService(registry);
|
|
748
|
+
// INV-AGT-SEL-001: Selection is deterministic (same input = same output)
|
|
749
|
+
const result = await selectionService.recommend({
|
|
750
|
+
task,
|
|
751
|
+
team,
|
|
752
|
+
requiredCapabilities,
|
|
753
|
+
excludeAgents,
|
|
754
|
+
maxResults,
|
|
755
|
+
});
|
|
756
|
+
// INV-AGT-SEL-004: Always returns at least one result (service handles fallback)
|
|
757
|
+
return {
|
|
758
|
+
content: [
|
|
759
|
+
{
|
|
760
|
+
type: 'text',
|
|
761
|
+
text: JSON.stringify({
|
|
762
|
+
recommended: result.recommended,
|
|
763
|
+
confidence: result.confidence,
|
|
764
|
+
reason: result.reason,
|
|
765
|
+
alternatives: result.alternatives.map(alt => ({
|
|
766
|
+
agentId: alt.agentId,
|
|
767
|
+
confidence: alt.confidence,
|
|
768
|
+
})),
|
|
769
|
+
}, null, 2),
|
|
770
|
+
},
|
|
771
|
+
],
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
catch (error) {
|
|
775
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
776
|
+
return {
|
|
777
|
+
content: [
|
|
778
|
+
{
|
|
779
|
+
type: 'text',
|
|
780
|
+
text: JSON.stringify({
|
|
781
|
+
error: 'AGENT_RECOMMEND_FAILED',
|
|
782
|
+
message,
|
|
783
|
+
}),
|
|
784
|
+
},
|
|
785
|
+
],
|
|
786
|
+
isError: true,
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
// ============================================================================
|
|
791
|
+
// Agent Capabilities Tool
|
|
792
|
+
// ============================================================================
|
|
793
|
+
/**
|
|
794
|
+
* Agent capabilities tool definition
|
|
795
|
+
* INV-MCP-004: Idempotent - read-only operation
|
|
796
|
+
*/
|
|
797
|
+
export const agentCapabilitiesTool = {
|
|
798
|
+
name: 'agent_capabilities',
|
|
799
|
+
description: 'List all unique capabilities across agents with mapping to agent IDs. Use for capability-based routing and discovery. Read-only, no side effects.',
|
|
800
|
+
inputSchema: {
|
|
801
|
+
type: 'object',
|
|
802
|
+
properties: {
|
|
803
|
+
category: {
|
|
804
|
+
type: 'string',
|
|
805
|
+
enum: ['orchestrator', 'implementer', 'reviewer', 'specialist', 'generalist'],
|
|
806
|
+
description: 'Filter by agent category',
|
|
807
|
+
},
|
|
808
|
+
includeDisabled: {
|
|
809
|
+
type: 'boolean',
|
|
810
|
+
description: 'Include disabled agents (default false)',
|
|
811
|
+
default: false,
|
|
812
|
+
},
|
|
813
|
+
},
|
|
814
|
+
},
|
|
815
|
+
outputSchema: {
|
|
816
|
+
type: 'object',
|
|
817
|
+
properties: {
|
|
818
|
+
capabilities: {
|
|
819
|
+
type: 'array',
|
|
820
|
+
items: { type: 'string' },
|
|
821
|
+
description: 'All unique capabilities',
|
|
822
|
+
},
|
|
823
|
+
agentsByCapability: {
|
|
824
|
+
type: 'object',
|
|
825
|
+
description: 'Capability → agent IDs mapping',
|
|
826
|
+
additionalProperties: {
|
|
827
|
+
type: 'array',
|
|
828
|
+
items: { type: 'string' },
|
|
829
|
+
},
|
|
830
|
+
},
|
|
831
|
+
capabilitiesByAgent: {
|
|
832
|
+
type: 'object',
|
|
833
|
+
description: 'Agent ID → capabilities mapping',
|
|
834
|
+
additionalProperties: {
|
|
835
|
+
type: 'array',
|
|
836
|
+
items: { type: 'string' },
|
|
837
|
+
},
|
|
838
|
+
},
|
|
839
|
+
categoriesByAgent: {
|
|
840
|
+
type: 'object',
|
|
841
|
+
description: 'Agent ID → category mapping',
|
|
842
|
+
additionalProperties: { type: 'string' },
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
required: ['capabilities', 'agentsByCapability', 'capabilitiesByAgent'],
|
|
846
|
+
},
|
|
847
|
+
idempotent: true,
|
|
848
|
+
};
|
|
849
|
+
/**
|
|
850
|
+
* Handler for agent_capabilities tool
|
|
851
|
+
* Uses AgentSelectionService domain module for proper separation
|
|
852
|
+
*/
|
|
853
|
+
export const handleAgentCapabilities = async (args) => {
|
|
854
|
+
const category = args.category;
|
|
855
|
+
const includeDisabled = args.includeDisabled ?? false;
|
|
856
|
+
try {
|
|
857
|
+
const registry = await getSharedRegistry();
|
|
858
|
+
// Use domain service for capabilities discovery
|
|
859
|
+
const selectionService = createAgentSelectionService(registry);
|
|
860
|
+
// Delegate to domain service
|
|
861
|
+
const result = await selectionService.getCapabilities({
|
|
862
|
+
category,
|
|
863
|
+
includeDisabled,
|
|
864
|
+
});
|
|
865
|
+
return {
|
|
866
|
+
content: [
|
|
867
|
+
{
|
|
868
|
+
type: 'text',
|
|
869
|
+
text: JSON.stringify({
|
|
870
|
+
capabilities: result.capabilities,
|
|
871
|
+
agentsByCapability: result.agentsByCapability,
|
|
872
|
+
capabilitiesByAgent: result.capabilitiesByAgent,
|
|
873
|
+
categoriesByAgent: result.categoriesByAgent,
|
|
874
|
+
}, null, 2),
|
|
875
|
+
},
|
|
876
|
+
],
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
catch (error) {
|
|
880
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
881
|
+
return {
|
|
882
|
+
content: [
|
|
883
|
+
{
|
|
884
|
+
type: 'text',
|
|
885
|
+
text: JSON.stringify({
|
|
886
|
+
error: 'AGENT_CAPABILITIES_FAILED',
|
|
887
|
+
message,
|
|
888
|
+
}),
|
|
889
|
+
},
|
|
890
|
+
],
|
|
891
|
+
isError: true,
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
//# sourceMappingURL=agent.js.map
|