claude-flow-novice 1.5.12 → 1.5.13

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.
Files changed (40) hide show
  1. package/.claude-flow-novice/dist/mcp/auth.js +347 -0
  2. package/.claude-flow-novice/dist/mcp/claude-code-wrapper.js +717 -0
  3. package/.claude-flow-novice/dist/mcp/claude-flow-tools.js +1365 -0
  4. package/.claude-flow-novice/dist/mcp/client.js +201 -0
  5. package/.claude-flow-novice/dist/mcp/index.js +192 -0
  6. package/.claude-flow-novice/dist/mcp/integrate-wrapper.js +85 -0
  7. package/.claude-flow-novice/dist/mcp/lifecycle-manager.js +348 -0
  8. package/.claude-flow-novice/dist/mcp/load-balancer.js +386 -0
  9. package/.claude-flow-novice/dist/mcp/mcp-config-manager.js +1362 -0
  10. package/.claude-flow-novice/dist/mcp/mcp-server-novice-simplified.js +583 -0
  11. package/.claude-flow-novice/dist/mcp/mcp-server-novice.js +723 -0
  12. package/.claude-flow-novice/dist/mcp/mcp-server-sdk.js +649 -0
  13. package/.claude-flow-novice/dist/mcp/mcp-server.js +2256 -0
  14. package/.claude-flow-novice/dist/mcp/orchestration-integration.js +800 -0
  15. package/.claude-flow-novice/dist/mcp/performance-monitor.js +489 -0
  16. package/.claude-flow-novice/dist/mcp/protocol-manager.js +376 -0
  17. package/.claude-flow-novice/dist/mcp/router.js +220 -0
  18. package/.claude-flow-novice/dist/mcp/ruv-swarm-tools.js +671 -0
  19. package/.claude-flow-novice/dist/mcp/ruv-swarm-wrapper.js +254 -0
  20. package/.claude-flow-novice/dist/mcp/server-with-wrapper.js +32 -0
  21. package/.claude-flow-novice/dist/mcp/server-wrapper-mode.js +26 -0
  22. package/.claude-flow-novice/dist/mcp/server.js +539 -0
  23. package/.claude-flow-novice/dist/mcp/session-manager.js +338 -0
  24. package/.claude-flow-novice/dist/mcp/sparc-modes.js +455 -0
  25. package/.claude-flow-novice/dist/mcp/swarm-tools.js +903 -0
  26. package/.claude-flow-novice/dist/mcp/tools.js +426 -0
  27. package/.claude-flow-novice/dist/src/cli/commands/swarm.js +23 -1
  28. package/.claude-flow-novice/dist/src/cli/commands/swarm.js.map +1 -1
  29. package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/CLAUDE.md +40 -101
  30. package/.claude-flow-novice/dist/src/coordination/swarm-coordinator-factory.js +36 -0
  31. package/.claude-flow-novice/dist/src/coordination/swarm-coordinator-factory.js.map +1 -0
  32. package/.claude-flow-novice/dist/src/validators/index.js +12 -0
  33. package/.claude-flow-novice/dist/src/validators/index.js.map +1 -0
  34. package/.claude-flow-novice/dist/src/validators/swarm-init-validator.js +261 -0
  35. package/.claude-flow-novice/dist/src/validators/swarm-init-validator.js.map +1 -0
  36. package/.claude-flow-novice/dist/src/validators/todowrite-batching-validator.js +204 -0
  37. package/.claude-flow-novice/dist/src/validators/todowrite-batching-validator.js.map +1 -0
  38. package/.claude-flow-novice/dist/src/validators/todowrite-integration.js +189 -0
  39. package/.claude-flow-novice/dist/src/validators/todowrite-integration.js.map +1 -0
  40. package/package.json +2 -2
@@ -0,0 +1,539 @@
1
+ /**
2
+ * MCP (Model Context Protocol) server implementation
3
+ */ import { MCPError as MCPErrorClass, MCPMethodNotFoundError } from '../utils/errors.js';
4
+ import { StdioTransport } from './transports/stdio.js';
5
+ import { HttpTransport } from './transports/http.js';
6
+ import { ToolRegistry } from './tools.js';
7
+ import { RequestRouter } from './router.js';
8
+ import { SessionManager } from './session-manager.js';
9
+ import { AuthManager } from './auth.js';
10
+ import { LoadBalancer, RequestQueue } from './load-balancer.js';
11
+ import { createClaudeFlowTools } from './claude-flow-tools.js';
12
+ import { createSwarmTools } from './swarm-tools.js';
13
+ import { createRuvSwarmTools, isRuvSwarmAvailable, initializeRuvSwarmIntegration } from './ruv-swarm-tools.js';
14
+ import { platform, arch } from 'node:os';
15
+ import { performance } from 'node:perf_hooks';
16
+ /**
17
+ * MCP server implementation
18
+ */ export class MCPServer {
19
+ config;
20
+ eventBus;
21
+ logger;
22
+ orchestrator;
23
+ swarmCoordinator;
24
+ agentManager;
25
+ resourceManager;
26
+ messagebus;
27
+ monitor;
28
+ transport;
29
+ toolRegistry;
30
+ router;
31
+ sessionManager;
32
+ authManager;
33
+ loadBalancer;
34
+ requestQueue;
35
+ running = false;
36
+ currentSession;
37
+ serverInfo = {
38
+ name: 'Claude-Flow MCP Server',
39
+ version: '1.0.0'
40
+ };
41
+ supportedProtocolVersion = {
42
+ major: 2024,
43
+ minor: 11,
44
+ patch: 5
45
+ };
46
+ serverCapabilities = {
47
+ logging: {
48
+ level: 'info'
49
+ },
50
+ tools: {
51
+ listChanged: true
52
+ },
53
+ resources: {
54
+ listChanged: false,
55
+ subscribe: false
56
+ },
57
+ prompts: {
58
+ listChanged: false
59
+ }
60
+ };
61
+ constructor(config, eventBus, logger, orchestrator, swarmCoordinator, agentManager, resourceManager, messagebus, monitor){
62
+ this.config = config;
63
+ this.eventBus = eventBus;
64
+ this.logger = logger;
65
+ this.orchestrator = orchestrator;
66
+ this.swarmCoordinator = swarmCoordinator;
67
+ this.agentManager = agentManager;
68
+ this.resourceManager = resourceManager;
69
+ this.messagebus = messagebus;
70
+ this.monitor = monitor;
71
+ // Initialize transport
72
+ this.transport = this.createTransport();
73
+ // Initialize tool registry
74
+ this.toolRegistry = new ToolRegistry(logger);
75
+ // Initialize session manager
76
+ this.sessionManager = new SessionManager(config, logger);
77
+ // Initialize auth manager
78
+ this.authManager = new AuthManager(config.auth || {
79
+ enabled: false,
80
+ method: 'token'
81
+ }, logger);
82
+ // Initialize load balancer if enabled
83
+ if (config.loadBalancer?.enabled) {
84
+ this.loadBalancer = new LoadBalancer(config.loadBalancer, logger);
85
+ this.requestQueue = new RequestQueue(1000, 30000, logger);
86
+ }
87
+ // Initialize request router
88
+ this.router = new RequestRouter(this.toolRegistry, logger);
89
+ }
90
+ async start() {
91
+ if (this.running) {
92
+ throw new MCPErrorClass('MCP server already running');
93
+ }
94
+ this.logger.info('Starting MCP server', {
95
+ transport: this.config.transport
96
+ });
97
+ try {
98
+ // Set up request handler
99
+ this.transport.onRequest(async (request)=>{
100
+ return await this.handleRequest(request);
101
+ });
102
+ // Start transport
103
+ await this.transport.start();
104
+ // Register built-in tools
105
+ this.registerBuiltInTools();
106
+ this.running = true;
107
+ this.logger.info('MCP server started successfully');
108
+ } catch (error) {
109
+ this.logger.error('Failed to start MCP server', error);
110
+ throw new MCPErrorClass('Failed to start MCP server', {
111
+ error
112
+ });
113
+ }
114
+ }
115
+ async stop() {
116
+ if (!this.running) {
117
+ return;
118
+ }
119
+ this.logger.info('Stopping MCP server');
120
+ try {
121
+ // Stop transport
122
+ await this.transport.stop();
123
+ // Clean up session manager
124
+ if (this.sessionManager && 'destroy' in this.sessionManager) {
125
+ this.sessionManager.destroy();
126
+ }
127
+ // Clean up all sessions
128
+ for (const session of this.sessionManager.getActiveSessions()){
129
+ this.sessionManager.removeSession(session.id);
130
+ }
131
+ this.running = false;
132
+ this.currentSession = undefined;
133
+ this.logger.info('MCP server stopped');
134
+ } catch (error) {
135
+ this.logger.error('Error stopping MCP server', error);
136
+ throw error;
137
+ }
138
+ }
139
+ registerTool(tool) {
140
+ this.toolRegistry.register(tool);
141
+ this.logger.info('Tool registered', {
142
+ name: tool.name
143
+ });
144
+ }
145
+ async getHealthStatus() {
146
+ try {
147
+ const transportHealth = await this.transport.getHealthStatus();
148
+ const registeredTools = this.toolRegistry.getToolCount();
149
+ const { totalRequests, successfulRequests, failedRequests } = this.router.getMetrics();
150
+ const sessionMetrics = this.sessionManager.getSessionMetrics();
151
+ const metrics = {
152
+ registeredTools,
153
+ totalRequests,
154
+ successfulRequests,
155
+ failedRequests,
156
+ totalSessions: sessionMetrics.total,
157
+ activeSessions: sessionMetrics.active,
158
+ authenticatedSessions: sessionMetrics.authenticated,
159
+ expiredSessions: sessionMetrics.expired,
160
+ ...transportHealth.metrics
161
+ };
162
+ if (this.loadBalancer) {
163
+ const lbMetrics = this.loadBalancer.getMetrics();
164
+ metrics.rateLimitedRequests = lbMetrics.rateLimitedRequests;
165
+ metrics.averageResponseTime = lbMetrics.averageResponseTime;
166
+ metrics.requestsPerSecond = lbMetrics.requestsPerSecond;
167
+ metrics.circuitBreakerTrips = lbMetrics.circuitBreakerTrips;
168
+ }
169
+ const status = {
170
+ healthy: this.running && transportHealth.healthy,
171
+ metrics
172
+ };
173
+ if (transportHealth.error !== undefined) {
174
+ status.error = transportHealth.error;
175
+ }
176
+ return status;
177
+ } catch (error) {
178
+ return {
179
+ healthy: false,
180
+ error: error instanceof Error ? error.message : 'Unknown error'
181
+ };
182
+ }
183
+ }
184
+ getMetrics() {
185
+ const routerMetrics = this.router.getMetrics();
186
+ const sessionMetrics = this.sessionManager.getSessionMetrics();
187
+ const lbMetrics = this.loadBalancer?.getMetrics();
188
+ return {
189
+ totalRequests: routerMetrics.totalRequests,
190
+ successfulRequests: routerMetrics.successfulRequests,
191
+ failedRequests: routerMetrics.failedRequests,
192
+ averageResponseTime: lbMetrics?.averageResponseTime || 0,
193
+ activeSessions: sessionMetrics.active,
194
+ toolInvocations: {},
195
+ errors: {},
196
+ lastReset: lbMetrics?.lastReset || new Date()
197
+ };
198
+ }
199
+ getSessions() {
200
+ return this.sessionManager.getActiveSessions();
201
+ }
202
+ getSession(sessionId) {
203
+ return this.sessionManager.getSession(sessionId);
204
+ }
205
+ terminateSession(sessionId) {
206
+ this.sessionManager.removeSession(sessionId);
207
+ if (this.currentSession?.id === sessionId) {
208
+ this.currentSession = undefined;
209
+ }
210
+ }
211
+ async handleRequest(request) {
212
+ this.logger.debug('Handling MCP request', {
213
+ id: request.id,
214
+ method: request.method
215
+ });
216
+ try {
217
+ // Handle initialization request separately
218
+ if (request.method === 'initialize') {
219
+ return await this.handleInitialize(request);
220
+ }
221
+ // Get or create session
222
+ const session = this.getOrCreateSession();
223
+ // Check if session is initialized for non-initialize requests
224
+ if (!session.isInitialized) {
225
+ return {
226
+ jsonrpc: '2.0',
227
+ id: request.id,
228
+ error: {
229
+ code: -32002,
230
+ message: 'Server not initialized'
231
+ }
232
+ };
233
+ }
234
+ // Update session activity
235
+ this.sessionManager.updateActivity(session.id);
236
+ // Check load balancer constraints
237
+ if (this.loadBalancer) {
238
+ const allowed = await this.loadBalancer.shouldAllowRequest(session, request);
239
+ if (!allowed) {
240
+ return {
241
+ jsonrpc: '2.0',
242
+ id: request.id,
243
+ error: {
244
+ code: -32000,
245
+ message: 'Rate limit exceeded or circuit breaker open'
246
+ }
247
+ };
248
+ }
249
+ }
250
+ // Record request start
251
+ const requestMetrics = this.loadBalancer?.recordRequestStart(session, request);
252
+ try {
253
+ // Process request through router
254
+ const result = await this.router.route(request);
255
+ const response = {
256
+ jsonrpc: '2.0',
257
+ id: request.id,
258
+ result
259
+ };
260
+ // Record success
261
+ if (requestMetrics) {
262
+ this.loadBalancer?.recordRequestEnd(requestMetrics, response);
263
+ }
264
+ return response;
265
+ } catch (error) {
266
+ // Record failure
267
+ if (requestMetrics) {
268
+ this.loadBalancer?.recordRequestEnd(requestMetrics, undefined, error);
269
+ }
270
+ throw error;
271
+ }
272
+ } catch (error) {
273
+ this.logger.error('Error handling MCP request', {
274
+ id: request.id,
275
+ method: request.method,
276
+ error
277
+ });
278
+ return {
279
+ jsonrpc: '2.0',
280
+ id: request.id,
281
+ error: this.errorToMCPError(error)
282
+ };
283
+ }
284
+ }
285
+ async handleInitialize(request) {
286
+ try {
287
+ const params = request.params;
288
+ if (!params) {
289
+ return {
290
+ jsonrpc: '2.0',
291
+ id: request.id,
292
+ error: {
293
+ code: -32602,
294
+ message: 'Invalid params'
295
+ }
296
+ };
297
+ }
298
+ // Create session
299
+ const session = this.sessionManager.createSession(this.config.transport);
300
+ this.currentSession = session;
301
+ // Initialize session
302
+ this.sessionManager.initializeSession(session.id, params);
303
+ // Prepare response
304
+ const result = {
305
+ protocolVersion: this.supportedProtocolVersion,
306
+ capabilities: this.serverCapabilities,
307
+ serverInfo: this.serverInfo,
308
+ instructions: 'Claude-Flow MCP Server ready for tool execution'
309
+ };
310
+ this.logger.info('Session initialized', {
311
+ sessionId: session.id,
312
+ clientInfo: params.clientInfo,
313
+ protocolVersion: params.protocolVersion
314
+ });
315
+ return {
316
+ jsonrpc: '2.0',
317
+ id: request.id,
318
+ result
319
+ };
320
+ } catch (error) {
321
+ this.logger.error('Error during initialization', error);
322
+ return {
323
+ jsonrpc: '2.0',
324
+ id: request.id,
325
+ error: this.errorToMCPError(error)
326
+ };
327
+ }
328
+ }
329
+ getOrCreateSession() {
330
+ if (this.currentSession) {
331
+ return this.currentSession;
332
+ }
333
+ // For stdio transport, create a default session
334
+ const session = this.sessionManager.createSession(this.config.transport);
335
+ this.currentSession = session;
336
+ return session;
337
+ }
338
+ createTransport() {
339
+ switch(this.config.transport){
340
+ case 'stdio':
341
+ return new StdioTransport(this.logger);
342
+ case 'http':
343
+ return new HttpTransport(this.config.host || 'localhost', this.config.port || 3000, this.config.tlsEnabled || false, this.logger);
344
+ default:
345
+ throw new MCPErrorClass(`Unknown transport type: ${this.config.transport}`);
346
+ }
347
+ }
348
+ registerBuiltInTools() {
349
+ // System information tool
350
+ this.registerTool({
351
+ name: 'system/info',
352
+ description: 'Get system information',
353
+ inputSchema: {
354
+ type: 'object',
355
+ properties: {}
356
+ },
357
+ handler: async ()=>{
358
+ return {
359
+ version: '1.0.0',
360
+ platform: platform(),
361
+ arch: arch(),
362
+ runtime: 'Node.js',
363
+ uptime: performance.now()
364
+ };
365
+ }
366
+ });
367
+ // Health check tool
368
+ this.registerTool({
369
+ name: 'system/health',
370
+ description: 'Get system health status',
371
+ inputSchema: {
372
+ type: 'object',
373
+ properties: {}
374
+ },
375
+ handler: async ()=>{
376
+ return await this.getHealthStatus();
377
+ }
378
+ });
379
+ // List tools
380
+ this.registerTool({
381
+ name: 'tools/list',
382
+ description: 'List all available tools',
383
+ inputSchema: {
384
+ type: 'object',
385
+ properties: {}
386
+ },
387
+ handler: async ()=>{
388
+ return this.toolRegistry.listTools();
389
+ }
390
+ });
391
+ // Tool schema
392
+ this.registerTool({
393
+ name: 'tools/schema',
394
+ description: 'Get schema for a specific tool',
395
+ inputSchema: {
396
+ type: 'object',
397
+ properties: {
398
+ name: {
399
+ type: 'string'
400
+ }
401
+ },
402
+ required: [
403
+ 'name'
404
+ ]
405
+ },
406
+ handler: async (input)=>{
407
+ const tool = this.toolRegistry.getTool(input.name);
408
+ if (!tool) {
409
+ throw new Error(`Tool not found: ${input.name}`);
410
+ }
411
+ return {
412
+ name: tool.name,
413
+ description: tool.description,
414
+ inputSchema: tool.inputSchema
415
+ };
416
+ }
417
+ });
418
+ // Register Claude-Flow specific tools if orchestrator is available
419
+ if (this.orchestrator) {
420
+ const claudeFlowTools = createClaudeFlowTools(this.logger);
421
+ for (const tool of claudeFlowTools){
422
+ // Wrap the handler to inject orchestrator context
423
+ const originalHandler = tool.handler;
424
+ tool.handler = async (input, context)=>{
425
+ const claudeFlowContext = {
426
+ ...context,
427
+ orchestrator: this.orchestrator
428
+ };
429
+ return await originalHandler(input, claudeFlowContext);
430
+ };
431
+ this.registerTool(tool);
432
+ }
433
+ this.logger.info('Registered Claude-Flow tools', {
434
+ count: claudeFlowTools.length
435
+ });
436
+ } else {
437
+ this.logger.warn('Orchestrator not available - Claude-Flow tools not registered');
438
+ }
439
+ // Register Swarm-specific tools if swarm components are available
440
+ if (this.swarmCoordinator || this.agentManager || this.resourceManager) {
441
+ const swarmTools = createSwarmTools(this.logger);
442
+ for (const tool of swarmTools){
443
+ // Wrap the handler to inject swarm context
444
+ const originalHandler = tool.handler;
445
+ tool.handler = async (input, context)=>{
446
+ const swarmContext = {
447
+ ...context,
448
+ swarmCoordinator: this.swarmCoordinator,
449
+ agentManager: this.agentManager,
450
+ resourceManager: this.resourceManager,
451
+ messageBus: this.messagebus,
452
+ monitor: this.monitor
453
+ };
454
+ return await originalHandler(input, swarmContext);
455
+ };
456
+ this.registerTool(tool);
457
+ }
458
+ this.logger.info('Registered Swarm tools', {
459
+ count: swarmTools.length
460
+ });
461
+ } else {
462
+ this.logger.warn('Swarm components not available - Swarm tools not registered');
463
+ }
464
+ // Register ruv-swarm MCP tools if available
465
+ this.registerRuvSwarmTools();
466
+ }
467
+ /**
468
+ * Register ruv-swarm MCP tools if available
469
+ */ async registerRuvSwarmTools() {
470
+ try {
471
+ // Check if ruv-swarm is available
472
+ const available = await isRuvSwarmAvailable(this.logger);
473
+ if (!available) {
474
+ this.logger.info('ruv-swarm not available - skipping ruv-swarm MCP tools registration');
475
+ return;
476
+ }
477
+ // Initialize ruv-swarm integration
478
+ const workingDirectory = process.cwd();
479
+ const integration = await initializeRuvSwarmIntegration(workingDirectory, this.logger);
480
+ if (!integration.success) {
481
+ this.logger.warn('Failed to initialize ruv-swarm integration', {
482
+ error: integration.error
483
+ });
484
+ return;
485
+ }
486
+ // Create ruv-swarm tools
487
+ const ruvSwarmTools = createRuvSwarmTools(this.logger);
488
+ for (const tool of ruvSwarmTools){
489
+ // Wrap the handler to inject ruv-swarm context
490
+ const originalHandler = tool.handler;
491
+ tool.handler = async (input, context)=>{
492
+ const ruvSwarmContext = {
493
+ ...context,
494
+ workingDirectory,
495
+ sessionId: `mcp-session-${Date.now()}`,
496
+ swarmId: process.env.CLAUDE_SWARM_ID || `mcp-swarm-${Date.now()}`
497
+ };
498
+ return await originalHandler(input, ruvSwarmContext);
499
+ };
500
+ this.registerTool(tool);
501
+ }
502
+ this.logger.info('Registered ruv-swarm MCP tools', {
503
+ count: ruvSwarmTools.length,
504
+ integration: integration.data
505
+ });
506
+ } catch (error) {
507
+ this.logger.error('Error registering ruv-swarm MCP tools', error);
508
+ }
509
+ }
510
+ errorToMCPError(error) {
511
+ if (error instanceof MCPMethodNotFoundError) {
512
+ return {
513
+ code: -32601,
514
+ message: error instanceof Error ? error.message : String(error),
515
+ data: error.details
516
+ };
517
+ }
518
+ if (error instanceof MCPErrorClass) {
519
+ return {
520
+ code: -32603,
521
+ message: error instanceof Error ? error.message : String(error),
522
+ data: error.details
523
+ };
524
+ }
525
+ if (error instanceof Error) {
526
+ return {
527
+ code: -32603,
528
+ message: error instanceof Error ? error.message : String(error)
529
+ };
530
+ }
531
+ return {
532
+ code: -32603,
533
+ message: 'Internal error',
534
+ data: error
535
+ };
536
+ }
537
+ }
538
+
539
+ //# sourceMappingURL=server.js.map