agent-orchestrator-mcp-server 0.1.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.
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Integration mock for the Agent Orchestrator API client.
3
+ *
4
+ * Used in integration tests to simulate API responses without hitting real endpoints.
5
+ */
6
+ /**
7
+ * Creates a mock Agent Orchestrator client for integration testing.
8
+ */
9
+ export function createIntegrationMockOrchestratorClient(initialMockData) {
10
+ const mockData = {
11
+ sessions: initialMockData?.sessions || [
12
+ {
13
+ id: 1,
14
+ slug: 'test-session-1',
15
+ title: 'Test Session 1',
16
+ status: 'running',
17
+ agent_type: 'claude_code',
18
+ prompt: 'Test prompt',
19
+ git_root: 'https://github.com/example/repo.git',
20
+ branch: 'main',
21
+ subdirectory: null,
22
+ execution_provider: 'local_filesystem',
23
+ stop_condition: null,
24
+ mcp_servers: ['github-development'],
25
+ config: {},
26
+ metadata: { clone_path: 'repo-main-123' },
27
+ custom_metadata: {},
28
+ session_id: 'abc123',
29
+ job_id: 'job_456',
30
+ running_job_id: null,
31
+ archived_at: null,
32
+ created_at: '2025-01-15T14:30:00Z',
33
+ updated_at: '2025-01-15T14:35:00Z',
34
+ },
35
+ ],
36
+ logs: initialMockData?.logs || [
37
+ {
38
+ id: 1,
39
+ session_id: 1,
40
+ content: 'Agent started',
41
+ level: 'info',
42
+ created_at: '2025-01-15T14:30:00Z',
43
+ updated_at: '2025-01-15T14:30:00Z',
44
+ },
45
+ ],
46
+ subagentTranscripts: initialMockData?.subagentTranscripts || [
47
+ {
48
+ id: 1,
49
+ session_id: 1,
50
+ agent_id: 'agent-abc123',
51
+ tool_use_id: 'tool-xyz789',
52
+ filename: 'transcript_001.jsonl',
53
+ message_count: 15,
54
+ subagent_type: 'explore',
55
+ description: 'Exploring authentication codebase',
56
+ status: 'completed',
57
+ duration_ms: 45000,
58
+ total_tokens: 12500,
59
+ tool_use_count: 8,
60
+ formatted_duration: '45s',
61
+ formatted_tokens: '12.5k',
62
+ display_label: 'Exploring authentication codebase',
63
+ created_at: '2025-01-15T14:31:00Z',
64
+ updated_at: '2025-01-15T14:31:45Z',
65
+ },
66
+ ],
67
+ };
68
+ let sessionIdCounter = mockData.sessions?.length || 1;
69
+ let logIdCounter = mockData.logs?.length || 1;
70
+ let transcriptIdCounter = mockData.subagentTranscripts?.length || 1;
71
+ return {
72
+ mockData,
73
+ async listSessions(options) {
74
+ let sessions = [...(mockData.sessions || [])];
75
+ if (options?.status) {
76
+ sessions = sessions.filter((s) => s.status === options.status);
77
+ }
78
+ if (options?.agent_type) {
79
+ sessions = sessions.filter((s) => s.agent_type === options.agent_type);
80
+ }
81
+ if (!options?.show_archived) {
82
+ sessions = sessions.filter((s) => s.status !== 'archived');
83
+ }
84
+ const page = options?.page || 1;
85
+ const perPage = options?.per_page || 25;
86
+ const start = (page - 1) * perPage;
87
+ const paginatedSessions = sessions.slice(start, start + perPage);
88
+ return {
89
+ sessions: paginatedSessions,
90
+ pagination: {
91
+ page,
92
+ per_page: perPage,
93
+ total_count: sessions.length,
94
+ total_pages: Math.ceil(sessions.length / perPage),
95
+ },
96
+ };
97
+ },
98
+ async searchSessions(query, options) {
99
+ let sessions = [...(mockData.sessions || [])];
100
+ // Filter by query (simple contains match on title)
101
+ sessions = sessions.filter((s) => s.title.toLowerCase().includes(query.toLowerCase()));
102
+ if (options?.status) {
103
+ sessions = sessions.filter((s) => s.status === options.status);
104
+ }
105
+ if (!options?.show_archived) {
106
+ sessions = sessions.filter((s) => s.status !== 'archived');
107
+ }
108
+ const page = options?.page || 1;
109
+ const perPage = options?.per_page || 25;
110
+ const start = (page - 1) * perPage;
111
+ const paginatedSessions = sessions.slice(start, start + perPage);
112
+ return {
113
+ query,
114
+ search_contents: options?.search_contents || false,
115
+ sessions: paginatedSessions,
116
+ pagination: {
117
+ page,
118
+ per_page: perPage,
119
+ total_count: sessions.length,
120
+ total_pages: Math.ceil(sessions.length / perPage),
121
+ },
122
+ };
123
+ },
124
+ async getSession(id, includeTranscript) {
125
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
126
+ if (!session) {
127
+ throw new Error(`API Error (404): Session not found`);
128
+ }
129
+ const result = { ...session };
130
+ if (includeTranscript) {
131
+ result.transcript = '{"type":"user",...}\n{"type":"assistant",...}';
132
+ }
133
+ return result;
134
+ },
135
+ async createSession(data) {
136
+ sessionIdCounter++;
137
+ const session = {
138
+ id: sessionIdCounter,
139
+ slug: data.slug || null,
140
+ title: data.title || 'New Session',
141
+ status: 'waiting',
142
+ agent_type: data.agent_type || 'claude_code',
143
+ prompt: data.prompt || null,
144
+ git_root: data.git_root || null,
145
+ branch: data.branch || 'main',
146
+ subdirectory: data.subdirectory || null,
147
+ execution_provider: data.execution_provider || 'local_filesystem',
148
+ stop_condition: data.stop_condition || null,
149
+ mcp_servers: data.mcp_servers || [],
150
+ config: data.config || {},
151
+ metadata: {},
152
+ custom_metadata: data.custom_metadata || {},
153
+ session_id: null,
154
+ job_id: data.prompt ? `job_${Date.now()}` : null,
155
+ running_job_id: null,
156
+ archived_at: null,
157
+ created_at: new Date().toISOString(),
158
+ updated_at: new Date().toISOString(),
159
+ };
160
+ mockData.sessions?.push(session);
161
+ return session;
162
+ },
163
+ async updateSession(id, data) {
164
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
165
+ if (!session) {
166
+ throw new Error(`API Error (404): Session not found`);
167
+ }
168
+ if (data.title !== undefined)
169
+ session.title = data.title;
170
+ if (data.slug !== undefined)
171
+ session.slug = data.slug;
172
+ if (data.stop_condition !== undefined)
173
+ session.stop_condition = data.stop_condition;
174
+ if (data.custom_metadata !== undefined)
175
+ session.custom_metadata = data.custom_metadata;
176
+ session.updated_at = new Date().toISOString();
177
+ return session;
178
+ },
179
+ async deleteSession(id) {
180
+ const index = mockData.sessions?.findIndex((s) => s.id === Number(id) || s.slug === String(id));
181
+ if (index === undefined || index === -1) {
182
+ throw new Error(`API Error (404): Session not found`);
183
+ }
184
+ mockData.sessions?.splice(index, 1);
185
+ },
186
+ async archiveSession(id) {
187
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
188
+ if (!session) {
189
+ throw new Error(`API Error (404): Session not found`);
190
+ }
191
+ session.status = 'archived';
192
+ session.archived_at = new Date().toISOString();
193
+ session.updated_at = new Date().toISOString();
194
+ return session;
195
+ },
196
+ async unarchiveSession(id) {
197
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
198
+ if (!session) {
199
+ throw new Error(`API Error (404): Session not found`);
200
+ }
201
+ session.status = 'needs_input';
202
+ session.archived_at = null;
203
+ session.updated_at = new Date().toISOString();
204
+ return session;
205
+ },
206
+ async followUp(id, prompt) {
207
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
208
+ if (!session) {
209
+ throw new Error(`API Error (404): Session not found`);
210
+ }
211
+ if (session.status !== 'needs_input') {
212
+ throw new Error(`API Error (422): Session is not in needs_input status`);
213
+ }
214
+ session.prompt = prompt;
215
+ session.status = 'running';
216
+ session.running_job_id = `job_${Date.now()}`;
217
+ session.updated_at = new Date().toISOString();
218
+ return { session, message: 'Follow-up prompt sent' };
219
+ },
220
+ async pauseSession(id) {
221
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
222
+ if (!session) {
223
+ throw new Error(`API Error (404): Session not found`);
224
+ }
225
+ session.status = 'needs_input';
226
+ session.running_job_id = null;
227
+ session.updated_at = new Date().toISOString();
228
+ return { session, message: 'Session paused' };
229
+ },
230
+ async restartSession(id) {
231
+ const session = mockData.sessions?.find((s) => s.id === Number(id) || s.slug === String(id));
232
+ if (!session) {
233
+ throw new Error(`API Error (404): Session not found`);
234
+ }
235
+ session.status = 'running';
236
+ session.running_job_id = `job_${Date.now()}`;
237
+ session.updated_at = new Date().toISOString();
238
+ return { session, message: 'Session restarted' };
239
+ },
240
+ async listLogs(sessionId, options) {
241
+ let logs = (mockData.logs || []).filter((l) => l.session_id === Number(sessionId));
242
+ if (options?.level) {
243
+ logs = logs.filter((l) => l.level === options.level);
244
+ }
245
+ const page = options?.page || 1;
246
+ const perPage = options?.per_page || 25;
247
+ const start = (page - 1) * perPage;
248
+ const paginatedLogs = logs.slice(start, start + perPage);
249
+ return {
250
+ logs: paginatedLogs,
251
+ pagination: {
252
+ page,
253
+ per_page: perPage,
254
+ total_count: logs.length,
255
+ total_pages: Math.ceil(logs.length / perPage),
256
+ },
257
+ };
258
+ },
259
+ async getLog(sessionId, logId) {
260
+ const log = mockData.logs?.find((l) => l.session_id === Number(sessionId) && l.id === logId);
261
+ if (!log) {
262
+ throw new Error(`API Error (404): Log not found`);
263
+ }
264
+ return log;
265
+ },
266
+ async createLog(sessionId, data) {
267
+ logIdCounter++;
268
+ const log = {
269
+ id: logIdCounter,
270
+ session_id: Number(sessionId),
271
+ content: data.content,
272
+ level: data.level,
273
+ created_at: new Date().toISOString(),
274
+ updated_at: new Date().toISOString(),
275
+ };
276
+ mockData.logs?.push(log);
277
+ return log;
278
+ },
279
+ async updateLog(sessionId, logId, data) {
280
+ const log = mockData.logs?.find((l) => l.session_id === Number(sessionId) && l.id === logId);
281
+ if (!log) {
282
+ throw new Error(`API Error (404): Log not found`);
283
+ }
284
+ if (data.content !== undefined)
285
+ log.content = data.content;
286
+ if (data.level !== undefined)
287
+ log.level = data.level;
288
+ log.updated_at = new Date().toISOString();
289
+ return log;
290
+ },
291
+ async deleteLog(sessionId, logId) {
292
+ const index = mockData.logs?.findIndex((l) => l.session_id === Number(sessionId) && l.id === logId);
293
+ if (index === undefined || index === -1) {
294
+ throw new Error(`API Error (404): Log not found`);
295
+ }
296
+ mockData.logs?.splice(index, 1);
297
+ },
298
+ async listSubagentTranscripts(sessionId, options) {
299
+ let transcripts = (mockData.subagentTranscripts || []).filter((t) => t.session_id === Number(sessionId));
300
+ if (options?.status) {
301
+ transcripts = transcripts.filter((t) => t.status === options.status);
302
+ }
303
+ if (options?.subagent_type) {
304
+ transcripts = transcripts.filter((t) => t.subagent_type === options.subagent_type);
305
+ }
306
+ const page = options?.page || 1;
307
+ const perPage = options?.per_page || 25;
308
+ const start = (page - 1) * perPage;
309
+ const paginatedTranscripts = transcripts.slice(start, start + perPage);
310
+ return {
311
+ subagent_transcripts: paginatedTranscripts,
312
+ pagination: {
313
+ page,
314
+ per_page: perPage,
315
+ total_count: transcripts.length,
316
+ total_pages: Math.ceil(transcripts.length / perPage),
317
+ },
318
+ };
319
+ },
320
+ async getSubagentTranscript(sessionId, transcriptId, includeTranscript) {
321
+ const transcript = mockData.subagentTranscripts?.find((t) => t.session_id === Number(sessionId) && t.id === transcriptId);
322
+ if (!transcript) {
323
+ throw new Error(`API Error (404): Subagent transcript not found`);
324
+ }
325
+ const result = { ...transcript };
326
+ if (includeTranscript) {
327
+ result.transcript = '{"type":"user",...}\n{"type":"assistant",...}';
328
+ }
329
+ return result;
330
+ },
331
+ async createSubagentTranscript(sessionId, data) {
332
+ transcriptIdCounter++;
333
+ const transcript = {
334
+ id: transcriptIdCounter,
335
+ session_id: Number(sessionId),
336
+ agent_id: data.agent_id,
337
+ tool_use_id: data.tool_use_id || null,
338
+ transcript: data.transcript,
339
+ filename: data.filename || null,
340
+ message_count: data.message_count || null,
341
+ subagent_type: data.subagent_type || null,
342
+ description: data.description || null,
343
+ status: data.status || null,
344
+ duration_ms: data.duration_ms || null,
345
+ total_tokens: data.total_tokens || null,
346
+ tool_use_count: data.tool_use_count || null,
347
+ formatted_duration: null,
348
+ formatted_tokens: null,
349
+ display_label: data.description || null,
350
+ created_at: new Date().toISOString(),
351
+ updated_at: new Date().toISOString(),
352
+ };
353
+ mockData.subagentTranscripts?.push(transcript);
354
+ return transcript;
355
+ },
356
+ async updateSubagentTranscript(sessionId, transcriptId, data) {
357
+ const transcript = mockData.subagentTranscripts?.find((t) => t.session_id === Number(sessionId) && t.id === transcriptId);
358
+ if (!transcript) {
359
+ throw new Error(`API Error (404): Subagent transcript not found`);
360
+ }
361
+ Object.assign(transcript, data);
362
+ transcript.updated_at = new Date().toISOString();
363
+ return transcript;
364
+ },
365
+ async deleteSubagentTranscript(sessionId, transcriptId) {
366
+ const index = mockData.subagentTranscripts?.findIndex((t) => t.session_id === Number(sessionId) && t.id === transcriptId);
367
+ if (index === undefined || index === -1) {
368
+ throw new Error(`API Error (404): Subagent transcript not found`);
369
+ }
370
+ mockData.subagentTranscripts?.splice(index, 1);
371
+ },
372
+ };
373
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Agent Orchestrator API Client
3
+ *
4
+ * A client for interacting with the Agent Orchestrator REST API.
5
+ */
6
+ /** Default timeout for API requests in milliseconds */
7
+ const DEFAULT_TIMEOUT_MS = 30000;
8
+ /**
9
+ * Implementation of the Agent Orchestrator API client.
10
+ */
11
+ export class AgentOrchestratorClient {
12
+ baseUrl;
13
+ apiKey;
14
+ timeoutMs;
15
+ constructor(baseUrl, apiKey, timeoutMs = DEFAULT_TIMEOUT_MS) {
16
+ // Validate inputs
17
+ if (!baseUrl || baseUrl.trim().length === 0) {
18
+ throw new Error('Base URL cannot be empty');
19
+ }
20
+ if (!apiKey || apiKey.trim().length === 0) {
21
+ throw new Error('API key cannot be empty');
22
+ }
23
+ // Remove trailing slash if present
24
+ this.baseUrl = baseUrl.trim().replace(/\/$/, '');
25
+ this.apiKey = apiKey.trim();
26
+ this.timeoutMs = timeoutMs;
27
+ }
28
+ async request(method, path, body, query) {
29
+ const url = new URL(`${this.baseUrl}/api/v1${path}`);
30
+ if (query) {
31
+ Object.entries(query).forEach(([key, value]) => {
32
+ if (value !== undefined) {
33
+ url.searchParams.set(key, String(value));
34
+ }
35
+ });
36
+ }
37
+ const headers = {
38
+ 'X-API-Key': this.apiKey,
39
+ 'Content-Type': 'application/json',
40
+ };
41
+ // Set up timeout with AbortController
42
+ const controller = new AbortController();
43
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
44
+ const options = {
45
+ method,
46
+ headers,
47
+ signal: controller.signal,
48
+ };
49
+ if (body && (method === 'POST' || method === 'PATCH' || method === 'PUT')) {
50
+ options.body = JSON.stringify(body);
51
+ }
52
+ let response;
53
+ try {
54
+ response = await fetch(url.toString(), options);
55
+ }
56
+ catch (error) {
57
+ clearTimeout(timeoutId);
58
+ if (error instanceof Error && error.name === 'AbortError') {
59
+ throw new Error(`Request timeout after ${this.timeoutMs}ms`);
60
+ }
61
+ throw error;
62
+ }
63
+ finally {
64
+ clearTimeout(timeoutId);
65
+ }
66
+ if (!response.ok) {
67
+ const errorText = await response.text();
68
+ let errorMessage;
69
+ try {
70
+ const errorJson = JSON.parse(errorText);
71
+ errorMessage = errorJson.message || errorJson.error || errorText;
72
+ }
73
+ catch {
74
+ errorMessage = errorText;
75
+ }
76
+ throw new Error(`API Error (${response.status}): ${errorMessage}`);
77
+ }
78
+ // Handle 204 No Content
79
+ if (response.status === 204) {
80
+ return undefined;
81
+ }
82
+ return response.json();
83
+ }
84
+ // Sessions
85
+ async listSessions(options) {
86
+ return this.request('GET', '/sessions', undefined, options);
87
+ }
88
+ async searchSessions(query, options) {
89
+ return this.request('GET', '/sessions/search', undefined, {
90
+ q: query,
91
+ ...options,
92
+ });
93
+ }
94
+ async getSession(id, includeTranscript) {
95
+ const response = await this.request('GET', `/sessions/${id}`, undefined, {
96
+ include_transcript: includeTranscript,
97
+ });
98
+ return response.session;
99
+ }
100
+ async createSession(data) {
101
+ const response = await this.request('POST', '/sessions', data);
102
+ return response.session;
103
+ }
104
+ async updateSession(id, data) {
105
+ const response = await this.request('PATCH', `/sessions/${id}`, data);
106
+ return response.session;
107
+ }
108
+ async deleteSession(id) {
109
+ await this.request('DELETE', `/sessions/${id}`);
110
+ }
111
+ async archiveSession(id) {
112
+ const response = await this.request('POST', `/sessions/${id}/archive`);
113
+ return response.session;
114
+ }
115
+ async unarchiveSession(id) {
116
+ const response = await this.request('POST', `/sessions/${id}/unarchive`);
117
+ return response.session;
118
+ }
119
+ async followUp(id, prompt) {
120
+ return this.request('POST', `/sessions/${id}/follow_up`, { prompt });
121
+ }
122
+ async pauseSession(id) {
123
+ return this.request('POST', `/sessions/${id}/pause`);
124
+ }
125
+ async restartSession(id) {
126
+ return this.request('POST', `/sessions/${id}/restart`);
127
+ }
128
+ // Logs
129
+ async listLogs(sessionId, options) {
130
+ return this.request('GET', `/sessions/${sessionId}/logs`, undefined, options);
131
+ }
132
+ async getLog(sessionId, logId) {
133
+ const response = await this.request('GET', `/sessions/${sessionId}/logs/${logId}`);
134
+ return response.log;
135
+ }
136
+ async createLog(sessionId, data) {
137
+ const response = await this.request('POST', `/sessions/${sessionId}/logs`, data);
138
+ return response.log;
139
+ }
140
+ async updateLog(sessionId, logId, data) {
141
+ const response = await this.request('PATCH', `/sessions/${sessionId}/logs/${logId}`, data);
142
+ return response.log;
143
+ }
144
+ async deleteLog(sessionId, logId) {
145
+ await this.request('DELETE', `/sessions/${sessionId}/logs/${logId}`);
146
+ }
147
+ // Subagent Transcripts
148
+ async listSubagentTranscripts(sessionId, options) {
149
+ return this.request('GET', `/sessions/${sessionId}/subagent_transcripts`, undefined, options);
150
+ }
151
+ async getSubagentTranscript(sessionId, transcriptId, includeTranscript) {
152
+ const response = await this.request('GET', `/sessions/${sessionId}/subagent_transcripts/${transcriptId}`, undefined, { include_transcript: includeTranscript });
153
+ return response.subagent_transcript;
154
+ }
155
+ async createSubagentTranscript(sessionId, data) {
156
+ const response = await this.request('POST', `/sessions/${sessionId}/subagent_transcripts`, data);
157
+ return response.subagent_transcript;
158
+ }
159
+ async updateSubagentTranscript(sessionId, transcriptId, data) {
160
+ const response = await this.request('PATCH', `/sessions/${sessionId}/subagent_transcripts/${transcriptId}`, data);
161
+ return response.subagent_transcript;
162
+ }
163
+ async deleteSubagentTranscript(sessionId, transcriptId) {
164
+ await this.request('DELETE', `/sessions/${sessionId}/subagent_transcripts/${transcriptId}`);
165
+ }
166
+ }
@@ -0,0 +1,3 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ export declare function registerResources(server: Server): void;
3
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1,67 @@
1
+ import { ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
2
+ // =============================================================================
3
+ // RESOURCES IMPLEMENTATION
4
+ // =============================================================================
5
+ // Resources expose data that can be read by MCP clients.
6
+ // For agent-orchestrator, we expose a configuration resource for debugging.
7
+ // =============================================================================
8
+ export function registerResources(server) {
9
+ // List available resources
10
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
11
+ return {
12
+ resources: [
13
+ {
14
+ uri: 'agent-orchestrator://config',
15
+ name: 'Server Configuration',
16
+ description: 'Current server configuration and status. Useful for debugging and verifying setup.',
17
+ mimeType: 'application/json',
18
+ },
19
+ ],
20
+ };
21
+ });
22
+ // Read resource contents
23
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
24
+ const { uri } = request.params;
25
+ // =========================================================================
26
+ // CONFIG RESOURCE - Server Status and Configuration
27
+ // =========================================================================
28
+ if (uri === 'agent-orchestrator://config') {
29
+ const config = {
30
+ server: {
31
+ name: 'agent-orchestrator-mcp-server',
32
+ version: '0.1.0',
33
+ transport: 'stdio',
34
+ },
35
+ environment: {
36
+ AGENT_ORCHESTRATOR_BASE_URL: process.env.AGENT_ORCHESTRATOR_BASE_URL
37
+ ? '***configured***'
38
+ : 'not set',
39
+ AGENT_ORCHESTRATOR_API_KEY: process.env.AGENT_ORCHESTRATOR_API_KEY
40
+ ? '***configured***'
41
+ : 'not set',
42
+ ENABLED_TOOLGROUPS: process.env.ENABLED_TOOLGROUPS || 'all (default)',
43
+ SKIP_HEALTH_CHECKS: process.env.SKIP_HEALTH_CHECKS || 'false',
44
+ },
45
+ capabilities: {
46
+ tools: true,
47
+ resources: true,
48
+ },
49
+ toolGroups: {
50
+ readonly: 'Read-only operations (list, get, search)',
51
+ write: 'Write operations (create, update, follow_up, pause, restart, archive, unarchive)',
52
+ admin: 'Administrative operations (delete)',
53
+ },
54
+ };
55
+ return {
56
+ contents: [
57
+ {
58
+ uri: 'agent-orchestrator://config',
59
+ mimeType: 'application/json',
60
+ text: JSON.stringify(config, null, 2),
61
+ },
62
+ ],
63
+ };
64
+ }
65
+ throw new Error(`Resource not found: ${uri}`);
66
+ });
67
+ }
@@ -0,0 +1,31 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { type IAgentOrchestratorClient } from './orchestrator-client/orchestrator-client.js';
3
+ export type { IAgentOrchestratorClient } from './orchestrator-client/orchestrator-client.js';
4
+ export type ClientFactory = () => IAgentOrchestratorClient;
5
+ export declare function createMCPServer(): {
6
+ server: Server<{
7
+ method: string;
8
+ params?: {
9
+ [x: string]: unknown;
10
+ _meta?: {
11
+ [x: string]: unknown;
12
+ progressToken?: string | number | undefined;
13
+ } | undefined;
14
+ } | undefined;
15
+ }, {
16
+ method: string;
17
+ params?: {
18
+ [x: string]: unknown;
19
+ _meta?: {
20
+ [x: string]: unknown;
21
+ } | undefined;
22
+ } | undefined;
23
+ }, {
24
+ [x: string]: unknown;
25
+ _meta?: {
26
+ [x: string]: unknown;
27
+ } | undefined;
28
+ }>;
29
+ registerHandlers: (server: Server, clientFactory?: ClientFactory) => Promise<void>;
30
+ };
31
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1,34 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { registerResources } from './resources.js';
3
+ import { createRegisterTools } from './tools.js';
4
+ import { AgentOrchestratorClient, } from './orchestrator-client/orchestrator-client.js';
5
+ export function createMCPServer() {
6
+ const server = new Server({
7
+ name: 'agent-orchestrator-mcp-server',
8
+ version: '0.1.0',
9
+ }, {
10
+ capabilities: {
11
+ resources: {},
12
+ tools: {},
13
+ },
14
+ });
15
+ const registerHandlers = async (server, clientFactory) => {
16
+ // Use provided factory or create default client
17
+ const factory = clientFactory ||
18
+ (() => {
19
+ const baseUrl = process.env.AGENT_ORCHESTRATOR_BASE_URL;
20
+ const apiKey = process.env.AGENT_ORCHESTRATOR_API_KEY;
21
+ if (!baseUrl) {
22
+ throw new Error('AGENT_ORCHESTRATOR_BASE_URL environment variable must be configured');
23
+ }
24
+ if (!apiKey) {
25
+ throw new Error('AGENT_ORCHESTRATOR_API_KEY environment variable must be configured');
26
+ }
27
+ return new AgentOrchestratorClient(baseUrl, apiKey);
28
+ });
29
+ registerResources(server);
30
+ const registerTools = createRegisterTools(factory);
31
+ registerTools(server);
32
+ };
33
+ return { server, registerHandlers };
34
+ }