claude-flow 2.7.33 → 2.7.35
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/.claude/settings.local.json +9 -2
- package/.claude/skills/agentic-jujutsu/SKILL.md +1 -1
- package/CHANGELOG.md +140 -0
- package/bin/claude-flow +1 -1
- package/dist/src/cli/commands/mcp.js +61 -7
- package/dist/src/cli/commands/mcp.js.map +1 -1
- package/dist/src/cli/init/index.js +55 -33
- package/dist/src/cli/init/index.js.map +1 -1
- package/dist/src/cli/simple-cli.js +182 -172
- package/dist/src/cli/simple-cli.js.map +1 -1
- package/dist/src/cli/simple-commands/init/agent-copier.js +9 -3
- package/dist/src/cli/simple-commands/init/agent-copier.js.map +1 -1
- package/dist/src/core/DatabaseManager.js +39 -9
- package/dist/src/core/DatabaseManager.js.map +1 -1
- package/dist/src/mcp/async/job-manager-mcp25.js +240 -0
- package/dist/src/mcp/async/job-manager-mcp25.js.map +1 -0
- package/dist/src/mcp/index.js +8 -0
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/mcp/protocol/version-negotiation.js +182 -0
- package/dist/src/mcp/protocol/version-negotiation.js.map +1 -0
- package/dist/src/mcp/registry/mcp-registry-client-2025.js +210 -0
- package/dist/src/mcp/registry/mcp-registry-client-2025.js.map +1 -0
- package/dist/src/mcp/server-factory.js +189 -0
- package/dist/src/mcp/server-factory.js.map +1 -0
- package/dist/src/mcp/server-mcp-2025.js +283 -0
- package/dist/src/mcp/server-mcp-2025.js.map +1 -0
- package/dist/src/mcp/tool-registry-progressive.js +319 -0
- package/dist/src/mcp/tool-registry-progressive.js.map +1 -0
- package/dist/src/mcp/tools/_template.js +62 -0
- package/dist/src/mcp/tools/_template.js.map +1 -0
- package/dist/src/mcp/tools/loader.js +228 -0
- package/dist/src/mcp/tools/loader.js.map +1 -0
- package/dist/src/mcp/tools/system/search.js +224 -0
- package/dist/src/mcp/tools/system/search.js.map +1 -0
- package/dist/src/mcp/tools/system/status.js +168 -0
- package/dist/src/mcp/tools/system/status.js.map +1 -0
- package/dist/src/mcp/validation/schema-validator-2025.js +198 -0
- package/dist/src/mcp/validation/schema-validator-2025.js.map +1 -0
- package/dist/src/utils/error-recovery.js +215 -0
- package/dist/src/utils/error-recovery.js.map +1 -0
- package/dist/src/utils/metrics-reader.js +10 -0
- package/dist/src/utils/metrics-reader.js.map +1 -1
- package/docs/.claude-flow/metrics/performance.json +3 -3
- package/docs/.claude-flow/metrics/task-metrics.json +3 -3
- package/docs/.github-release-issue-v2.7.33.md +488 -0
- package/docs/AGENTDB_BRANCH_MERGE_VERIFICATION.md +436 -0
- package/docs/AUTOMATIC_ERROR_RECOVERY_v2.7.35.md +321 -0
- package/docs/BRANCH_REVIEW_SUMMARY.md +439 -0
- package/docs/CONFIRMATION_AUTOMATIC_ERROR_RECOVERY.md +384 -0
- package/docs/DEEP_CODE_REVIEW_v2.7.33.md +1159 -0
- package/docs/DOCKER_TEST_RESULTS_v2.7.35.md +305 -0
- package/docs/MCP_2025_FEATURE_CONFIRMATION.md +698 -0
- package/docs/NPM_PUBLISH_GUIDE_v2.7.33.md +628 -0
- package/docs/REGRESSION_TEST_REPORT_v2.7.33.md +397 -0
- package/docs/RELEASE_NOTES_v2.7.33.md +618 -0
- package/docs/RELEASE_READINESS_SUMMARY.md +377 -0
- package/docs/RELEASE_SUMMARY_v2.7.33.md +456 -0
- package/docs/agentic-flow-agentdb-mcp-integration.md +1198 -0
- package/docs/features/automatic-error-recovery.md +333 -0
- package/docs/github-issues/README.md +88 -0
- package/docs/github-issues/wsl-enotempty-automatic-recovery.md +470 -0
- package/docs/mcp-2025-implementation-summary.md +459 -0
- package/docs/mcp-spec-2025-implementation-plan.md +1330 -0
- package/docs/phase-1-2-implementation-summary.md +676 -0
- package/docs/regression-analysis-phase-1-2.md +555 -0
- package/docs/troubleshooting/wsl-better-sqlite3-error.md +239 -0
- package/package.json +5 -2
- package/scripts/create-github-issue.sh +64 -0
- package/scripts/test-docker-wsl.sh +198 -0
- package/src/cli/commands/mcp.ts +86 -9
- package/src/cli/init/index.ts +72 -42
- package/src/cli/simple-commands/init/agent-copier.js +10 -5
- package/src/core/DatabaseManager.ts +55 -9
- package/src/mcp/async/job-manager-mcp25.ts +456 -0
- package/src/mcp/index.ts +60 -0
- package/src/mcp/protocol/version-negotiation.ts +329 -0
- package/src/mcp/registry/mcp-registry-client-2025.ts +334 -0
- package/src/mcp/server-factory.ts +426 -0
- package/src/mcp/server-mcp-2025.ts +507 -0
- package/src/mcp/tool-registry-progressive.ts +539 -0
- package/src/mcp/tools/_template.ts +174 -0
- package/src/mcp/tools/loader.ts +362 -0
- package/src/mcp/tools/system/search.ts +276 -0
- package/src/mcp/tools/system/status.ts +206 -0
- package/src/mcp/validation/schema-validator-2025.ts +294 -0
- package/src/utils/error-recovery.ts +325 -0
- package/docs/AGENTDB_V1.6.1_DEEP_REVIEW.md +0 -386
- package/docs/AGENT_FOLDER_STRUCTURE_FIX.md +0 -192
- package/docs/RECENT_RELEASES_SUMMARY.md +0 -375
- package/docs/V2.7.31_RELEASE_NOTES.md +0 -375
- /package/.claude/agents/analysis/{analyze-code-quality.md → code-review/analyze-code-quality.md} +0 -0
- /package/.claude/agents/architecture/{arch-system-design.md → system-design/arch-system-design.md} +0 -0
- /package/.claude/agents/data/{data-ml-model.md → ml/data-ml-model.md} +0 -0
- /package/.claude/agents/development/{dev-backend-api.md → backend/dev-backend-api.md} +0 -0
- /package/.claude/agents/devops/{ops-cicd-github.md → ci-cd/ops-cicd-github.md} +0 -0
- /package/.claude/agents/documentation/{docs-api-openapi.md → api-docs/docs-api-openapi.md} +0 -0
- /package/.claude/agents/specialized/{spec-mobile-react-native.md → mobile/spec-mobile-react-native.md} +0 -0
- /package/.claude/agents/testing/{tdd-london-swarm.md → unit/tdd-london-swarm.md} +0 -0
- /package/.claude/agents/testing/{production-validator.md → validation/production-validator.md} +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { MCPServer } from './server.js';
|
|
2
|
+
import { MCP2025Server } from './server-mcp-2025.js';
|
|
3
|
+
export class MCPServerFactory {
|
|
4
|
+
static async createServer(config, eventBus, logger, orchestrator, swarmCoordinator, agentManager, resourceManager, messagebus, monitor) {
|
|
5
|
+
const features = config.features || {};
|
|
6
|
+
const useMCP2025 = features.enableMCP2025 === true;
|
|
7
|
+
if (useMCP2025) {
|
|
8
|
+
logger.info('Creating MCP 2025-11 server with enhanced features');
|
|
9
|
+
return await this.createMCP2025Server(config, eventBus, logger, orchestrator);
|
|
10
|
+
} else {
|
|
11
|
+
logger.info('Creating legacy MCP server (backward compatibility mode)');
|
|
12
|
+
return this.createLegacyServer(config, eventBus, logger, orchestrator, swarmCoordinator, agentManager, resourceManager, messagebus, monitor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
static async createMCP2025Server(config, eventBus, logger, orchestrator) {
|
|
16
|
+
const features = config.features || {};
|
|
17
|
+
const mcp2025Config = config.mcp2025 || {};
|
|
18
|
+
const serverConfig = {
|
|
19
|
+
serverId: mcp2025Config.serverId || `claude-flow-${Date.now()}`,
|
|
20
|
+
transport: config.transport || 'stdio',
|
|
21
|
+
enableMCP2025: true,
|
|
22
|
+
supportLegacyClients: features.supportLegacyClients !== false,
|
|
23
|
+
async: {
|
|
24
|
+
enabled: features.enableAsyncJobs !== false,
|
|
25
|
+
maxJobs: mcp2025Config.async?.maxJobs || 100,
|
|
26
|
+
jobTTL: mcp2025Config.async?.jobTTL || 3600000,
|
|
27
|
+
persistence: mcp2025Config.async?.persistence || 'memory'
|
|
28
|
+
},
|
|
29
|
+
registry: {
|
|
30
|
+
enabled: features.enableRegistryIntegration === true,
|
|
31
|
+
url: mcp2025Config.registry?.url || 'https://registry.mcp.run',
|
|
32
|
+
apiKey: mcp2025Config.registry?.apiKey,
|
|
33
|
+
updateInterval: mcp2025Config.registry?.updateInterval || 60000,
|
|
34
|
+
retryAttempts: mcp2025Config.registry?.retryAttempts || 3
|
|
35
|
+
},
|
|
36
|
+
validation: {
|
|
37
|
+
enabled: features.enableSchemaValidation !== false,
|
|
38
|
+
strictMode: mcp2025Config.validation?.strictMode || false
|
|
39
|
+
},
|
|
40
|
+
toolsDirectory: mcp2025Config.toolsDirectory,
|
|
41
|
+
orchestratorContext: orchestrator
|
|
42
|
+
};
|
|
43
|
+
const server = new MCP2025Server(serverConfig, eventBus, logger);
|
|
44
|
+
await server.initialize();
|
|
45
|
+
logger.info('MCP 2025-11 server created successfully', {
|
|
46
|
+
serverId: serverConfig.serverId,
|
|
47
|
+
features: {
|
|
48
|
+
versionNegotiation: true,
|
|
49
|
+
asyncJobs: serverConfig.async.enabled,
|
|
50
|
+
registry: serverConfig.registry.enabled,
|
|
51
|
+
validation: serverConfig.validation.enabled,
|
|
52
|
+
progressiveDisclosure: true
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return server;
|
|
56
|
+
}
|
|
57
|
+
static createLegacyServer(config, eventBus, logger, orchestrator, swarmCoordinator, agentManager, resourceManager, messagebus, monitor) {
|
|
58
|
+
const legacyConfig = {
|
|
59
|
+
transport: config.transport,
|
|
60
|
+
host: config.host,
|
|
61
|
+
port: config.port,
|
|
62
|
+
tlsEnabled: config.tlsEnabled,
|
|
63
|
+
enableMetrics: config.enableMetrics,
|
|
64
|
+
auth: config.auth,
|
|
65
|
+
loadBalancer: config.loadBalancer,
|
|
66
|
+
sessionTimeout: config.sessionTimeout,
|
|
67
|
+
maxSessions: config.maxSessions
|
|
68
|
+
};
|
|
69
|
+
const server = new MCPServer(legacyConfig, eventBus, logger, orchestrator, swarmCoordinator, agentManager, resourceManager, messagebus, monitor);
|
|
70
|
+
logger.info('Legacy MCP server created successfully', {
|
|
71
|
+
transport: config.transport,
|
|
72
|
+
mode: 'backward-compatibility'
|
|
73
|
+
});
|
|
74
|
+
return server;
|
|
75
|
+
}
|
|
76
|
+
static detectOptimalConfig(currentConfig) {
|
|
77
|
+
const extended = {
|
|
78
|
+
...currentConfig,
|
|
79
|
+
features: {
|
|
80
|
+
enableMCP2025: process.env.NODE_ENV !== 'production',
|
|
81
|
+
enableVersionNegotiation: true,
|
|
82
|
+
enableAsyncJobs: true,
|
|
83
|
+
enableRegistryIntegration: false,
|
|
84
|
+
enableSchemaValidation: true,
|
|
85
|
+
supportLegacyClients: true,
|
|
86
|
+
enableProgressiveDisclosure: true
|
|
87
|
+
},
|
|
88
|
+
mcp2025: {
|
|
89
|
+
async: {
|
|
90
|
+
enabled: true,
|
|
91
|
+
maxJobs: 100,
|
|
92
|
+
jobTTL: 3600000,
|
|
93
|
+
persistence: 'memory'
|
|
94
|
+
},
|
|
95
|
+
registry: {
|
|
96
|
+
enabled: false,
|
|
97
|
+
url: process.env.MCP_REGISTRY_URL || 'https://registry.mcp.run',
|
|
98
|
+
apiKey: process.env.MCP_REGISTRY_API_KEY
|
|
99
|
+
},
|
|
100
|
+
validation: {
|
|
101
|
+
enabled: true,
|
|
102
|
+
strictMode: false
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return extended;
|
|
107
|
+
}
|
|
108
|
+
static validateConfig(config) {
|
|
109
|
+
const errors = [];
|
|
110
|
+
const warnings = [];
|
|
111
|
+
if (!config.transport) {
|
|
112
|
+
errors.push('Transport type is required');
|
|
113
|
+
}
|
|
114
|
+
if (config.features?.enableMCP2025) {
|
|
115
|
+
if (config.features.enableRegistryIntegration && !config.mcp2025?.registry?.apiKey) {
|
|
116
|
+
warnings.push('Registry integration enabled but no API key provided');
|
|
117
|
+
}
|
|
118
|
+
if (config.mcp2025?.async?.persistence === 'redis') {
|
|
119
|
+
warnings.push('Redis persistence not yet implemented, falling back to memory');
|
|
120
|
+
}
|
|
121
|
+
if (config.mcp2025?.async?.persistence === 'sqlite') {
|
|
122
|
+
warnings.push('SQLite persistence not yet implemented, falling back to memory');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (config.transport === 'http') {
|
|
126
|
+
if (!config.host) {
|
|
127
|
+
warnings.push('HTTP transport enabled but no host specified, using default');
|
|
128
|
+
}
|
|
129
|
+
if (!config.port) {
|
|
130
|
+
warnings.push('HTTP transport enabled but no port specified, using default');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
valid: errors.length === 0,
|
|
135
|
+
errors,
|
|
136
|
+
warnings
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export async function createMCPServer(config, eventBus, logger, options) {
|
|
141
|
+
const extendedConfig = options?.autoDetectFeatures ? MCPServerFactory.detectOptimalConfig(config) : config;
|
|
142
|
+
const validation = MCPServerFactory.validateConfig(extendedConfig);
|
|
143
|
+
if (!validation.valid) {
|
|
144
|
+
throw new Error(`Invalid MCP configuration: ${validation.errors.join(', ')}`);
|
|
145
|
+
}
|
|
146
|
+
for (const warning of validation.warnings){
|
|
147
|
+
logger.warn('MCP configuration warning', {
|
|
148
|
+
warning
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return await MCPServerFactory.createServer(extendedConfig, eventBus, logger, options?.orchestrator, options?.swarmCoordinator, options?.agentManager, options?.resourceManager, options?.messagebus, options?.monitor);
|
|
152
|
+
}
|
|
153
|
+
export function isMCP2025Available() {
|
|
154
|
+
try {
|
|
155
|
+
require.resolve('uuid');
|
|
156
|
+
require.resolve('ajv');
|
|
157
|
+
require.resolve('ajv-formats');
|
|
158
|
+
return true;
|
|
159
|
+
} catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export function getServerCapabilities(config) {
|
|
164
|
+
const capabilities = [];
|
|
165
|
+
if (config.features?.enableMCP2025) {
|
|
166
|
+
capabilities.push('mcp-2025-11');
|
|
167
|
+
if (config.features.enableVersionNegotiation) {
|
|
168
|
+
capabilities.push('version-negotiation');
|
|
169
|
+
}
|
|
170
|
+
if (config.features.enableAsyncJobs) {
|
|
171
|
+
capabilities.push('async-jobs');
|
|
172
|
+
}
|
|
173
|
+
if (config.features.enableRegistryIntegration) {
|
|
174
|
+
capabilities.push('registry');
|
|
175
|
+
}
|
|
176
|
+
if (config.features.enableSchemaValidation) {
|
|
177
|
+
capabilities.push('schema-validation');
|
|
178
|
+
}
|
|
179
|
+
if (config.features.enableProgressiveDisclosure) {
|
|
180
|
+
capabilities.push('progressive-disclosure');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (config.features?.supportLegacyClients !== false) {
|
|
184
|
+
capabilities.push('backward-compatible');
|
|
185
|
+
}
|
|
186
|
+
return capabilities;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//# sourceMappingURL=server-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/mcp/server-factory.ts"],"sourcesContent":["/**\n * MCP Server Factory\n *\n * Creates appropriate MCP server instance based on configuration.\n * Provides seamless transition from legacy MCP to MCP 2025-11 with feature flags.\n */\n\nimport type { IEventBus } from '../interfaces/event-bus.js';\nimport type { ILogger } from '../interfaces/logger.js';\nimport type { MCPConfig } from '../utils/types.js';\nimport { MCPServer, type IMCPServer } from './server.js';\nimport { MCP2025Server, type MCP2025ServerConfig } from './server-mcp-2025.js';\nimport { ProgressiveToolRegistry } from './tool-registry-progressive.js';\n\n/**\n * MCP server feature flags for gradual rollout\n */\nexport interface MCPFeatureFlags {\n // Enable MCP 2025-11 features\n enableMCP2025?: boolean;\n\n // Individual feature flags\n enableVersionNegotiation?: boolean;\n enableAsyncJobs?: boolean;\n enableRegistryIntegration?: boolean;\n enableSchemaValidation?: boolean;\n\n // Backward compatibility\n supportLegacyClients?: boolean;\n\n // Progressive disclosure (already implemented in Phase 1)\n enableProgressiveDisclosure?: boolean;\n}\n\n/**\n * Extended MCP configuration with 2025-11 support\n */\nexport interface ExtendedMCPConfig extends MCPConfig {\n // Feature flags\n features?: MCPFeatureFlags;\n\n // MCP 2025-11 specific config\n mcp2025?: {\n serverId?: string;\n\n // Async job configuration\n async?: {\n enabled?: boolean;\n maxJobs?: number;\n jobTTL?: number;\n persistence?: 'memory' | 'redis' | 'sqlite';\n };\n\n // Registry configuration\n registry?: {\n enabled?: boolean;\n url?: string;\n apiKey?: string;\n updateInterval?: number;\n retryAttempts?: number;\n };\n\n // Validation configuration\n validation?: {\n enabled?: boolean;\n strictMode?: boolean;\n };\n\n // Tool discovery\n toolsDirectory?: string;\n };\n}\n\n/**\n * MCP Server Factory\n *\n * Creates appropriate server instance based on configuration:\n * - MCP2025Server if MCP 2025-11 features enabled\n * - Legacy MCPServer for backward compatibility\n */\nexport class MCPServerFactory {\n /**\n * Create MCP server instance based on configuration\n */\n static async createServer(\n config: ExtendedMCPConfig,\n eventBus: IEventBus,\n logger: ILogger,\n orchestrator?: any,\n swarmCoordinator?: any,\n agentManager?: any,\n resourceManager?: any,\n messagebus?: any,\n monitor?: any\n ): Promise<IMCPServer | MCP2025Server> {\n const features = config.features || {};\n\n // Determine if MCP 2025-11 should be enabled\n const useMCP2025 = features.enableMCP2025 === true;\n\n if (useMCP2025) {\n logger.info('Creating MCP 2025-11 server with enhanced features');\n return await this.createMCP2025Server(\n config,\n eventBus,\n logger,\n orchestrator\n );\n } else {\n logger.info('Creating legacy MCP server (backward compatibility mode)');\n return this.createLegacyServer(\n config,\n eventBus,\n logger,\n orchestrator,\n swarmCoordinator,\n agentManager,\n resourceManager,\n messagebus,\n monitor\n );\n }\n }\n\n /**\n * Create MCP 2025-11 server with enhanced features\n */\n private static async createMCP2025Server(\n config: ExtendedMCPConfig,\n eventBus: IEventBus,\n logger: ILogger,\n orchestrator?: any\n ): Promise<MCP2025Server> {\n const features = config.features || {};\n const mcp2025Config = config.mcp2025 || {};\n\n // Build MCP 2025-11 server configuration\n const serverConfig: MCP2025ServerConfig = {\n serverId: mcp2025Config.serverId || `claude-flow-${Date.now()}`,\n transport: config.transport || 'stdio',\n\n // Feature flags\n enableMCP2025: true,\n supportLegacyClients: features.supportLegacyClients !== false, // Default true\n\n // Async jobs\n async: {\n enabled: features.enableAsyncJobs !== false, // Default true\n maxJobs: mcp2025Config.async?.maxJobs || 100,\n jobTTL: mcp2025Config.async?.jobTTL || 3600000, // 1 hour\n persistence: mcp2025Config.async?.persistence || 'memory',\n },\n\n // Registry integration\n registry: {\n enabled: features.enableRegistryIntegration === true,\n url: mcp2025Config.registry?.url || 'https://registry.mcp.run',\n apiKey: mcp2025Config.registry?.apiKey,\n updateInterval: mcp2025Config.registry?.updateInterval || 60000,\n retryAttempts: mcp2025Config.registry?.retryAttempts || 3,\n },\n\n // Schema validation\n validation: {\n enabled: features.enableSchemaValidation !== false, // Default true\n strictMode: mcp2025Config.validation?.strictMode || false,\n },\n\n // Tool registry (progressive disclosure)\n toolsDirectory: mcp2025Config.toolsDirectory,\n orchestratorContext: orchestrator,\n };\n\n // Create and initialize server\n const server = new MCP2025Server(serverConfig, eventBus, logger);\n await server.initialize();\n\n logger.info('MCP 2025-11 server created successfully', {\n serverId: serverConfig.serverId,\n features: {\n versionNegotiation: true,\n asyncJobs: serverConfig.async.enabled,\n registry: serverConfig.registry.enabled,\n validation: serverConfig.validation.enabled,\n progressiveDisclosure: true,\n },\n });\n\n return server;\n }\n\n /**\n * Create legacy MCP server for backward compatibility\n */\n private static createLegacyServer(\n config: ExtendedMCPConfig,\n eventBus: IEventBus,\n logger: ILogger,\n orchestrator?: any,\n swarmCoordinator?: any,\n agentManager?: any,\n resourceManager?: any,\n messagebus?: any,\n monitor?: any\n ): MCPServer {\n // Remove extended properties for legacy server\n const legacyConfig: MCPConfig = {\n transport: config.transport,\n host: config.host,\n port: config.port,\n tlsEnabled: config.tlsEnabled,\n enableMetrics: config.enableMetrics,\n auth: config.auth,\n loadBalancer: config.loadBalancer,\n sessionTimeout: config.sessionTimeout,\n maxSessions: config.maxSessions,\n };\n\n const server = new MCPServer(\n legacyConfig,\n eventBus,\n logger,\n orchestrator,\n swarmCoordinator,\n agentManager,\n resourceManager,\n messagebus,\n monitor\n );\n\n logger.info('Legacy MCP server created successfully', {\n transport: config.transport,\n mode: 'backward-compatibility',\n });\n\n return server;\n }\n\n /**\n * Detect optimal server configuration based on environment\n */\n static detectOptimalConfig(currentConfig: MCPConfig): ExtendedMCPConfig {\n const extended: ExtendedMCPConfig = {\n ...currentConfig,\n features: {\n // Enable MCP 2025-11 by default in development, opt-in for production\n enableMCP2025: process.env.NODE_ENV !== 'production',\n\n // Individual features (can be overridden)\n enableVersionNegotiation: true,\n enableAsyncJobs: true,\n enableRegistryIntegration: false, // Opt-in\n enableSchemaValidation: true,\n supportLegacyClients: true, // Always support legacy\n enableProgressiveDisclosure: true, // Phase 1 feature\n },\n mcp2025: {\n async: {\n enabled: true,\n maxJobs: 100,\n jobTTL: 3600000,\n persistence: 'memory',\n },\n registry: {\n enabled: false,\n url: process.env.MCP_REGISTRY_URL || 'https://registry.mcp.run',\n apiKey: process.env.MCP_REGISTRY_API_KEY,\n },\n validation: {\n enabled: true,\n strictMode: false,\n },\n },\n };\n\n return extended;\n }\n\n /**\n * Validate server configuration\n */\n static validateConfig(config: ExtendedMCPConfig): {\n valid: boolean;\n errors: string[];\n warnings: string[];\n } {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Basic validation\n if (!config.transport) {\n errors.push('Transport type is required');\n }\n\n // MCP 2025-11 specific validation\n if (config.features?.enableMCP2025) {\n if (config.features.enableRegistryIntegration && !config.mcp2025?.registry?.apiKey) {\n warnings.push('Registry integration enabled but no API key provided');\n }\n\n if (config.mcp2025?.async?.persistence === 'redis') {\n warnings.push('Redis persistence not yet implemented, falling back to memory');\n }\n\n if (config.mcp2025?.async?.persistence === 'sqlite') {\n warnings.push('SQLite persistence not yet implemented, falling back to memory');\n }\n }\n\n // Transport validation\n if (config.transport === 'http') {\n if (!config.host) {\n warnings.push('HTTP transport enabled but no host specified, using default');\n }\n if (!config.port) {\n warnings.push('HTTP transport enabled but no port specified, using default');\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n}\n\n/**\n * Convenience function for creating MCP server\n */\nexport async function createMCPServer(\n config: MCPConfig | ExtendedMCPConfig,\n eventBus: IEventBus,\n logger: ILogger,\n options?: {\n orchestrator?: any;\n swarmCoordinator?: any;\n agentManager?: any;\n resourceManager?: any;\n messagebus?: any;\n monitor?: any;\n autoDetectFeatures?: boolean;\n }\n): Promise<IMCPServer | MCP2025Server> {\n // Auto-detect optimal configuration if requested\n const extendedConfig = options?.autoDetectFeatures\n ? MCPServerFactory.detectOptimalConfig(config)\n : (config as ExtendedMCPConfig);\n\n // Validate configuration\n const validation = MCPServerFactory.validateConfig(extendedConfig);\n\n if (!validation.valid) {\n throw new Error(`Invalid MCP configuration: ${validation.errors.join(', ')}`);\n }\n\n // Log warnings\n for (const warning of validation.warnings) {\n logger.warn('MCP configuration warning', { warning });\n }\n\n // Create server\n return await MCPServerFactory.createServer(\n extendedConfig,\n eventBus,\n logger,\n options?.orchestrator,\n options?.swarmCoordinator,\n options?.agentManager,\n options?.resourceManager,\n options?.messagebus,\n options?.monitor\n );\n}\n\n/**\n * Check if MCP 2025-11 features are available\n */\nexport function isMCP2025Available(): boolean {\n try {\n // Check if required dependencies are available\n require.resolve('uuid');\n require.resolve('ajv');\n require.resolve('ajv-formats');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get MCP server capabilities based on configuration\n */\nexport function getServerCapabilities(config: ExtendedMCPConfig): string[] {\n const capabilities: string[] = [];\n\n if (config.features?.enableMCP2025) {\n capabilities.push('mcp-2025-11');\n\n if (config.features.enableVersionNegotiation) {\n capabilities.push('version-negotiation');\n }\n\n if (config.features.enableAsyncJobs) {\n capabilities.push('async-jobs');\n }\n\n if (config.features.enableRegistryIntegration) {\n capabilities.push('registry');\n }\n\n if (config.features.enableSchemaValidation) {\n capabilities.push('schema-validation');\n }\n\n if (config.features.enableProgressiveDisclosure) {\n capabilities.push('progressive-disclosure');\n }\n }\n\n if (config.features?.supportLegacyClients !== false) {\n capabilities.push('backward-compatible');\n }\n\n return capabilities;\n}\n"],"names":["MCPServer","MCP2025Server","MCPServerFactory","createServer","config","eventBus","logger","orchestrator","swarmCoordinator","agentManager","resourceManager","messagebus","monitor","features","useMCP2025","enableMCP2025","info","createMCP2025Server","createLegacyServer","mcp2025Config","mcp2025","serverConfig","serverId","Date","now","transport","supportLegacyClients","async","enabled","enableAsyncJobs","maxJobs","jobTTL","persistence","registry","enableRegistryIntegration","url","apiKey","updateInterval","retryAttempts","validation","enableSchemaValidation","strictMode","toolsDirectory","orchestratorContext","server","initialize","versionNegotiation","asyncJobs","progressiveDisclosure","legacyConfig","host","port","tlsEnabled","enableMetrics","auth","loadBalancer","sessionTimeout","maxSessions","mode","detectOptimalConfig","currentConfig","extended","process","env","NODE_ENV","enableVersionNegotiation","enableProgressiveDisclosure","MCP_REGISTRY_URL","MCP_REGISTRY_API_KEY","validateConfig","errors","warnings","push","valid","length","createMCPServer","options","extendedConfig","autoDetectFeatures","Error","join","warning","warn","isMCP2025Available","require","resolve","getServerCapabilities","capabilities"],"mappings":"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"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { VersionNegotiator, BackwardCompatibilityAdapter } from './protocol/version-negotiation.js';
|
|
2
|
+
import { MCPAsyncJobManager } from './async/job-manager-mcp25.js';
|
|
3
|
+
import { MCPRegistryClient } from './registry/mcp-registry-client-2025.js';
|
|
4
|
+
import { SchemaValidator, upgradeToolSchema } from './validation/schema-validator-2025.js';
|
|
5
|
+
import { ProgressiveToolRegistry } from './tool-registry-progressive.js';
|
|
6
|
+
export class MCP2025Server {
|
|
7
|
+
config;
|
|
8
|
+
eventBus;
|
|
9
|
+
logger;
|
|
10
|
+
versionNegotiator;
|
|
11
|
+
compatibilityAdapter;
|
|
12
|
+
jobManager;
|
|
13
|
+
registryClient;
|
|
14
|
+
schemaValidator;
|
|
15
|
+
toolRegistry;
|
|
16
|
+
sessions = new Map();
|
|
17
|
+
MAX_SESSIONS = 10000;
|
|
18
|
+
SESSION_TTL = 3600000;
|
|
19
|
+
sessionCleanupInterval;
|
|
20
|
+
constructor(config, eventBus, logger){
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.eventBus = eventBus;
|
|
23
|
+
this.logger = logger;
|
|
24
|
+
this.versionNegotiator = new VersionNegotiator(logger);
|
|
25
|
+
this.compatibilityAdapter = new BackwardCompatibilityAdapter(logger);
|
|
26
|
+
this.schemaValidator = new SchemaValidator(logger);
|
|
27
|
+
this.toolRegistry = new ProgressiveToolRegistry({
|
|
28
|
+
enableInProcess: true,
|
|
29
|
+
enableMetrics: true,
|
|
30
|
+
enableCaching: true,
|
|
31
|
+
orchestratorContext: config.orchestratorContext,
|
|
32
|
+
toolsDirectory: config.toolsDirectory
|
|
33
|
+
});
|
|
34
|
+
this.logger.info('MCP 2025-11 server created', {
|
|
35
|
+
serverId: config.serverId,
|
|
36
|
+
mcp2025Enabled: config.enableMCP2025,
|
|
37
|
+
legacySupport: config.supportLegacyClients
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async initialize() {
|
|
41
|
+
this.logger.info('Initializing MCP 2025-11 server');
|
|
42
|
+
await this.toolRegistry.initialize();
|
|
43
|
+
this.sessionCleanupInterval = setInterval(()=>this.cleanupExpiredSessions(), 300000);
|
|
44
|
+
if (this.config.async.enabled) {
|
|
45
|
+
this.jobManager = new MCPAsyncJobManager(null, this.logger, {
|
|
46
|
+
maxJobs: this.config.async.maxJobs,
|
|
47
|
+
jobTTL: this.config.async.jobTTL
|
|
48
|
+
});
|
|
49
|
+
this.logger.info('Async job manager initialized');
|
|
50
|
+
}
|
|
51
|
+
if (this.config.registry.enabled) {
|
|
52
|
+
this.registryClient = new MCPRegistryClient(this.config.registry, this.logger, ()=>this.toolRegistry.getToolNames(), ()=>this.versionNegotiator.getServerCapabilities(), async ()=>this.getHealthStatus());
|
|
53
|
+
try {
|
|
54
|
+
await this.registryClient.register();
|
|
55
|
+
} catch (error) {
|
|
56
|
+
this.logger.error('Failed to register with MCP Registry', {
|
|
57
|
+
error
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
this.logger.info('MCP 2025-11 server initialized successfully');
|
|
62
|
+
}
|
|
63
|
+
async handleHandshake(clientHandshake, sessionId) {
|
|
64
|
+
const isLegacy = this.compatibilityAdapter.isLegacyRequest(clientHandshake);
|
|
65
|
+
let handshake;
|
|
66
|
+
if (isLegacy && this.config.supportLegacyClients) {
|
|
67
|
+
this.logger.info('Legacy client detected, enabling compatibility mode', {
|
|
68
|
+
sessionId
|
|
69
|
+
});
|
|
70
|
+
handshake = this.compatibilityAdapter.convertToModern(clientHandshake);
|
|
71
|
+
} else {
|
|
72
|
+
handshake = clientHandshake;
|
|
73
|
+
}
|
|
74
|
+
const negotiation = await this.versionNegotiator.negotiate(handshake);
|
|
75
|
+
if (!negotiation.success) {
|
|
76
|
+
throw new Error(`Version negotiation failed: ${negotiation.error}`);
|
|
77
|
+
}
|
|
78
|
+
if (this.sessions.size >= this.MAX_SESSIONS) {
|
|
79
|
+
const oldestSession = Array.from(this.sessions.entries()).sort((a, b)=>a[1].createdAt - b[1].createdAt)[0];
|
|
80
|
+
if (oldestSession) {
|
|
81
|
+
this.sessions.delete(oldestSession[0]);
|
|
82
|
+
this.logger.warn('Session limit reached, removed oldest session', {
|
|
83
|
+
removedSessionId: oldestSession[0]
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const now = Date.now();
|
|
88
|
+
this.sessions.set(sessionId, {
|
|
89
|
+
clientId: handshake.client_id || 'unknown',
|
|
90
|
+
version: negotiation.agreed_version,
|
|
91
|
+
capabilities: negotiation.agreed_capabilities,
|
|
92
|
+
isLegacy,
|
|
93
|
+
createdAt: now,
|
|
94
|
+
lastAccess: now
|
|
95
|
+
});
|
|
96
|
+
const serverHandshake = this.versionNegotiator.createServerHandshake(this.config.serverId, this.config.transport, {
|
|
97
|
+
name: 'Claude Flow',
|
|
98
|
+
version: '2.7.32',
|
|
99
|
+
description: 'Enterprise AI orchestration with MCP 2025-11 support'
|
|
100
|
+
});
|
|
101
|
+
serverHandshake.mcp_version = negotiation.agreed_version;
|
|
102
|
+
serverHandshake.capabilities = negotiation.agreed_capabilities;
|
|
103
|
+
this.logger.info('Handshake completed', {
|
|
104
|
+
sessionId,
|
|
105
|
+
version: serverHandshake.mcp_version,
|
|
106
|
+
capabilities: serverHandshake.capabilities,
|
|
107
|
+
isLegacy
|
|
108
|
+
});
|
|
109
|
+
return serverHandshake;
|
|
110
|
+
}
|
|
111
|
+
async handleToolCall(request, sessionId) {
|
|
112
|
+
const session = this.sessions.get(sessionId);
|
|
113
|
+
if (session) {
|
|
114
|
+
session.lastAccess = Date.now();
|
|
115
|
+
}
|
|
116
|
+
if (session?.isLegacy) {
|
|
117
|
+
return this.handleLegacyToolCall(request, sessionId);
|
|
118
|
+
}
|
|
119
|
+
const mcpRequest = request;
|
|
120
|
+
if (!mcpRequest.tool_id) {
|
|
121
|
+
throw new Error('Missing tool_id in request');
|
|
122
|
+
}
|
|
123
|
+
const tool = await this.toolRegistry.getTool(mcpRequest.tool_id);
|
|
124
|
+
if (!tool) {
|
|
125
|
+
throw new Error(`Tool not found: ${mcpRequest.tool_id}`);
|
|
126
|
+
}
|
|
127
|
+
if (this.config.validation.enabled) {
|
|
128
|
+
const validation = this.schemaValidator.validateInput(upgradeToolSchema(tool.inputSchema), mcpRequest.arguments);
|
|
129
|
+
if (!validation.valid) {
|
|
130
|
+
throw new Error(`Invalid input: ${validation.errors?.map((e)=>e.message).join(', ')}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const hasAsyncCapability = session?.capabilities.includes('async');
|
|
134
|
+
const isAsyncRequest = mcpRequest.mode === 'async' && hasAsyncCapability;
|
|
135
|
+
if (isAsyncRequest && this.jobManager) {
|
|
136
|
+
this.logger.info('Submitting async job', {
|
|
137
|
+
tool_id: mcpRequest.tool_id,
|
|
138
|
+
request_id: mcpRequest.request_id
|
|
139
|
+
});
|
|
140
|
+
return await this.jobManager.submitJob(mcpRequest, async (args, onProgress)=>{
|
|
141
|
+
return await tool.handler(args, {
|
|
142
|
+
orchestrator: this.config.orchestratorContext,
|
|
143
|
+
sessionId
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
this.logger.info('Executing tool synchronously', {
|
|
148
|
+
tool_id: mcpRequest.tool_id,
|
|
149
|
+
request_id: mcpRequest.request_id
|
|
150
|
+
});
|
|
151
|
+
const startTime = Date.now();
|
|
152
|
+
const result = await tool.handler(mcpRequest.arguments, {
|
|
153
|
+
orchestrator: this.config.orchestratorContext,
|
|
154
|
+
sessionId
|
|
155
|
+
});
|
|
156
|
+
if (this.config.validation.enabled && tool.metadata?.outputSchema) {
|
|
157
|
+
const validation = this.schemaValidator.validateOutput(tool.metadata.outputSchema, result);
|
|
158
|
+
if (!validation.valid) {
|
|
159
|
+
this.logger.warn('Output validation failed', {
|
|
160
|
+
tool_id: mcpRequest.tool_id,
|
|
161
|
+
errors: validation.errors
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
request_id: mcpRequest.request_id,
|
|
167
|
+
status: 'success',
|
|
168
|
+
result,
|
|
169
|
+
metadata: {
|
|
170
|
+
duration_ms: Date.now() - startTime
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async handleLegacyToolCall(request, sessionId) {
|
|
176
|
+
this.logger.info('Handling legacy tool call', {
|
|
177
|
+
toolName: request.name || request.method,
|
|
178
|
+
sessionId
|
|
179
|
+
});
|
|
180
|
+
const toolId = request.name || request.method;
|
|
181
|
+
const args = request.arguments || request.params || {};
|
|
182
|
+
const tool = await this.toolRegistry.getTool(toolId);
|
|
183
|
+
if (!tool) {
|
|
184
|
+
throw new Error(`Tool not found: ${toolId}`);
|
|
185
|
+
}
|
|
186
|
+
const result = await tool.handler(args, {
|
|
187
|
+
orchestrator: this.config.orchestratorContext,
|
|
188
|
+
sessionId
|
|
189
|
+
});
|
|
190
|
+
return this.compatibilityAdapter.convertToLegacy({
|
|
191
|
+
result,
|
|
192
|
+
status: 'success'
|
|
193
|
+
}, true);
|
|
194
|
+
}
|
|
195
|
+
async pollJob(job_id) {
|
|
196
|
+
if (!this.jobManager) {
|
|
197
|
+
throw new Error('Async jobs not enabled');
|
|
198
|
+
}
|
|
199
|
+
return await this.jobManager.pollJob(job_id);
|
|
200
|
+
}
|
|
201
|
+
async resumeJob(job_id) {
|
|
202
|
+
if (!this.jobManager) {
|
|
203
|
+
throw new Error('Async jobs not enabled');
|
|
204
|
+
}
|
|
205
|
+
return await this.jobManager.resumeJob(job_id);
|
|
206
|
+
}
|
|
207
|
+
async cancelJob(job_id) {
|
|
208
|
+
if (!this.jobManager) {
|
|
209
|
+
throw new Error('Async jobs not enabled');
|
|
210
|
+
}
|
|
211
|
+
return await this.jobManager.cancelJob(job_id);
|
|
212
|
+
}
|
|
213
|
+
async listJobs(filter) {
|
|
214
|
+
if (!this.jobManager) {
|
|
215
|
+
throw new Error('Async jobs not enabled');
|
|
216
|
+
}
|
|
217
|
+
return await this.jobManager.listJobs(filter);
|
|
218
|
+
}
|
|
219
|
+
async getHealthStatus() {
|
|
220
|
+
const startTime = Date.now();
|
|
221
|
+
const latency = Date.now() - startTime;
|
|
222
|
+
let status = 'healthy';
|
|
223
|
+
if (latency > 100) {
|
|
224
|
+
status = 'degraded';
|
|
225
|
+
}
|
|
226
|
+
if (latency > 500) {
|
|
227
|
+
status = 'unhealthy';
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
status,
|
|
231
|
+
latency_ms: latency
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
getMetrics() {
|
|
235
|
+
return {
|
|
236
|
+
sessions: {
|
|
237
|
+
total: this.sessions.size,
|
|
238
|
+
byVersion: this.getSessionsByVersion(),
|
|
239
|
+
legacy: Array.from(this.sessions.values()).filter((s)=>s.isLegacy).length
|
|
240
|
+
},
|
|
241
|
+
jobs: this.jobManager?.getMetrics(),
|
|
242
|
+
tools: this.toolRegistry.getMetrics(),
|
|
243
|
+
validation: this.schemaValidator.getCacheStats()
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
getSessionsByVersion() {
|
|
247
|
+
const counts = {};
|
|
248
|
+
for (const session of this.sessions.values()){
|
|
249
|
+
counts[session.version] = (counts[session.version] || 0) + 1;
|
|
250
|
+
}
|
|
251
|
+
return counts;
|
|
252
|
+
}
|
|
253
|
+
cleanupExpiredSessions() {
|
|
254
|
+
const now = Date.now();
|
|
255
|
+
let cleaned = 0;
|
|
256
|
+
for (const [sessionId, session] of this.sessions.entries()){
|
|
257
|
+
if (now - session.lastAccess > this.SESSION_TTL) {
|
|
258
|
+
this.sessions.delete(sessionId);
|
|
259
|
+
cleaned++;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (cleaned > 0) {
|
|
263
|
+
this.logger.info('Cleaned up expired sessions', {
|
|
264
|
+
count: cleaned
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async cleanup() {
|
|
269
|
+
this.logger.info('Cleaning up MCP 2025-11 server');
|
|
270
|
+
if (this.sessionCleanupInterval) {
|
|
271
|
+
clearInterval(this.sessionCleanupInterval);
|
|
272
|
+
}
|
|
273
|
+
if (this.registryClient) {
|
|
274
|
+
await this.registryClient.unregister();
|
|
275
|
+
}
|
|
276
|
+
this.schemaValidator.clearCache();
|
|
277
|
+
await this.toolRegistry.cleanup();
|
|
278
|
+
this.sessions.clear();
|
|
279
|
+
this.logger.info('Cleanup complete');
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
//# sourceMappingURL=server-mcp-2025.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/mcp/server-mcp-2025.ts"],"sourcesContent":["/**\n * MCP 2025-11 Enhanced Server\n *\n * Integrates all MCP 2025-11 features with full backward compatibility:\n * - Version negotiation\n * - Async job support\n * - Registry integration\n * - JSON Schema 1.1 validation\n * - Dual-mode operation (2025-11 + legacy)\n */\n\nimport type { ILogger } from '../interfaces/logger.js';\nimport type { IEventBus } from '../interfaces/event-bus.js';\nimport { VersionNegotiator, BackwardCompatibilityAdapter, type MCPHandshake, type MCPVersion, type MCPCapability } from './protocol/version-negotiation.js';\nimport { MCPAsyncJobManager, type MCPToolRequest, type MCPJobHandle, type MCPJobResult } from './async/job-manager-mcp25.js';\nimport { MCPRegistryClient, type RegistryConfig } from './registry/mcp-registry-client-2025.js';\nimport { SchemaValidator, upgradeToolSchema } from './validation/schema-validator-2025.js';\nimport { ProgressiveToolRegistry } from './tool-registry-progressive.js';\n\n/**\n * MCP 2025-11 server configuration\n */\nexport interface MCP2025ServerConfig {\n serverId: string;\n transport: 'stdio' | 'http' | 'ws';\n\n // Version & capabilities\n enableMCP2025: boolean; // Feature flag for gradual rollout\n supportLegacyClients: boolean; // Backward compatibility\n\n // Async jobs\n async: {\n enabled: boolean;\n maxJobs?: number;\n jobTTL?: number;\n persistence?: 'memory' | 'redis' | 'sqlite';\n };\n\n // Registry\n registry: RegistryConfig;\n\n // Schema validation\n validation: {\n enabled: boolean;\n strictMode?: boolean;\n };\n\n // Tool registry\n toolsDirectory?: string;\n\n // Existing config\n orchestratorContext?: any;\n}\n\n/**\n * MCP 2025-11 Enhanced Server\n */\nexport class MCP2025Server {\n private versionNegotiator: VersionNegotiator;\n private compatibilityAdapter: BackwardCompatibilityAdapter;\n private jobManager?: MCPAsyncJobManager;\n private registryClient?: MCPRegistryClient;\n private schemaValidator: SchemaValidator;\n private toolRegistry: ProgressiveToolRegistry;\n\n // Session state\n private sessions: Map<string, {\n clientId: string;\n version: MCPVersion;\n capabilities: MCPCapability[];\n isLegacy: boolean;\n createdAt: number;\n lastAccess: number;\n }> = new Map();\n\n // Session management constants\n private readonly MAX_SESSIONS = 10000;\n private readonly SESSION_TTL = 3600000; // 1 hour\n private sessionCleanupInterval?: NodeJS.Timeout;\n\n constructor(\n private config: MCP2025ServerConfig,\n private eventBus: IEventBus,\n private logger: ILogger\n ) {\n // Initialize version negotiation\n this.versionNegotiator = new VersionNegotiator(logger);\n this.compatibilityAdapter = new BackwardCompatibilityAdapter(logger);\n\n // Initialize schema validator\n this.schemaValidator = new SchemaValidator(logger);\n\n // Initialize tool registry (progressive)\n this.toolRegistry = new ProgressiveToolRegistry({\n enableInProcess: true,\n enableMetrics: true,\n enableCaching: true,\n orchestratorContext: config.orchestratorContext,\n toolsDirectory: config.toolsDirectory,\n });\n\n this.logger.info('MCP 2025-11 server created', {\n serverId: config.serverId,\n mcp2025Enabled: config.enableMCP2025,\n legacySupport: config.supportLegacyClients,\n });\n }\n\n /**\n * Initialize server\n */\n async initialize(): Promise<void> {\n this.logger.info('Initializing MCP 2025-11 server');\n\n // Initialize tool registry\n await this.toolRegistry.initialize();\n\n // Start session cleanup interval\n this.sessionCleanupInterval = setInterval(\n () => this.cleanupExpiredSessions(),\n 300000 // Every 5 minutes\n );\n\n // Initialize async job manager if enabled\n if (this.config.async.enabled) {\n this.jobManager = new MCPAsyncJobManager(\n null, // Use memory persistence for now\n this.logger,\n {\n maxJobs: this.config.async.maxJobs,\n jobTTL: this.config.async.jobTTL,\n }\n );\n\n this.logger.info('Async job manager initialized');\n }\n\n // Initialize registry client if enabled\n if (this.config.registry.enabled) {\n this.registryClient = new MCPRegistryClient(\n this.config.registry,\n this.logger,\n () => this.toolRegistry.getToolNames(),\n () => this.versionNegotiator.getServerCapabilities(),\n async () => this.getHealthStatus()\n );\n\n // Register with MCP Registry\n try {\n await this.registryClient.register();\n } catch (error) {\n this.logger.error('Failed to register with MCP Registry', { error });\n // Don't fail initialization if registry is unavailable\n }\n }\n\n this.logger.info('MCP 2025-11 server initialized successfully');\n }\n\n /**\n * Handle client connection/handshake\n */\n async handleHandshake(clientHandshake: any, sessionId: string): Promise<MCPHandshake> {\n // Check if legacy client\n const isLegacy = this.compatibilityAdapter.isLegacyRequest(clientHandshake);\n\n let handshake: MCPHandshake;\n if (isLegacy && this.config.supportLegacyClients) {\n this.logger.info('Legacy client detected, enabling compatibility mode', { sessionId });\n handshake = this.compatibilityAdapter.convertToModern(clientHandshake);\n } else {\n handshake = clientHandshake;\n }\n\n // Negotiate version and capabilities\n const negotiation = await this.versionNegotiator.negotiate(handshake);\n\n if (!negotiation.success) {\n throw new Error(`Version negotiation failed: ${negotiation.error}`);\n }\n\n // Enforce session limit\n if (this.sessions.size >= this.MAX_SESSIONS) {\n // Remove oldest session\n const oldestSession = Array.from(this.sessions.entries())\n .sort((a, b) => a[1].createdAt - b[1].createdAt)[0];\n if (oldestSession) {\n this.sessions.delete(oldestSession[0]);\n this.logger.warn('Session limit reached, removed oldest session', {\n removedSessionId: oldestSession[0],\n });\n }\n }\n\n // Store session info\n const now = Date.now();\n this.sessions.set(sessionId, {\n clientId: handshake.client_id || 'unknown',\n version: negotiation.agreed_version,\n capabilities: negotiation.agreed_capabilities,\n isLegacy,\n createdAt: now,\n lastAccess: now,\n });\n\n // Create server handshake response\n const serverHandshake = this.versionNegotiator.createServerHandshake(\n this.config.serverId,\n this.config.transport,\n {\n name: 'Claude Flow',\n version: '2.7.32',\n description: 'Enterprise AI orchestration with MCP 2025-11 support',\n }\n );\n\n // Apply agreed version and capabilities\n serverHandshake.mcp_version = negotiation.agreed_version;\n serverHandshake.capabilities = negotiation.agreed_capabilities;\n\n this.logger.info('Handshake completed', {\n sessionId,\n version: serverHandshake.mcp_version,\n capabilities: serverHandshake.capabilities,\n isLegacy,\n });\n\n return serverHandshake;\n }\n\n /**\n * Handle tool call request (with async support)\n */\n async handleToolCall(\n request: MCPToolRequest | any,\n sessionId: string\n ): Promise<MCPJobHandle | MCPJobResult | any> {\n const session = this.sessions.get(sessionId);\n\n // Update last access time\n if (session) {\n session.lastAccess = Date.now();\n }\n\n // Handle legacy request format\n if (session?.isLegacy) {\n return this.handleLegacyToolCall(request, sessionId);\n }\n\n // MCP 2025-11 format\n const mcpRequest = request as MCPToolRequest;\n\n // Validate request\n if (!mcpRequest.tool_id) {\n throw new Error('Missing tool_id in request');\n }\n\n // Get tool\n const tool = await this.toolRegistry.getTool(mcpRequest.tool_id);\n if (!tool) {\n throw new Error(`Tool not found: ${mcpRequest.tool_id}`);\n }\n\n // Validate input if validation enabled\n if (this.config.validation.enabled) {\n const validation = this.schemaValidator.validateInput(\n upgradeToolSchema(tool.inputSchema),\n mcpRequest.arguments\n );\n\n if (!validation.valid) {\n throw new Error(\n `Invalid input: ${validation.errors?.map(e => e.message).join(', ')}`\n );\n }\n }\n\n // Check if async mode requested\n const hasAsyncCapability = session?.capabilities.includes('async');\n const isAsyncRequest = mcpRequest.mode === 'async' && hasAsyncCapability;\n\n if (isAsyncRequest && this.jobManager) {\n // Submit as async job\n this.logger.info('Submitting async job', {\n tool_id: mcpRequest.tool_id,\n request_id: mcpRequest.request_id,\n });\n\n return await this.jobManager.submitJob(\n mcpRequest,\n async (args, onProgress) => {\n // Execute tool with progress tracking\n return await tool.handler(args, {\n orchestrator: this.config.orchestratorContext,\n sessionId,\n });\n }\n );\n } else {\n // Execute synchronously\n this.logger.info('Executing tool synchronously', {\n tool_id: mcpRequest.tool_id,\n request_id: mcpRequest.request_id,\n });\n\n const startTime = Date.now();\n const result = await tool.handler(mcpRequest.arguments, {\n orchestrator: this.config.orchestratorContext,\n sessionId,\n });\n\n // Validate output if validation enabled\n if (this.config.validation.enabled && tool.metadata?.outputSchema) {\n const validation = this.schemaValidator.validateOutput(\n tool.metadata.outputSchema,\n result\n );\n\n if (!validation.valid) {\n this.logger.warn('Output validation failed', {\n tool_id: mcpRequest.tool_id,\n errors: validation.errors,\n });\n }\n }\n\n // Return in MCP 2025-11 format\n return {\n request_id: mcpRequest.request_id,\n status: 'success',\n result,\n metadata: {\n duration_ms: Date.now() - startTime,\n },\n } as MCPJobResult;\n }\n }\n\n /**\n * Handle legacy tool call\n */\n private async handleLegacyToolCall(request: any, sessionId: string): Promise<any> {\n this.logger.info('Handling legacy tool call', {\n toolName: request.name || request.method,\n sessionId,\n });\n\n // Convert to modern format internally\n const toolId = request.name || request.method;\n const args = request.arguments || request.params || {};\n\n const tool = await this.toolRegistry.getTool(toolId);\n if (!tool) {\n throw new Error(`Tool not found: ${toolId}`);\n }\n\n const result = await tool.handler(args, {\n orchestrator: this.config.orchestratorContext,\n sessionId,\n });\n\n // Return in legacy format\n return this.compatibilityAdapter.convertToLegacy(\n { result, status: 'success' },\n true\n );\n }\n\n /**\n * Poll async job\n */\n async pollJob(job_id: string): Promise<MCPJobHandle> {\n if (!this.jobManager) {\n throw new Error('Async jobs not enabled');\n }\n\n return await this.jobManager.pollJob(job_id);\n }\n\n /**\n * Resume async job (get results)\n */\n async resumeJob(job_id: string): Promise<MCPJobResult> {\n if (!this.jobManager) {\n throw new Error('Async jobs not enabled');\n }\n\n return await this.jobManager.resumeJob(job_id);\n }\n\n /**\n * Cancel async job\n */\n async cancelJob(job_id: string): Promise<boolean> {\n if (!this.jobManager) {\n throw new Error('Async jobs not enabled');\n }\n\n return await this.jobManager.cancelJob(job_id);\n }\n\n /**\n * List async jobs\n */\n async listJobs(filter?: { status?: string; limit?: number }) {\n if (!this.jobManager) {\n throw new Error('Async jobs not enabled');\n }\n\n return await this.jobManager.listJobs(filter);\n }\n\n /**\n * Get health status\n */\n private async getHealthStatus(): Promise<{\n status: 'healthy' | 'degraded' | 'unhealthy';\n latency_ms: number;\n }> {\n const startTime = Date.now();\n\n // Perform health checks\n const latency = Date.now() - startTime;\n\n // Determine status based on metrics\n let status: 'healthy' | 'degraded' | 'unhealthy' = 'healthy';\n\n if (latency > 100) {\n status = 'degraded';\n }\n if (latency > 500) {\n status = 'unhealthy';\n }\n\n return { status, latency_ms: latency };\n }\n\n /**\n * Get metrics\n */\n getMetrics() {\n return {\n sessions: {\n total: this.sessions.size,\n byVersion: this.getSessionsByVersion(),\n legacy: Array.from(this.sessions.values()).filter(s => s.isLegacy).length,\n },\n jobs: this.jobManager?.getMetrics(),\n tools: this.toolRegistry.getMetrics(),\n validation: this.schemaValidator.getCacheStats(),\n };\n }\n\n private getSessionsByVersion() {\n const counts: Record<string, number> = {};\n for (const session of this.sessions.values()) {\n counts[session.version] = (counts[session.version] || 0) + 1;\n }\n return counts;\n }\n\n /**\n * Cleanup expired sessions\n */\n private cleanupExpiredSessions(): void {\n const now = Date.now();\n let cleaned = 0;\n\n for (const [sessionId, session] of this.sessions.entries()) {\n // Remove if last access was more than TTL ago\n if (now - session.lastAccess > this.SESSION_TTL) {\n this.sessions.delete(sessionId);\n cleaned++;\n }\n }\n\n if (cleaned > 0) {\n this.logger.info('Cleaned up expired sessions', { count: cleaned });\n }\n }\n\n /**\n * Cleanup resources\n */\n async cleanup(): Promise<void> {\n this.logger.info('Cleaning up MCP 2025-11 server');\n\n // Stop session cleanup interval\n if (this.sessionCleanupInterval) {\n clearInterval(this.sessionCleanupInterval);\n }\n\n // Unregister from registry\n if (this.registryClient) {\n await this.registryClient.unregister();\n }\n\n // Clear caches\n this.schemaValidator.clearCache();\n await this.toolRegistry.cleanup();\n\n // Clear sessions\n this.sessions.clear();\n\n this.logger.info('Cleanup complete');\n }\n}\n"],"names":["VersionNegotiator","BackwardCompatibilityAdapter","MCPAsyncJobManager","MCPRegistryClient","SchemaValidator","upgradeToolSchema","ProgressiveToolRegistry","MCP2025Server","versionNegotiator","compatibilityAdapter","jobManager","registryClient","schemaValidator","toolRegistry","sessions","Map","MAX_SESSIONS","SESSION_TTL","sessionCleanupInterval","config","eventBus","logger","enableInProcess","enableMetrics","enableCaching","orchestratorContext","toolsDirectory","info","serverId","mcp2025Enabled","enableMCP2025","legacySupport","supportLegacyClients","initialize","setInterval","cleanupExpiredSessions","async","enabled","maxJobs","jobTTL","registry","getToolNames","getServerCapabilities","getHealthStatus","register","error","handleHandshake","clientHandshake","sessionId","isLegacy","isLegacyRequest","handshake","convertToModern","negotiation","negotiate","success","Error","size","oldestSession","Array","from","entries","sort","a","b","createdAt","delete","warn","removedSessionId","now","Date","set","clientId","client_id","version","agreed_version","capabilities","agreed_capabilities","lastAccess","serverHandshake","createServerHandshake","transport","name","description","mcp_version","handleToolCall","request","session","get","handleLegacyToolCall","mcpRequest","tool_id","tool","getTool","validation","validateInput","inputSchema","arguments","valid","errors","map","e","message","join","hasAsyncCapability","includes","isAsyncRequest","mode","request_id","submitJob","args","onProgress","handler","orchestrator","startTime","result","metadata","outputSchema","validateOutput","status","duration_ms","toolName","method","toolId","params","convertToLegacy","pollJob","job_id","resumeJob","cancelJob","listJobs","filter","latency","latency_ms","getMetrics","total","byVersion","getSessionsByVersion","legacy","values","s","length","jobs","tools","getCacheStats","counts","cleaned","count","cleanup","clearInterval","unregister","clearCache","clear"],"mappings":"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"}
|