claude-flow 2.7.32 → 2.7.34
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 +645 -0
- package/CHANGELOG.md +75 -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/help-formatter.js +5 -3
- package/dist/src/cli/help-formatter.js.map +1 -1
- package/dist/src/cli/simple-cli.js +173 -79
- package/dist/src/cli/simple-cli.js.map +1 -1
- package/dist/src/cli/validation-helper.js.map +1 -1
- package/dist/src/core/version.js +2 -2
- package/dist/src/core/version.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/memory/swarm-memory.js +340 -421
- package/dist/src/memory/swarm-memory.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/BRANCH_REVIEW_SUMMARY.md +439 -0
- package/docs/DEEP_CODE_REVIEW_v2.7.33.md +1159 -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/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/package.json +5 -1
- package/src/cli/commands/mcp.ts +86 -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/docs/AGENTDB_V1.6.1_DEEP_REVIEW.md +0 -386
- package/docs/RECENT_RELEASES_SUMMARY.md +0 -375
- package/docs/V2.7.31_RELEASE_NOTES.md +0 -375
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/validation-helper.
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/validation-helper.ts"],"sourcesContent":["/**\n * CLI Parameter Validation Helper\n * Provides standardized error messages for invalid parameters\n */\n\nimport { HelpFormatter } from './help-formatter.js';\n\nexport class ValidationHelper {\n /**\n * Validate enum parameter\n */\n static validateEnum(\n value: string,\n paramName: string,\n validOptions: string[],\n commandPath: string,\n ): void {\n if (!validOptions.includes(value)) {\n console.error(\n HelpFormatter.formatValidationError(value, paramName, validOptions, commandPath),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate numeric parameter\n */\n static validateNumber(\n value: string,\n paramName: string,\n min?: number,\n max?: number,\n commandPath?: string,\n ): number {\n const num = parseInt(value, 10);\n\n if (isNaN(num)) {\n console.error(\n HelpFormatter.formatError(\n `'${value}' is not a valid number for ${paramName}.`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n if (min !== undefined && num < min) {\n console.error(\n HelpFormatter.formatError(\n `${paramName} must be at least ${min}. Got: ${num}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n if (max !== undefined && num > max) {\n console.error(\n HelpFormatter.formatError(\n `${paramName} must be at most ${max}. Got: ${num}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n return num;\n }\n\n /**\n * Validate required parameter\n */\n static validateRequired(value: any, paramName: string, commandPath?: string): void {\n if (!value || (typeof value === 'string' && value.trim() === '')) {\n console.error(\n HelpFormatter.formatError(\n `Missing required parameter: ${paramName}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate file path exists\n */\n static async validateFilePath(\n path: string,\n paramName: string,\n commandPath?: string,\n ): Promise<void> {\n try {\n const fs = await import('fs/promises');\n await fs.access(path);\n } catch (error) {\n console.error(\n HelpFormatter.formatError(\n `File not found for ${paramName}: ${path}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate boolean flag\n */\n static validateBoolean(value: string, paramName: string, commandPath?: string): boolean {\n const lowerValue = value.toLowerCase();\n if (lowerValue === 'true' || lowerValue === '1' || lowerValue === 'yes') {\n return true;\n }\n if (lowerValue === 'false' || lowerValue === '0' || lowerValue === 'no') {\n return false;\n }\n\n console.error(\n HelpFormatter.formatError(\n `'${value}' is not a valid boolean for ${paramName}. Use: true, false, yes, no, 1, or 0.`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n}\n"],"names":["HelpFormatter","ValidationHelper","validateEnum","value","paramName","validOptions","commandPath","includes","console","error","formatValidationError","process","exit","validateNumber","min","max","num","parseInt","isNaN","formatError","undefined","validateRequired","trim","validateFilePath","path","fs","access","validateBoolean","lowerValue","toLowerCase"],"mappings":"AAKA,SAASA,aAAa,QAAQ,sBAAsB;AAEpD,OAAO,MAAMC;IAIX,OAAOC,aACLC,KAAa,EACbC,SAAiB,EACjBC,YAAsB,EACtBC,WAAmB,EACb;QACN,IAAI,CAACD,aAAaE,QAAQ,CAACJ,QAAQ;YACjCK,QAAQC,KAAK,CACXT,cAAcU,qBAAqB,CAACP,OAAOC,WAAWC,cAAcC;YAEtEK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,OAAOC,eACLV,KAAa,EACbC,SAAiB,EACjBU,GAAY,EACZC,GAAY,EACZT,WAAoB,EACZ;QACR,MAAMU,MAAMC,SAASd,OAAO;QAE5B,IAAIe,MAAMF,MAAM;YACdR,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,4BAA4B,EAAEC,UAAU,CAAC,CAAC,EACpDE,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIE,QAAQM,aAAaJ,MAAMF,KAAK;YAClCN,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,GAAGf,UAAU,kBAAkB,EAAEU,IAAI,OAAO,EAAEE,KAAK,EACnDV,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIG,QAAQK,aAAaJ,MAAMD,KAAK;YAClCP,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,GAAGf,UAAU,iBAAiB,EAAEW,IAAI,OAAO,EAAEC,KAAK,EAClDV,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,OAAOI;IACT;IAKA,OAAOK,iBAAiBlB,KAAU,EAAEC,SAAiB,EAAEE,WAAoB,EAAQ;QACjF,IAAI,CAACH,SAAU,OAAOA,UAAU,YAAYA,MAAMmB,IAAI,OAAO,IAAK;YAChEd,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,4BAA4B,EAAEf,WAAW,EAC1CE,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,aAAaW,iBACXC,IAAY,EACZpB,SAAiB,EACjBE,WAAoB,EACL;QACf,IAAI;YACF,MAAMmB,KAAK,MAAM,MAAM,CAAC;YACxB,MAAMA,GAAGC,MAAM,CAACF;QAClB,EAAE,OAAOf,OAAO;YACdD,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,mBAAmB,EAAEf,UAAU,EAAE,EAAEoB,MAAM,EAC1ClB,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,OAAOe,gBAAgBxB,KAAa,EAAEC,SAAiB,EAAEE,WAAoB,EAAW;QACtF,MAAMsB,aAAazB,MAAM0B,WAAW;QACpC,IAAID,eAAe,UAAUA,eAAe,OAAOA,eAAe,OAAO;YACvE,OAAO;QACT;QACA,IAAIA,eAAe,WAAWA,eAAe,OAAOA,eAAe,MAAM;YACvE,OAAO;QACT;QAEApB,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,6BAA6B,EAAEC,UAAU,qCAAqC,CAAC,EACzFE,eAAe;QAGnBK,QAAQC,IAAI,CAAC;IACf;AACF"}
|
package/dist/src/core/version.js
CHANGED
|
@@ -12,7 +12,7 @@ try {
|
|
|
12
12
|
BUILD_DATE = new Date().toISOString().split('T')[0];
|
|
13
13
|
} catch (error) {
|
|
14
14
|
console.warn('Warning: Could not read version from package.json, using fallback');
|
|
15
|
-
VERSION = '2.0.0-alpha.
|
|
15
|
+
VERSION = '2.0.0-alpha.91';
|
|
16
16
|
BUILD_DATE = new Date().toISOString().split('T')[0];
|
|
17
17
|
}
|
|
18
18
|
export { VERSION, BUILD_DATE };
|
|
@@ -23,4 +23,4 @@ export function displayVersion() {
|
|
|
23
23
|
console.log(getVersionString());
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
//# sourceMappingURL=version.js.
|
|
26
|
+
//# sourceMappingURL=version.js.mapp
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/version.
|
|
1
|
+
{"version":3,"sources":["../../../src/core/version.ts"],"sourcesContent":["/**\n * Centralized version management\n * Reads version from package.json to ensure consistency\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read version from package.json\nlet VERSION: string;\nlet BUILD_DATE: string;\n\ntry {\n // Navigate to project root and read package.json\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n VERSION = packageJson.version;\n BUILD_DATE = new Date().toISOString().split('T')[0];\n} catch (error) {\n // Fallback version if package.json can't be read\n console.warn('Warning: Could not read version from package.json, using fallback');\n VERSION = '2.0.0-alpha.91';\n BUILD_DATE = new Date().toISOString().split('T')[0];\n}\n\nexport { VERSION, BUILD_DATE };\n\n// Helper function to get formatted version string\nexport function getVersionString(includeV = true): string {\n return includeV ? `v${VERSION}` : VERSION;\n}\n\n// Helper function for version display in CLI\nexport function displayVersion(): void {\n console.log(getVersionString());\n}"],"names":["readFileSync","join","dirname","fileURLToPath","__filename","url","__dirname","VERSION","BUILD_DATE","packageJsonPath","packageJson","JSON","parse","version","Date","toISOString","split","error","console","warn","getVersionString","includeV","displayVersion","log"],"mappings":"AAKA,SAASA,YAAY,QAAQ,KAAK;AAClC,SAASC,IAAI,EAAEC,OAAO,QAAQ,OAAO;AACrC,SAASC,aAAa,QAAQ,MAAM;AAGpC,MAAMC,aAAaD,cAAc,YAAYE,GAAG;AAChD,MAAMC,YAAYJ,QAAQE;AAG1B,IAAIG;AACJ,IAAIC;AAEJ,IAAI;IAEF,MAAMC,kBAAkBR,KAAKK,WAAW;IACxC,MAAMI,cAAcC,KAAKC,KAAK,CAACZ,aAAaS,iBAAiB;IAC7DF,UAAUG,YAAYG,OAAO;IAC7BL,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD,EAAE,OAAOC,OAAO;IAEdC,QAAQC,IAAI,CAAC;IACbZ,UAAU;IACVC,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD;AAEA,SAAST,OAAO,EAAEC,UAAU,GAAG;AAG/B,OAAO,SAASY,iBAAiBC,WAAW,IAAI;IAC9C,OAAOA,WAAW,CAAC,CAAC,EAAEd,SAAS,GAAGA;AACpC;AAGA,OAAO,SAASe;IACdJ,QAAQK,GAAG,CAACH;AACd"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
export class MemoryJobPersistence {
|
|
4
|
+
jobs = new Map();
|
|
5
|
+
async save(job) {
|
|
6
|
+
this.jobs.set(job.job_id, {
|
|
7
|
+
...job
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
async load(job_id) {
|
|
11
|
+
const job = this.jobs.get(job_id);
|
|
12
|
+
return job ? {
|
|
13
|
+
...job
|
|
14
|
+
} : null;
|
|
15
|
+
}
|
|
16
|
+
async list(filter) {
|
|
17
|
+
let jobs = Array.from(this.jobs.values());
|
|
18
|
+
if (filter?.status) {
|
|
19
|
+
jobs = jobs.filter((j)=>j.status === filter.status);
|
|
20
|
+
}
|
|
21
|
+
if (filter?.limit) {
|
|
22
|
+
jobs = jobs.slice(0, filter.limit);
|
|
23
|
+
}
|
|
24
|
+
return jobs;
|
|
25
|
+
}
|
|
26
|
+
async delete(job_id) {
|
|
27
|
+
this.jobs.delete(job_id);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class MCPAsyncJobManager extends EventEmitter {
|
|
31
|
+
logger;
|
|
32
|
+
config;
|
|
33
|
+
jobs = new Map();
|
|
34
|
+
executors = new Map();
|
|
35
|
+
persistence;
|
|
36
|
+
constructor(persistence, logger, config = {}){
|
|
37
|
+
super(), this.logger = logger, this.config = config;
|
|
38
|
+
this.persistence = persistence || new MemoryJobPersistence();
|
|
39
|
+
this.config.maxJobs = this.config.maxJobs || 1000;
|
|
40
|
+
this.config.jobTTL = this.config.jobTTL || 86400000;
|
|
41
|
+
this.config.defaultPollInterval = this.config.defaultPollInterval || 5;
|
|
42
|
+
setInterval(()=>this.cleanupExpiredJobs(), 3600000);
|
|
43
|
+
}
|
|
44
|
+
async submitJob(request, executor) {
|
|
45
|
+
if (this.jobs.size >= this.config.maxJobs) {
|
|
46
|
+
throw new Error('Job queue full. Please try again later.');
|
|
47
|
+
}
|
|
48
|
+
const existingJob = Array.from(this.jobs.values()).find((j)=>j.request_id === request.request_id && (j.status === 'queued' || j.status === 'running'));
|
|
49
|
+
if (existingJob) {
|
|
50
|
+
throw new Error(`Duplicate request_id: ${request.request_id}. Job already submitted.`);
|
|
51
|
+
}
|
|
52
|
+
const job = {
|
|
53
|
+
request_id: request.request_id,
|
|
54
|
+
job_id: uuidv4(),
|
|
55
|
+
tool_id: request.tool_id,
|
|
56
|
+
arguments: request.arguments,
|
|
57
|
+
mode: request.mode,
|
|
58
|
+
status: 'queued',
|
|
59
|
+
progress: 0,
|
|
60
|
+
context: request.context,
|
|
61
|
+
created_at: new Date()
|
|
62
|
+
};
|
|
63
|
+
await this.persistence.save(job);
|
|
64
|
+
this.jobs.set(job.job_id, job);
|
|
65
|
+
this.logger.info('Job submitted', {
|
|
66
|
+
job_id: job.job_id,
|
|
67
|
+
request_id: job.request_id,
|
|
68
|
+
tool_id: job.tool_id
|
|
69
|
+
});
|
|
70
|
+
this.executeJob(job, executor);
|
|
71
|
+
return {
|
|
72
|
+
request_id: job.request_id,
|
|
73
|
+
job_id: job.job_id,
|
|
74
|
+
status: 'in_progress',
|
|
75
|
+
poll_after: this.config.defaultPollInterval
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async pollJob(job_id) {
|
|
79
|
+
const job = await this.persistence.load(job_id);
|
|
80
|
+
if (!job) {
|
|
81
|
+
throw new Error(`Job not found: ${job_id}`);
|
|
82
|
+
}
|
|
83
|
+
const status = job.status === 'success' ? 'success' : job.status === 'error' ? 'error' : 'in_progress';
|
|
84
|
+
const handle = {
|
|
85
|
+
request_id: job.request_id,
|
|
86
|
+
job_id: job.job_id,
|
|
87
|
+
status,
|
|
88
|
+
poll_after: status === 'in_progress' ? this.config.defaultPollInterval : 0
|
|
89
|
+
};
|
|
90
|
+
if (status === 'in_progress') {
|
|
91
|
+
handle.progress = {
|
|
92
|
+
percent: job.progress,
|
|
93
|
+
message: job.progress_message
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return handle;
|
|
97
|
+
}
|
|
98
|
+
async resumeJob(job_id) {
|
|
99
|
+
const job = await this.persistence.load(job_id);
|
|
100
|
+
if (!job) {
|
|
101
|
+
throw new Error(`Job not found: ${job_id}`);
|
|
102
|
+
}
|
|
103
|
+
const result = {
|
|
104
|
+
request_id: job.request_id,
|
|
105
|
+
status: job.status === 'success' ? 'success' : job.status === 'error' ? 'error' : 'in_progress',
|
|
106
|
+
metadata: {}
|
|
107
|
+
};
|
|
108
|
+
if (job.status === 'success') {
|
|
109
|
+
result.result = job.result;
|
|
110
|
+
result.metadata.duration_ms = job.completed_at && job.started_at ? job.completed_at.getTime() - job.started_at.getTime() : undefined;
|
|
111
|
+
result.metadata.tokens_used = job.tokens_used;
|
|
112
|
+
} else if (job.status === 'error') {
|
|
113
|
+
result.error = {
|
|
114
|
+
code: 'EXECUTION_ERROR',
|
|
115
|
+
message: job.error?.message || 'Job execution failed',
|
|
116
|
+
details: job.error
|
|
117
|
+
};
|
|
118
|
+
} else {
|
|
119
|
+
result.progress = {
|
|
120
|
+
percent: job.progress,
|
|
121
|
+
message: job.progress_message
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
async cancelJob(job_id) {
|
|
127
|
+
const job = this.jobs.get(job_id);
|
|
128
|
+
if (!job) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
if (job.status === 'success' || job.status === 'error') {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
if (job.abortController) {
|
|
135
|
+
job.abortController.abort();
|
|
136
|
+
}
|
|
137
|
+
job.status = 'cancelled';
|
|
138
|
+
job.completed_at = new Date();
|
|
139
|
+
await this.persistence.save(job);
|
|
140
|
+
this.emit('job:cancelled', job_id);
|
|
141
|
+
this.logger.info('Job cancelled', {
|
|
142
|
+
job_id
|
|
143
|
+
});
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
async listJobs(filter) {
|
|
147
|
+
return await this.persistence.list(filter);
|
|
148
|
+
}
|
|
149
|
+
async executeJob(job, executor) {
|
|
150
|
+
job.status = 'running';
|
|
151
|
+
job.started_at = new Date();
|
|
152
|
+
job.abortController = new AbortController();
|
|
153
|
+
await this.persistence.save(job);
|
|
154
|
+
this.emit('job:started', job.job_id);
|
|
155
|
+
this.logger.info('Job started', {
|
|
156
|
+
job_id: job.job_id,
|
|
157
|
+
tool_id: job.tool_id
|
|
158
|
+
});
|
|
159
|
+
try {
|
|
160
|
+
const onProgress = (percent, message)=>{
|
|
161
|
+
job.progress = Math.min(100, Math.max(0, percent));
|
|
162
|
+
job.progress_message = message;
|
|
163
|
+
this.persistence.save(job).catch((err)=>this.logger.error('Failed to save progress', {
|
|
164
|
+
job_id: job.job_id,
|
|
165
|
+
error: err
|
|
166
|
+
}));
|
|
167
|
+
this.emit('job:progress', job.job_id, job.progress, message);
|
|
168
|
+
};
|
|
169
|
+
if (job.abortController.signal.aborted) {
|
|
170
|
+
throw new Error('Job cancelled before execution');
|
|
171
|
+
}
|
|
172
|
+
const result = await executor(job.arguments, onProgress);
|
|
173
|
+
job.status = 'success';
|
|
174
|
+
job.result = result;
|
|
175
|
+
job.progress = 100;
|
|
176
|
+
job.completed_at = new Date();
|
|
177
|
+
await this.persistence.save(job);
|
|
178
|
+
this.emit('job:completed', job.job_id, result);
|
|
179
|
+
this.logger.info('Job completed', {
|
|
180
|
+
job_id: job.job_id,
|
|
181
|
+
duration_ms: job.completed_at.getTime() - job.started_at.getTime()
|
|
182
|
+
});
|
|
183
|
+
} catch (error) {
|
|
184
|
+
job.status = 'error';
|
|
185
|
+
job.error = {
|
|
186
|
+
message: error.message,
|
|
187
|
+
stack: error.stack,
|
|
188
|
+
code: error.code
|
|
189
|
+
};
|
|
190
|
+
job.completed_at = new Date();
|
|
191
|
+
await this.persistence.save(job);
|
|
192
|
+
this.emit('job:failed', job.job_id, error);
|
|
193
|
+
this.logger.error('Job failed', {
|
|
194
|
+
job_id: job.job_id,
|
|
195
|
+
error: error.message
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async cleanupExpiredJobs() {
|
|
200
|
+
const now = Date.now();
|
|
201
|
+
const jobs = await this.persistence.list();
|
|
202
|
+
let cleaned = 0;
|
|
203
|
+
for (const job of jobs){
|
|
204
|
+
const age = now - job.created_at.getTime();
|
|
205
|
+
if (age > this.config.jobTTL && job.status !== 'running') {
|
|
206
|
+
await this.persistence.delete(job.job_id);
|
|
207
|
+
this.jobs.delete(job.job_id);
|
|
208
|
+
cleaned++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (cleaned > 0) {
|
|
212
|
+
this.logger.info('Cleaned up expired jobs', {
|
|
213
|
+
count: cleaned
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return cleaned;
|
|
217
|
+
}
|
|
218
|
+
getMetrics() {
|
|
219
|
+
const jobs = Array.from(this.jobs.values());
|
|
220
|
+
return {
|
|
221
|
+
total: jobs.length,
|
|
222
|
+
byStatus: {
|
|
223
|
+
queued: jobs.filter((j)=>j.status === 'queued').length,
|
|
224
|
+
running: jobs.filter((j)=>j.status === 'running').length,
|
|
225
|
+
success: jobs.filter((j)=>j.status === 'success').length,
|
|
226
|
+
error: jobs.filter((j)=>j.status === 'error').length,
|
|
227
|
+
cancelled: jobs.filter((j)=>j.status === 'cancelled').length
|
|
228
|
+
},
|
|
229
|
+
averageDuration: this.calculateAverageDuration(jobs)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
calculateAverageDuration(jobs) {
|
|
233
|
+
const completed = jobs.filter((j)=>(j.status === 'success' || j.status === 'error') && j.started_at && j.completed_at);
|
|
234
|
+
if (completed.length === 0) return 0;
|
|
235
|
+
const total = completed.reduce((sum, j)=>sum + (j.completed_at.getTime() - j.started_at.getTime()), 0);
|
|
236
|
+
return total / completed.length;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=job-manager-mcp25.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/mcp/async/job-manager-mcp25.ts"],"sourcesContent":["/**\n * MCP 2025-11 Async Job Manager\n *\n * Implements async job lifecycle per MCP 2025-11 specification:\n * - Job handles with request_id\n * - Poll/resume semantics\n * - Progress tracking\n * - Job persistence\n */\n\nimport { EventEmitter } from 'events';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { ILogger } from '../../interfaces/logger.js';\n\n/**\n * MCP tool request (2025-11 format)\n */\nexport interface MCPToolRequest {\n request_id: string;\n tool_id: string;\n arguments: Record<string, any>;\n session?: string;\n mode: 'async' | 'sync';\n context?: {\n trace_id?: string;\n client_name?: string;\n [key: string]: any;\n };\n}\n\n/**\n * MCP job handle (2025-11 format)\n */\nexport interface MCPJobHandle {\n request_id: string;\n job_id: string;\n status: 'in_progress' | 'success' | 'error';\n poll_after: number; // seconds\n progress?: {\n percent: number;\n message?: string;\n };\n}\n\n/**\n * MCP job result (2025-11 format)\n */\nexport interface MCPJobResult {\n request_id: string;\n status: 'success' | 'error' | 'in_progress';\n result?: any;\n error?: {\n code: string;\n message: string;\n details?: any;\n };\n progress?: {\n percent: number;\n message?: string;\n };\n metadata: {\n duration_ms?: number;\n tokens_used?: number;\n [key: string]: any;\n };\n}\n\n/**\n * Internal job state\n */\ninterface AsyncJob {\n request_id: string;\n job_id: string;\n tool_id: string;\n arguments: Record<string, any>;\n mode: 'async' | 'sync';\n status: 'queued' | 'running' | 'success' | 'error' | 'cancelled';\n progress: number;\n progress_message?: string;\n result?: any;\n error?: any;\n context?: any;\n created_at: Date;\n started_at?: Date;\n completed_at?: Date;\n tokens_used?: number;\n abortController?: AbortController;\n}\n\n/**\n * Job persistence interface\n */\nexport interface JobPersistence {\n save(job: AsyncJob): Promise<void>;\n load(job_id: string): Promise<AsyncJob | null>;\n list(filter?: { status?: string; limit?: number }): Promise<AsyncJob[]>;\n delete(job_id: string): Promise<void>;\n}\n\n/**\n * Simple in-memory job persistence (fallback)\n */\nexport class MemoryJobPersistence implements JobPersistence {\n private jobs: Map<string, AsyncJob> = new Map();\n\n async save(job: AsyncJob): Promise<void> {\n this.jobs.set(job.job_id, { ...job });\n }\n\n async load(job_id: string): Promise<AsyncJob | null> {\n const job = this.jobs.get(job_id);\n return job ? { ...job } : null;\n }\n\n async list(filter?: { status?: string; limit?: number }): Promise<AsyncJob[]> {\n let jobs = Array.from(this.jobs.values());\n\n if (filter?.status) {\n jobs = jobs.filter(j => j.status === filter.status);\n }\n\n if (filter?.limit) {\n jobs = jobs.slice(0, filter.limit);\n }\n\n return jobs;\n }\n\n async delete(job_id: string): Promise<void> {\n this.jobs.delete(job_id);\n }\n}\n\n/**\n * MCP 2025-11 Async Job Manager\n */\nexport class MCPAsyncJobManager extends EventEmitter {\n private jobs: Map<string, AsyncJob> = new Map();\n private executors: Map<string, Promise<any>> = new Map();\n private persistence: JobPersistence;\n\n constructor(\n persistence: JobPersistence | null,\n private logger: ILogger,\n private config: {\n maxJobs?: number;\n jobTTL?: number;\n defaultPollInterval?: number;\n } = {}\n ) {\n super();\n this.persistence = persistence || new MemoryJobPersistence();\n\n // Default config\n this.config.maxJobs = this.config.maxJobs || 1000;\n this.config.jobTTL = this.config.jobTTL || 86400000; // 24 hours\n this.config.defaultPollInterval = this.config.defaultPollInterval || 5;\n\n // Cleanup expired jobs periodically\n setInterval(() => this.cleanupExpiredJobs(), 3600000); // Every hour\n }\n\n /**\n * Submit async job (MCP 2025-11 format)\n */\n async submitJob(\n request: MCPToolRequest,\n executor: (args: any, onProgress: (percent: number, message?: string) => void) => Promise<any>\n ): Promise<MCPJobHandle> {\n // Check capacity\n if (this.jobs.size >= this.config.maxJobs!) {\n throw new Error('Job queue full. Please try again later.');\n }\n\n // Check for duplicate request_id (prevent race conditions)\n const existingJob = Array.from(this.jobs.values()).find(\n j => j.request_id === request.request_id &&\n (j.status === 'queued' || j.status === 'running')\n );\n if (existingJob) {\n throw new Error(`Duplicate request_id: ${request.request_id}. Job already submitted.`);\n }\n\n // Create job\n const job: AsyncJob = {\n request_id: request.request_id,\n job_id: uuidv4(),\n tool_id: request.tool_id,\n arguments: request.arguments,\n mode: request.mode,\n status: 'queued',\n progress: 0,\n context: request.context,\n created_at: new Date(),\n };\n\n // Save to persistence\n await this.persistence.save(job);\n this.jobs.set(job.job_id, job);\n\n this.logger.info('Job submitted', {\n job_id: job.job_id,\n request_id: job.request_id,\n tool_id: job.tool_id,\n });\n\n // Start execution in background\n this.executeJob(job, executor);\n\n // Return job handle immediately\n return {\n request_id: job.request_id,\n job_id: job.job_id,\n status: 'in_progress',\n poll_after: this.config.defaultPollInterval!,\n };\n }\n\n /**\n * Poll job status\n */\n async pollJob(job_id: string): Promise<MCPJobHandle> {\n const job = await this.persistence.load(job_id);\n\n if (!job) {\n throw new Error(`Job not found: ${job_id}`);\n }\n\n const status = job.status === 'success' ? 'success' :\n job.status === 'error' ? 'error' : 'in_progress';\n\n const handle: MCPJobHandle = {\n request_id: job.request_id,\n job_id: job.job_id,\n status,\n poll_after: status === 'in_progress' ? this.config.defaultPollInterval! : 0,\n };\n\n if (status === 'in_progress') {\n handle.progress = {\n percent: job.progress,\n message: job.progress_message,\n };\n }\n\n return handle;\n }\n\n /**\n * Resume job (get results)\n */\n async resumeJob(job_id: string): Promise<MCPJobResult> {\n const job = await this.persistence.load(job_id);\n\n if (!job) {\n throw new Error(`Job not found: ${job_id}`);\n }\n\n const result: MCPJobResult = {\n request_id: job.request_id,\n status: job.status === 'success' ? 'success' :\n job.status === 'error' ? 'error' : 'in_progress',\n metadata: {},\n };\n\n if (job.status === 'success') {\n result.result = job.result;\n result.metadata.duration_ms = job.completed_at && job.started_at\n ? job.completed_at.getTime() - job.started_at.getTime()\n : undefined;\n result.metadata.tokens_used = job.tokens_used;\n } else if (job.status === 'error') {\n result.error = {\n code: 'EXECUTION_ERROR',\n message: job.error?.message || 'Job execution failed',\n details: job.error,\n };\n } else {\n // Still in progress\n result.progress = {\n percent: job.progress,\n message: job.progress_message,\n };\n }\n\n return result;\n }\n\n /**\n * Cancel a running job\n */\n async cancelJob(job_id: string): Promise<boolean> {\n const job = this.jobs.get(job_id);\n\n if (!job) {\n return false;\n }\n\n if (job.status === 'success' || job.status === 'error') {\n return false; // Already finished\n }\n\n // Abort execution if AbortController is available\n if (job.abortController) {\n job.abortController.abort();\n }\n\n job.status = 'cancelled';\n job.completed_at = new Date();\n await this.persistence.save(job);\n\n this.emit('job:cancelled', job_id);\n this.logger.info('Job cancelled', { job_id });\n\n return true;\n }\n\n /**\n * List jobs\n */\n async listJobs(filter?: {\n status?: string;\n limit?: number;\n }): Promise<AsyncJob[]> {\n return await this.persistence.list(filter);\n }\n\n /**\n * Execute job in background\n */\n private async executeJob(\n job: AsyncJob,\n executor: (args: any, onProgress: (percent: number, message?: string) => void) => Promise<any>\n ): Promise<void> {\n // Update status to running\n job.status = 'running';\n job.started_at = new Date();\n\n // Create AbortController for cancellation support\n job.abortController = new AbortController();\n\n await this.persistence.save(job);\n\n this.emit('job:started', job.job_id);\n this.logger.info('Job started', { job_id: job.job_id, tool_id: job.tool_id });\n\n try {\n // Progress callback\n const onProgress = (percent: number, message?: string) => {\n job.progress = Math.min(100, Math.max(0, percent));\n job.progress_message = message;\n this.persistence.save(job).catch(err =>\n this.logger.error('Failed to save progress', { job_id: job.job_id, error: err })\n );\n this.emit('job:progress', job.job_id, job.progress, message);\n };\n\n // Check if already cancelled\n if (job.abortController.signal.aborted) {\n throw new Error('Job cancelled before execution');\n }\n\n // Execute with abort support\n const result = await executor(job.arguments, onProgress);\n\n // Mark successful\n job.status = 'success';\n job.result = result;\n job.progress = 100;\n job.completed_at = new Date();\n await this.persistence.save(job);\n\n this.emit('job:completed', job.job_id, result);\n this.logger.info('Job completed', {\n job_id: job.job_id,\n duration_ms: job.completed_at.getTime() - job.started_at!.getTime(),\n });\n } catch (error: any) {\n // Mark failed\n job.status = 'error';\n job.error = {\n message: error.message,\n stack: error.stack,\n code: error.code,\n };\n job.completed_at = new Date();\n await this.persistence.save(job);\n\n this.emit('job:failed', job.job_id, error);\n this.logger.error('Job failed', {\n job_id: job.job_id,\n error: error.message,\n });\n }\n }\n\n /**\n * Cleanup expired jobs\n */\n private async cleanupExpiredJobs(): Promise<number> {\n const now = Date.now();\n const jobs = await this.persistence.list();\n let cleaned = 0;\n\n for (const job of jobs) {\n const age = now - job.created_at.getTime();\n\n // Remove if expired and not running\n if (age > this.config.jobTTL! && job.status !== 'running') {\n await this.persistence.delete(job.job_id);\n this.jobs.delete(job.job_id);\n cleaned++;\n }\n }\n\n if (cleaned > 0) {\n this.logger.info('Cleaned up expired jobs', { count: cleaned });\n }\n\n return cleaned;\n }\n\n /**\n * Get metrics\n */\n getMetrics() {\n const jobs = Array.from(this.jobs.values());\n\n return {\n total: jobs.length,\n byStatus: {\n queued: jobs.filter(j => j.status === 'queued').length,\n running: jobs.filter(j => j.status === 'running').length,\n success: jobs.filter(j => j.status === 'success').length,\n error: jobs.filter(j => j.status === 'error').length,\n cancelled: jobs.filter(j => j.status === 'cancelled').length,\n },\n averageDuration: this.calculateAverageDuration(jobs),\n };\n }\n\n private calculateAverageDuration(jobs: AsyncJob[]): number {\n const completed = jobs.filter(j =>\n (j.status === 'success' || j.status === 'error') &&\n j.started_at && j.completed_at\n );\n\n if (completed.length === 0) return 0;\n\n const total = completed.reduce((sum, j) =>\n sum + (j.completed_at!.getTime() - j.started_at!.getTime()), 0\n );\n\n return total / completed.length;\n }\n}\n"],"names":["EventEmitter","v4","uuidv4","MemoryJobPersistence","jobs","Map","save","job","set","job_id","load","get","list","filter","Array","from","values","status","j","limit","slice","delete","MCPAsyncJobManager","executors","persistence","logger","config","maxJobs","jobTTL","defaultPollInterval","setInterval","cleanupExpiredJobs","submitJob","request","executor","size","Error","existingJob","find","request_id","tool_id","arguments","mode","progress","context","created_at","Date","info","executeJob","poll_after","pollJob","handle","percent","message","progress_message","resumeJob","result","metadata","duration_ms","completed_at","started_at","getTime","undefined","tokens_used","error","code","details","cancelJob","abortController","abort","emit","listJobs","AbortController","onProgress","Math","min","max","catch","err","signal","aborted","stack","now","cleaned","age","count","getMetrics","total","length","byStatus","queued","running","success","cancelled","averageDuration","calculateAverageDuration","completed","reduce","sum"],"mappings":"AAUA,SAASA,YAAY,QAAQ,SAAS;AACtC,SAASC,MAAMC,MAAM,QAAQ,OAAO;AA2FpC,OAAO,MAAMC;IACHC,OAA8B,IAAIC,MAAM;IAEhD,MAAMC,KAAKC,GAAa,EAAiB;QACvC,IAAI,CAACH,IAAI,CAACI,GAAG,CAACD,IAAIE,MAAM,EAAE;YAAE,GAAGF,GAAG;QAAC;IACrC;IAEA,MAAMG,KAAKD,MAAc,EAA4B;QACnD,MAAMF,MAAM,IAAI,CAACH,IAAI,CAACO,GAAG,CAACF;QAC1B,OAAOF,MAAM;YAAE,GAAGA,GAAG;QAAC,IAAI;IAC5B;IAEA,MAAMK,KAAKC,MAA4C,EAAuB;QAC5E,IAAIT,OAAOU,MAAMC,IAAI,CAAC,IAAI,CAACX,IAAI,CAACY,MAAM;QAEtC,IAAIH,QAAQI,QAAQ;YAClBb,OAAOA,KAAKS,MAAM,CAACK,CAAAA,IAAKA,EAAED,MAAM,KAAKJ,OAAOI,MAAM;QACpD;QAEA,IAAIJ,QAAQM,OAAO;YACjBf,OAAOA,KAAKgB,KAAK,CAAC,GAAGP,OAAOM,KAAK;QACnC;QAEA,OAAOf;IACT;IAEA,MAAMiB,OAAOZ,MAAc,EAAiB;QAC1C,IAAI,CAACL,IAAI,CAACiB,MAAM,CAACZ;IACnB;AACF;AAKA,OAAO,MAAMa,2BAA2BtB;;;IAC9BI,OAA8B,IAAIC,MAAM;IACxCkB,YAAuC,IAAIlB,MAAM;IACjDmB,YAA4B;IAEpC,YACEA,WAAkC,EAClC,AAAQC,MAAe,EACvB,AAAQC,SAIJ,CAAC,CAAC,CACN;QACA,KAAK,SAPGD,SAAAA,aACAC,SAAAA;QAOR,IAAI,CAACF,WAAW,GAAGA,eAAe,IAAIrB;QAGtC,IAAI,CAACuB,MAAM,CAACC,OAAO,GAAG,IAAI,CAACD,MAAM,CAACC,OAAO,IAAI;QAC7C,IAAI,CAACD,MAAM,CAACE,MAAM,GAAG,IAAI,CAACF,MAAM,CAACE,MAAM,IAAI;QAC3C,IAAI,CAACF,MAAM,CAACG,mBAAmB,GAAG,IAAI,CAACH,MAAM,CAACG,mBAAmB,IAAI;QAGrEC,YAAY,IAAM,IAAI,CAACC,kBAAkB,IAAI;IAC/C;IAKA,MAAMC,UACJC,OAAuB,EACvBC,QAA8F,EACvE;QAEvB,IAAI,IAAI,CAAC9B,IAAI,CAAC+B,IAAI,IAAI,IAAI,CAACT,MAAM,CAACC,OAAO,EAAG;YAC1C,MAAM,IAAIS,MAAM;QAClB;QAGA,MAAMC,cAAcvB,MAAMC,IAAI,CAAC,IAAI,CAACX,IAAI,CAACY,MAAM,IAAIsB,IAAI,CACrDpB,CAAAA,IAAKA,EAAEqB,UAAU,KAAKN,QAAQM,UAAU,IAClCrB,CAAAA,EAAED,MAAM,KAAK,YAAYC,EAAED,MAAM,KAAK,SAAQ;QAEtD,IAAIoB,aAAa;YACf,MAAM,IAAID,MAAM,CAAC,sBAAsB,EAAEH,QAAQM,UAAU,CAAC,wBAAwB,CAAC;QACvF;QAGA,MAAMhC,MAAgB;YACpBgC,YAAYN,QAAQM,UAAU;YAC9B9B,QAAQP;YACRsC,SAASP,QAAQO,OAAO;YACxBC,WAAWR,QAAQQ,SAAS;YAC5BC,MAAMT,QAAQS,IAAI;YAClBzB,QAAQ;YACR0B,UAAU;YACVC,SAASX,QAAQW,OAAO;YACxBC,YAAY,IAAIC;QAClB;QAGA,MAAM,IAAI,CAACtB,WAAW,CAAClB,IAAI,CAACC;QAC5B,IAAI,CAACH,IAAI,CAACI,GAAG,CAACD,IAAIE,MAAM,EAAEF;QAE1B,IAAI,CAACkB,MAAM,CAACsB,IAAI,CAAC,iBAAiB;YAChCtC,QAAQF,IAAIE,MAAM;YAClB8B,YAAYhC,IAAIgC,UAAU;YAC1BC,SAASjC,IAAIiC,OAAO;QACtB;QAGA,IAAI,CAACQ,UAAU,CAACzC,KAAK2B;QAGrB,OAAO;YACLK,YAAYhC,IAAIgC,UAAU;YAC1B9B,QAAQF,IAAIE,MAAM;YAClBQ,QAAQ;YACRgC,YAAY,IAAI,CAACvB,MAAM,CAACG,mBAAmB;QAC7C;IACF;IAKA,MAAMqB,QAAQzC,MAAc,EAAyB;QACnD,MAAMF,MAAM,MAAM,IAAI,CAACiB,WAAW,CAACd,IAAI,CAACD;QAExC,IAAI,CAACF,KAAK;YACR,MAAM,IAAI6B,MAAM,CAAC,eAAe,EAAE3B,QAAQ;QAC5C;QAEA,MAAMQ,SAASV,IAAIU,MAAM,KAAK,YAAY,YAC3BV,IAAIU,MAAM,KAAK,UAAU,UAAU;QAElD,MAAMkC,SAAuB;YAC3BZ,YAAYhC,IAAIgC,UAAU;YAC1B9B,QAAQF,IAAIE,MAAM;YAClBQ;YACAgC,YAAYhC,WAAW,gBAAgB,IAAI,CAACS,MAAM,CAACG,mBAAmB,GAAI;QAC5E;QAEA,IAAIZ,WAAW,eAAe;YAC5BkC,OAAOR,QAAQ,GAAG;gBAChBS,SAAS7C,IAAIoC,QAAQ;gBACrBU,SAAS9C,IAAI+C,gBAAgB;YAC/B;QACF;QAEA,OAAOH;IACT;IAKA,MAAMI,UAAU9C,MAAc,EAAyB;QACrD,MAAMF,MAAM,MAAM,IAAI,CAACiB,WAAW,CAACd,IAAI,CAACD;QAExC,IAAI,CAACF,KAAK;YACR,MAAM,IAAI6B,MAAM,CAAC,eAAe,EAAE3B,QAAQ;QAC5C;QAEA,MAAM+C,SAAuB;YAC3BjB,YAAYhC,IAAIgC,UAAU;YAC1BtB,QAAQV,IAAIU,MAAM,KAAK,YAAY,YAC3BV,IAAIU,MAAM,KAAK,UAAU,UAAU;YAC3CwC,UAAU,CAAC;QACb;QAEA,IAAIlD,IAAIU,MAAM,KAAK,WAAW;YAC5BuC,OAAOA,MAAM,GAAGjD,IAAIiD,MAAM;YAC1BA,OAAOC,QAAQ,CAACC,WAAW,GAAGnD,IAAIoD,YAAY,IAAIpD,IAAIqD,UAAU,GAC5DrD,IAAIoD,YAAY,CAACE,OAAO,KAAKtD,IAAIqD,UAAU,CAACC,OAAO,KACnDC;YACJN,OAAOC,QAAQ,CAACM,WAAW,GAAGxD,IAAIwD,WAAW;QAC/C,OAAO,IAAIxD,IAAIU,MAAM,KAAK,SAAS;YACjCuC,OAAOQ,KAAK,GAAG;gBACbC,MAAM;gBACNZ,SAAS9C,IAAIyD,KAAK,EAAEX,WAAW;gBAC/Ba,SAAS3D,IAAIyD,KAAK;YACpB;QACF,OAAO;YAELR,OAAOb,QAAQ,GAAG;gBAChBS,SAAS7C,IAAIoC,QAAQ;gBACrBU,SAAS9C,IAAI+C,gBAAgB;YAC/B;QACF;QAEA,OAAOE;IACT;IAKA,MAAMW,UAAU1D,MAAc,EAAoB;QAChD,MAAMF,MAAM,IAAI,CAACH,IAAI,CAACO,GAAG,CAACF;QAE1B,IAAI,CAACF,KAAK;YACR,OAAO;QACT;QAEA,IAAIA,IAAIU,MAAM,KAAK,aAAaV,IAAIU,MAAM,KAAK,SAAS;YACtD,OAAO;QACT;QAGA,IAAIV,IAAI6D,eAAe,EAAE;YACvB7D,IAAI6D,eAAe,CAACC,KAAK;QAC3B;QAEA9D,IAAIU,MAAM,GAAG;QACbV,IAAIoD,YAAY,GAAG,IAAIb;QACvB,MAAM,IAAI,CAACtB,WAAW,CAAClB,IAAI,CAACC;QAE5B,IAAI,CAAC+D,IAAI,CAAC,iBAAiB7D;QAC3B,IAAI,CAACgB,MAAM,CAACsB,IAAI,CAAC,iBAAiB;YAAEtC;QAAO;QAE3C,OAAO;IACT;IAKA,MAAM8D,SAAS1D,MAGd,EAAuB;QACtB,OAAO,MAAM,IAAI,CAACW,WAAW,CAACZ,IAAI,CAACC;IACrC;IAKA,MAAcmC,WACZzC,GAAa,EACb2B,QAA8F,EAC/E;QAEf3B,IAAIU,MAAM,GAAG;QACbV,IAAIqD,UAAU,GAAG,IAAId;QAGrBvC,IAAI6D,eAAe,GAAG,IAAII;QAE1B,MAAM,IAAI,CAAChD,WAAW,CAAClB,IAAI,CAACC;QAE5B,IAAI,CAAC+D,IAAI,CAAC,eAAe/D,IAAIE,MAAM;QACnC,IAAI,CAACgB,MAAM,CAACsB,IAAI,CAAC,eAAe;YAAEtC,QAAQF,IAAIE,MAAM;YAAE+B,SAASjC,IAAIiC,OAAO;QAAC;QAE3E,IAAI;YAEF,MAAMiC,aAAa,CAACrB,SAAiBC;gBACnC9C,IAAIoC,QAAQ,GAAG+B,KAAKC,GAAG,CAAC,KAAKD,KAAKE,GAAG,CAAC,GAAGxB;gBACzC7C,IAAI+C,gBAAgB,GAAGD;gBACvB,IAAI,CAAC7B,WAAW,CAAClB,IAAI,CAACC,KAAKsE,KAAK,CAACC,CAAAA,MAC/B,IAAI,CAACrD,MAAM,CAACuC,KAAK,CAAC,2BAA2B;wBAAEvD,QAAQF,IAAIE,MAAM;wBAAEuD,OAAOc;oBAAI;gBAEhF,IAAI,CAACR,IAAI,CAAC,gBAAgB/D,IAAIE,MAAM,EAAEF,IAAIoC,QAAQ,EAAEU;YACtD;YAGA,IAAI9C,IAAI6D,eAAe,CAACW,MAAM,CAACC,OAAO,EAAE;gBACtC,MAAM,IAAI5C,MAAM;YAClB;YAGA,MAAMoB,SAAS,MAAMtB,SAAS3B,IAAIkC,SAAS,EAAEgC;YAG7ClE,IAAIU,MAAM,GAAG;YACbV,IAAIiD,MAAM,GAAGA;YACbjD,IAAIoC,QAAQ,GAAG;YACfpC,IAAIoD,YAAY,GAAG,IAAIb;YACvB,MAAM,IAAI,CAACtB,WAAW,CAAClB,IAAI,CAACC;YAE5B,IAAI,CAAC+D,IAAI,CAAC,iBAAiB/D,IAAIE,MAAM,EAAE+C;YACvC,IAAI,CAAC/B,MAAM,CAACsB,IAAI,CAAC,iBAAiB;gBAChCtC,QAAQF,IAAIE,MAAM;gBAClBiD,aAAanD,IAAIoD,YAAY,CAACE,OAAO,KAAKtD,IAAIqD,UAAU,CAAEC,OAAO;YACnE;QACF,EAAE,OAAOG,OAAY;YAEnBzD,IAAIU,MAAM,GAAG;YACbV,IAAIyD,KAAK,GAAG;gBACVX,SAASW,MAAMX,OAAO;gBACtB4B,OAAOjB,MAAMiB,KAAK;gBAClBhB,MAAMD,MAAMC,IAAI;YAClB;YACA1D,IAAIoD,YAAY,GAAG,IAAIb;YACvB,MAAM,IAAI,CAACtB,WAAW,CAAClB,IAAI,CAACC;YAE5B,IAAI,CAAC+D,IAAI,CAAC,cAAc/D,IAAIE,MAAM,EAAEuD;YACpC,IAAI,CAACvC,MAAM,CAACuC,KAAK,CAAC,cAAc;gBAC9BvD,QAAQF,IAAIE,MAAM;gBAClBuD,OAAOA,MAAMX,OAAO;YACtB;QACF;IACF;IAKA,MAActB,qBAAsC;QAClD,MAAMmD,MAAMpC,KAAKoC,GAAG;QACpB,MAAM9E,OAAO,MAAM,IAAI,CAACoB,WAAW,CAACZ,IAAI;QACxC,IAAIuE,UAAU;QAEd,KAAK,MAAM5E,OAAOH,KAAM;YACtB,MAAMgF,MAAMF,MAAM3E,IAAIsC,UAAU,CAACgB,OAAO;YAGxC,IAAIuB,MAAM,IAAI,CAAC1D,MAAM,CAACE,MAAM,IAAKrB,IAAIU,MAAM,KAAK,WAAW;gBACzD,MAAM,IAAI,CAACO,WAAW,CAACH,MAAM,CAACd,IAAIE,MAAM;gBACxC,IAAI,CAACL,IAAI,CAACiB,MAAM,CAACd,IAAIE,MAAM;gBAC3B0E;YACF;QACF;QAEA,IAAIA,UAAU,GAAG;YACf,IAAI,CAAC1D,MAAM,CAACsB,IAAI,CAAC,2BAA2B;gBAAEsC,OAAOF;YAAQ;QAC/D;QAEA,OAAOA;IACT;IAKAG,aAAa;QACX,MAAMlF,OAAOU,MAAMC,IAAI,CAAC,IAAI,CAACX,IAAI,CAACY,MAAM;QAExC,OAAO;YACLuE,OAAOnF,KAAKoF,MAAM;YAClBC,UAAU;gBACRC,QAAQtF,KAAKS,MAAM,CAACK,CAAAA,IAAKA,EAAED,MAAM,KAAK,UAAUuE,MAAM;gBACtDG,SAASvF,KAAKS,MAAM,CAACK,CAAAA,IAAKA,EAAED,MAAM,KAAK,WAAWuE,MAAM;gBACxDI,SAASxF,KAAKS,MAAM,CAACK,CAAAA,IAAKA,EAAED,MAAM,KAAK,WAAWuE,MAAM;gBACxDxB,OAAO5D,KAAKS,MAAM,CAACK,CAAAA,IAAKA,EAAED,MAAM,KAAK,SAASuE,MAAM;gBACpDK,WAAWzF,KAAKS,MAAM,CAACK,CAAAA,IAAKA,EAAED,MAAM,KAAK,aAAauE,MAAM;YAC9D;YACAM,iBAAiB,IAAI,CAACC,wBAAwB,CAAC3F;QACjD;IACF;IAEQ2F,yBAAyB3F,IAAgB,EAAU;QACzD,MAAM4F,YAAY5F,KAAKS,MAAM,CAACK,CAAAA,IAC5B,AAACA,CAAAA,EAAED,MAAM,KAAK,aAAaC,EAAED,MAAM,KAAK,OAAM,KAC9CC,EAAE0C,UAAU,IAAI1C,EAAEyC,YAAY;QAGhC,IAAIqC,UAAUR,MAAM,KAAK,GAAG,OAAO;QAEnC,MAAMD,QAAQS,UAAUC,MAAM,CAAC,CAACC,KAAKhF,IACnCgF,MAAOhF,CAAAA,EAAEyC,YAAY,CAAEE,OAAO,KAAK3C,EAAE0C,UAAU,CAAEC,OAAO,EAAC,GAAI;QAG/D,OAAO0B,QAAQS,UAAUR,MAAM;IACjC;AACF"}
|
package/dist/src/mcp/index.js
CHANGED
|
@@ -2,6 +2,14 @@ export { InProcessMCPServer, createInProcessServer } from './in-process-server.j
|
|
|
2
2
|
export { ClaudeFlowToolRegistry, createToolRegistry, createClaudeFlowSdkServer } from './tool-registry.js';
|
|
3
3
|
export { SDKIntegration, initializeSDKIntegration, getSDKIntegration, createInProcessQuery, getInProcessServerConfig, measurePerformance } from './sdk-integration.js';
|
|
4
4
|
export { MCPServer } from './server.js';
|
|
5
|
+
export { MCP2025Server } from './server-mcp-2025.js';
|
|
6
|
+
export { MCPServerFactory, createMCPServer, isMCP2025Available, getServerCapabilities } from './server-factory.js';
|
|
7
|
+
export { VersionNegotiator, BackwardCompatibilityAdapter } from './protocol/version-negotiation.js';
|
|
8
|
+
export { MCPAsyncJobManager } from './async/job-manager-mcp25.js';
|
|
9
|
+
export { MCPRegistryClient } from './registry/mcp-registry-client-2025.js';
|
|
10
|
+
export { SchemaValidator, upgradeToolSchema } from './validation/schema-validator-2025.js';
|
|
11
|
+
export { ProgressiveToolRegistry, createProgressiveToolRegistry, createProgressiveClaudeFlowSdkServer } from './tool-registry-progressive.js';
|
|
12
|
+
export { DynamicToolLoader } from './tools/loader.js';
|
|
5
13
|
export { MCPLifecycleManager, LifecycleState } from './lifecycle-manager.js';
|
|
6
14
|
export { ToolRegistry } from './tools.js';
|
|
7
15
|
export { MCPProtocolManager } from './protocol-manager.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/mcp/index.ts"],"sourcesContent":["/**\n * MCP (Model Context Protocol) Module\n * Export all MCP components for easy integration\n */\n\n// Phase 6: In-Process MCP Server (10-100x performance improvement)\nexport { InProcessMCPServer, createInProcessServer } from './in-process-server.js';\nexport type { InProcessServerConfig, ToolCallMetrics } from './in-process-server.js';\n\nexport {\n ClaudeFlowToolRegistry,\n createToolRegistry,\n createClaudeFlowSdkServer,\n} from './tool-registry.js';\nexport type { ToolRegistryConfig } from './tool-registry.js';\n\nexport {\n SDKIntegration,\n initializeSDKIntegration,\n getSDKIntegration,\n createInProcessQuery,\n getInProcessServerConfig,\n measurePerformance,\n} from './sdk-integration.js';\nexport type { SDKIntegrationConfig } from './sdk-integration.js';\n\n// Core MCP Server\nexport { MCPServer, type IMCPServer } from './server.js';\n\n// Lifecycle Management\nexport {\n MCPLifecycleManager,\n LifecycleState,\n type LifecycleEvent,\n type HealthCheckResult,\n type LifecycleManagerConfig,\n} from './lifecycle-manager.js';\n\n// Tool Registry and Management\nexport {\n ToolRegistry,\n type ToolCapability,\n type ToolMetrics,\n type ToolDiscoveryQuery,\n} from './tools.js';\n\n// Protocol Management\nexport {\n MCPProtocolManager,\n type ProtocolVersionInfo,\n type CompatibilityResult,\n type NegotiationResult,\n} from './protocol-manager.js';\n\n// Authentication and Authorization\nexport {\n AuthManager,\n type IAuthManager,\n type AuthContext,\n type AuthResult,\n type TokenInfo,\n type TokenGenerationOptions,\n type AuthSession,\n Permissions,\n} from './auth.js';\n\n// Performance Monitoring\nexport {\n MCPPerformanceMonitor,\n type PerformanceMetrics,\n type RequestMetrics,\n type AlertRule,\n type Alert,\n type OptimizationSuggestion,\n} from './performance-monitor.js';\n\n// Orchestration Integration\nexport {\n MCPOrchestrationIntegration,\n type OrchestrationComponents,\n type MCPOrchestrationConfig,\n type IntegrationStatus,\n} from './orchestration-integration.js';\n\n// Transport Implementations\nexport { type ITransport } from './transports/base.js';\nexport { StdioTransport } from './transports/stdio.js';\nexport { HttpTransport } from './transports/http.js';\n\n// Request Routing\nexport { RequestRouter } from './router.js';\n\n// Session Management\nexport { SessionManager, type ISessionManager } from './session-manager.js';\n\n// Load Balancing\nexport { LoadBalancer, type ILoadBalancer, RequestQueue } from './load-balancer.js';\n\n// Tool Implementations\nexport { createClaudeFlowTools, type ClaudeFlowToolContext } from './claude-flow-tools.js';\nexport { createSwarmTools, type SwarmToolContext } from './swarm-tools.js';\n\n/**\n * MCP Integration Factory\n * Provides a simple way to create a complete MCP integration\n */\nexport class MCPIntegrationFactory {\n /**\n * Create a complete MCP integration with all components\n */\n static async createIntegration(config: {\n mcpConfig: import('../utils/types.js').MCPConfig;\n orchestrationConfig?: Partial<MCPOrchestrationConfig>;\n components?: Partial<OrchestrationComponents>;\n logger: import('../core/logger.js').ILogger;\n }): Promise<MCPOrchestrationIntegration> {\n const { mcpConfig, orchestrationConfig = {}, components = {}, logger } = config;\n\n const integration = new MCPOrchestrationIntegration(\n mcpConfig,\n {\n enabledIntegrations: {\n orchestrator: true,\n swarm: true,\n agents: true,\n resources: true,\n memory: true,\n monitoring: true,\n terminals: true,\n },\n autoStart: true,\n healthCheckInterval: 30000,\n reconnectAttempts: 3,\n reconnectDelay: 5000,\n enableMetrics: true,\n enableAlerts: true,\n ...orchestrationConfig,\n },\n components,\n logger,\n );\n\n return integration;\n }\n\n /**\n * Create a standalone MCP server (without orchestration integration)\n */\n static async createStandaloneServer(config: {\n mcpConfig: import('../utils/types.js').MCPConfig;\n logger: import('../core/logger.js').ILogger;\n enableLifecycleManagement?: boolean;\n enablePerformanceMonitoring?: boolean;\n }): Promise<{\n server: MCPServer;\n lifecycleManager?: MCPLifecycleManager;\n performanceMonitor?: MCPPerformanceMonitor;\n }> {\n const {\n mcpConfig,\n logger,\n enableLifecycleManagement = true,\n enablePerformanceMonitoring = true,\n } = config;\n\n const eventBus = new (await import('node:events')).EventEmitter();\n const server = new MCPServer(mcpConfig, eventBus, logger);\n\n let lifecycleManager: MCPLifecycleManager | undefined;\n let performanceMonitor: MCPPerformanceMonitor | undefined;\n\n if (enableLifecycleManagement) {\n lifecycleManager = new MCPLifecycleManager(mcpConfig, logger, () => server);\n }\n\n if (enablePerformanceMonitoring) {\n performanceMonitor = new MCPPerformanceMonitor(logger);\n }\n\n return {\n server,\n lifecycleManager,\n performanceMonitor,\n };\n }\n\n /**\n * Create a development/testing MCP setup\n */\n static async createDevelopmentSetup(logger: import('../core/logger.js').ILogger): Promise<{\n server: MCPServer;\n lifecycleManager: MCPLifecycleManager;\n performanceMonitor: MCPPerformanceMonitor;\n protocolManager: MCPProtocolManager;\n }> {\n const mcpConfig: import('../utils/types.js').MCPConfig = {\n transport: 'stdio',\n enableMetrics: true,\n auth: {\n enabled: false,\n method: 'token',\n },\n };\n\n const { server, lifecycleManager, performanceMonitor } = await this.createStandaloneServer({\n mcpConfig,\n logger,\n enableLifecycleManagement: true,\n enablePerformanceMonitoring: true,\n });\n\n const protocolManager = new MCPProtocolManager(logger);\n\n return {\n server,\n lifecycleManager: lifecycleManager!,\n performanceMonitor: performanceMonitor!,\n protocolManager,\n };\n }\n}\n\n/**\n * Default MCP configuration for common use cases\n */\nexport const DefaultMCPConfigs = {\n /**\n * Development configuration with stdio transport\n */\n development: {\n transport: 'stdio' as const,\n enableMetrics: true,\n auth: {\n enabled: false,\n method: 'token' as const,\n },\n },\n\n /**\n * Production configuration with HTTP transport and authentication\n */\n production: {\n transport: 'http' as const,\n host: '0.0.0.0',\n port: 3000,\n tlsEnabled: true,\n enableMetrics: true,\n auth: {\n enabled: true,\n method: 'token' as const,\n },\n loadBalancer: {\n enabled: true,\n maxRequestsPerSecond: 100,\n maxConcurrentRequests: 50,\n },\n sessionTimeout: 3600000, // 1 hour\n maxSessions: 1000,\n },\n\n /**\n * Testing configuration with minimal features\n */\n testing: {\n transport: 'stdio' as const,\n enableMetrics: false,\n auth: {\n enabled: false,\n method: 'token' as const,\n },\n },\n} as const;\n\n/**\n * MCP Utility Functions\n */\nexport const MCPUtils = {\n /**\n * Validate MCP protocol version\n */\n isValidProtocolVersion(version: import('../utils/types.js').MCPProtocolVersion): boolean {\n return (\n typeof version.major === 'number' &&\n typeof version.minor === 'number' &&\n typeof version.patch === 'number' &&\n version.major > 0\n );\n },\n\n /**\n * Compare two protocol versions\n */\n compareVersions(\n a: import('../utils/types.js').MCPProtocolVersion,\n b: import('../utils/types.js').MCPProtocolVersion,\n ): number {\n if (a.major !== b.major) return a.major - b.major;\n if (a.minor !== b.minor) return a.minor - b.minor;\n return a.patch - b.patch;\n },\n\n /**\n * Format protocol version as string\n */\n formatVersion(version: import('../utils/types.js').MCPProtocolVersion): string {\n return `${version.major}.${version.minor}.${version.patch}`;\n },\n\n /**\n * Parse protocol version from string\n */\n parseVersion(versionString: string): import('../utils/types.js').MCPProtocolVersion {\n const parts = versionString.split('.').map((p) => parseInt(p, 10));\n if (parts.length !== 3 || parts.some((p) => isNaN(p))) {\n throw new Error(`Invalid version string: ${versionString}`);\n }\n return {\n major: parts[0],\n minor: parts[1],\n patch: parts[2],\n };\n },\n\n /**\n * Generate a random session ID\n */\n generateSessionId(): string {\n return `mcp_session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;\n },\n\n /**\n * Generate a random request ID\n */\n generateRequestId(): string {\n return `mcp_req_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;\n },\n};\n\n/**\n * Phase 6: Initialize MCP with in-process server for maximum performance\n *\n * Provides 10-100x performance improvement by eliminating IPC overhead.\n * All Claude-Flow MCP tools execute in-process with microsecond latency.\n */\nexport async function initializeInProcessMCP(orchestratorContext?: any) {\n const { initializeSDKIntegration } = await import('./sdk-integration.js');\n\n return initializeSDKIntegration({\n enableInProcess: true,\n enableMetrics: true,\n enableCaching: true,\n orchestratorContext,\n fallbackToStdio: true,\n });\n}\n\n/**\n * Phase 6: Get in-process server status and performance metrics\n */\nexport async function getInProcessMCPStatus() {\n const { getSDKIntegration } = await import('./sdk-integration.js');\n const integration = getSDKIntegration();\n\n if (!integration) {\n return {\n initialized: false,\n inProcess: false,\n message: 'In-process MCP not initialized',\n };\n }\n\n return {\n initialized: true,\n inProcess: integration.isInProcessAvailable(),\n metrics: integration.getMetrics(),\n performanceComparison: integration.getPerformanceComparison(),\n };\n}\n"],"names":["InProcessMCPServer","createInProcessServer","ClaudeFlowToolRegistry","createToolRegistry","createClaudeFlowSdkServer","SDKIntegration","initializeSDKIntegration","getSDKIntegration","createInProcessQuery","getInProcessServerConfig","measurePerformance","MCPServer","MCPLifecycleManager","LifecycleState","ToolRegistry","MCPProtocolManager","AuthManager","Permissions","MCPPerformanceMonitor","MCPOrchestrationIntegration","StdioTransport","HttpTransport","RequestRouter","SessionManager","LoadBalancer","RequestQueue","createClaudeFlowTools","createSwarmTools","MCPIntegrationFactory","createIntegration","config","mcpConfig","orchestrationConfig","components","logger","integration","enabledIntegrations","orchestrator","swarm","agents","resources","memory","monitoring","terminals","autoStart","healthCheckInterval","reconnectAttempts","reconnectDelay","enableMetrics","enableAlerts","createStandaloneServer","enableLifecycleManagement","enablePerformanceMonitoring","eventBus","EventEmitter","server","lifecycleManager","performanceMonitor","createDevelopmentSetup","transport","auth","enabled","method","protocolManager","DefaultMCPConfigs","development","production","host","port","tlsEnabled","loadBalancer","maxRequestsPerSecond","maxConcurrentRequests","sessionTimeout","maxSessions","testing","MCPUtils","isValidProtocolVersion","version","major","minor","patch","compareVersions","a","b","formatVersion","parseVersion","versionString","parts","split","map","p","parseInt","length","some","isNaN","Error","generateSessionId","Date","now","Math","random","toString","substring","generateRequestId","initializeInProcessMCP","orchestratorContext","enableInProcess","enableCaching","fallbackToStdio","getInProcessMCPStatus","initialized","inProcess","message","isInProcessAvailable","metrics","getMetrics","performanceComparison","getPerformanceComparison"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/mcp/index.ts"],"sourcesContent":["/**\n * MCP (Model Context Protocol) Module\n * Export all MCP components for easy integration\n */\n\n// Phase 6: In-Process MCP Server (10-100x performance improvement)\nexport { InProcessMCPServer, createInProcessServer } from './in-process-server.js';\nexport type { InProcessServerConfig, ToolCallMetrics } from './in-process-server.js';\n\nexport {\n ClaudeFlowToolRegistry,\n createToolRegistry,\n createClaudeFlowSdkServer,\n} from './tool-registry.js';\nexport type { ToolRegistryConfig } from './tool-registry.js';\n\nexport {\n SDKIntegration,\n initializeSDKIntegration,\n getSDKIntegration,\n createInProcessQuery,\n getInProcessServerConfig,\n measurePerformance,\n} from './sdk-integration.js';\nexport type { SDKIntegrationConfig } from './sdk-integration.js';\n\n// Core MCP Server\nexport { MCPServer, type IMCPServer } from './server.js';\n\n// MCP 2025-11 Server and Components\nexport { MCP2025Server, type MCP2025ServerConfig } from './server-mcp-2025.js';\nexport {\n MCPServerFactory,\n createMCPServer,\n isMCP2025Available,\n getServerCapabilities,\n type MCPFeatureFlags,\n type ExtendedMCPConfig,\n} from './server-factory.js';\n\n// MCP 2025-11 Protocol Components\nexport {\n VersionNegotiator,\n BackwardCompatibilityAdapter,\n type MCPHandshake,\n type MCPVersion,\n type MCPCapability,\n type NegotiationResult as MCP2025NegotiationResult,\n} from './protocol/version-negotiation.js';\n\n// MCP 2025-11 Async Job Management\nexport {\n MCPAsyncJobManager,\n type MCPToolRequest,\n type MCPJobHandle,\n type MCPJobResult,\n type AsyncJob,\n type JobStatus,\n} from './async/job-manager-mcp25.js';\n\n// MCP 2025-11 Registry Integration\nexport {\n MCPRegistryClient,\n type RegistryConfig,\n type ServerRegistryEntry,\n} from './registry/mcp-registry-client-2025.js';\n\n// MCP 2025-11 Schema Validation\nexport {\n SchemaValidator,\n upgradeToolSchema,\n type ValidationResult,\n} from './validation/schema-validator-2025.js';\n\n// Progressive Tool Registry (Phase 1 & 2)\nexport {\n ProgressiveToolRegistry,\n createProgressiveToolRegistry,\n createProgressiveClaudeFlowSdkServer,\n type ProgressiveToolRegistryConfig,\n} from './tool-registry-progressive.js';\n\n// Dynamic Tool Loader (Phase 1)\nexport {\n DynamicToolLoader,\n type ToolMetadata,\n type ToolSearchQuery,\n} from './tools/loader.js';\n\n// Lifecycle Management\nexport {\n MCPLifecycleManager,\n LifecycleState,\n type LifecycleEvent,\n type HealthCheckResult,\n type LifecycleManagerConfig,\n} from './lifecycle-manager.js';\n\n// Tool Registry and Management\nexport {\n ToolRegistry,\n type ToolCapability,\n type ToolMetrics,\n type ToolDiscoveryQuery,\n} from './tools.js';\n\n// Protocol Management\nexport {\n MCPProtocolManager,\n type ProtocolVersionInfo,\n type CompatibilityResult,\n type NegotiationResult,\n} from './protocol-manager.js';\n\n// Authentication and Authorization\nexport {\n AuthManager,\n type IAuthManager,\n type AuthContext,\n type AuthResult,\n type TokenInfo,\n type TokenGenerationOptions,\n type AuthSession,\n Permissions,\n} from './auth.js';\n\n// Performance Monitoring\nexport {\n MCPPerformanceMonitor,\n type PerformanceMetrics,\n type RequestMetrics,\n type AlertRule,\n type Alert,\n type OptimizationSuggestion,\n} from './performance-monitor.js';\n\n// Orchestration Integration\nexport {\n MCPOrchestrationIntegration,\n type OrchestrationComponents,\n type MCPOrchestrationConfig,\n type IntegrationStatus,\n} from './orchestration-integration.js';\n\n// Transport Implementations\nexport { type ITransport } from './transports/base.js';\nexport { StdioTransport } from './transports/stdio.js';\nexport { HttpTransport } from './transports/http.js';\n\n// Request Routing\nexport { RequestRouter } from './router.js';\n\n// Session Management\nexport { SessionManager, type ISessionManager } from './session-manager.js';\n\n// Load Balancing\nexport { LoadBalancer, type ILoadBalancer, RequestQueue } from './load-balancer.js';\n\n// Tool Implementations\nexport { createClaudeFlowTools, type ClaudeFlowToolContext } from './claude-flow-tools.js';\nexport { createSwarmTools, type SwarmToolContext } from './swarm-tools.js';\n\n/**\n * MCP Integration Factory\n * Provides a simple way to create a complete MCP integration\n */\nexport class MCPIntegrationFactory {\n /**\n * Create a complete MCP integration with all components\n */\n static async createIntegration(config: {\n mcpConfig: import('../utils/types.js').MCPConfig;\n orchestrationConfig?: Partial<MCPOrchestrationConfig>;\n components?: Partial<OrchestrationComponents>;\n logger: import('../core/logger.js').ILogger;\n }): Promise<MCPOrchestrationIntegration> {\n const { mcpConfig, orchestrationConfig = {}, components = {}, logger } = config;\n\n const integration = new MCPOrchestrationIntegration(\n mcpConfig,\n {\n enabledIntegrations: {\n orchestrator: true,\n swarm: true,\n agents: true,\n resources: true,\n memory: true,\n monitoring: true,\n terminals: true,\n },\n autoStart: true,\n healthCheckInterval: 30000,\n reconnectAttempts: 3,\n reconnectDelay: 5000,\n enableMetrics: true,\n enableAlerts: true,\n ...orchestrationConfig,\n },\n components,\n logger,\n );\n\n return integration;\n }\n\n /**\n * Create a standalone MCP server (without orchestration integration)\n */\n static async createStandaloneServer(config: {\n mcpConfig: import('../utils/types.js').MCPConfig;\n logger: import('../core/logger.js').ILogger;\n enableLifecycleManagement?: boolean;\n enablePerformanceMonitoring?: boolean;\n }): Promise<{\n server: MCPServer;\n lifecycleManager?: MCPLifecycleManager;\n performanceMonitor?: MCPPerformanceMonitor;\n }> {\n const {\n mcpConfig,\n logger,\n enableLifecycleManagement = true,\n enablePerformanceMonitoring = true,\n } = config;\n\n const eventBus = new (await import('node:events')).EventEmitter();\n const server = new MCPServer(mcpConfig, eventBus, logger);\n\n let lifecycleManager: MCPLifecycleManager | undefined;\n let performanceMonitor: MCPPerformanceMonitor | undefined;\n\n if (enableLifecycleManagement) {\n lifecycleManager = new MCPLifecycleManager(mcpConfig, logger, () => server);\n }\n\n if (enablePerformanceMonitoring) {\n performanceMonitor = new MCPPerformanceMonitor(logger);\n }\n\n return {\n server,\n lifecycleManager,\n performanceMonitor,\n };\n }\n\n /**\n * Create a development/testing MCP setup\n */\n static async createDevelopmentSetup(logger: import('../core/logger.js').ILogger): Promise<{\n server: MCPServer;\n lifecycleManager: MCPLifecycleManager;\n performanceMonitor: MCPPerformanceMonitor;\n protocolManager: MCPProtocolManager;\n }> {\n const mcpConfig: import('../utils/types.js').MCPConfig = {\n transport: 'stdio',\n enableMetrics: true,\n auth: {\n enabled: false,\n method: 'token',\n },\n };\n\n const { server, lifecycleManager, performanceMonitor } = await this.createStandaloneServer({\n mcpConfig,\n logger,\n enableLifecycleManagement: true,\n enablePerformanceMonitoring: true,\n });\n\n const protocolManager = new MCPProtocolManager(logger);\n\n return {\n server,\n lifecycleManager: lifecycleManager!,\n performanceMonitor: performanceMonitor!,\n protocolManager,\n };\n }\n}\n\n/**\n * Default MCP configuration for common use cases\n */\nexport const DefaultMCPConfigs = {\n /**\n * Development configuration with stdio transport\n */\n development: {\n transport: 'stdio' as const,\n enableMetrics: true,\n auth: {\n enabled: false,\n method: 'token' as const,\n },\n },\n\n /**\n * Production configuration with HTTP transport and authentication\n */\n production: {\n transport: 'http' as const,\n host: '0.0.0.0',\n port: 3000,\n tlsEnabled: true,\n enableMetrics: true,\n auth: {\n enabled: true,\n method: 'token' as const,\n },\n loadBalancer: {\n enabled: true,\n maxRequestsPerSecond: 100,\n maxConcurrentRequests: 50,\n },\n sessionTimeout: 3600000, // 1 hour\n maxSessions: 1000,\n },\n\n /**\n * Testing configuration with minimal features\n */\n testing: {\n transport: 'stdio' as const,\n enableMetrics: false,\n auth: {\n enabled: false,\n method: 'token' as const,\n },\n },\n} as const;\n\n/**\n * MCP Utility Functions\n */\nexport const MCPUtils = {\n /**\n * Validate MCP protocol version\n */\n isValidProtocolVersion(version: import('../utils/types.js').MCPProtocolVersion): boolean {\n return (\n typeof version.major === 'number' &&\n typeof version.minor === 'number' &&\n typeof version.patch === 'number' &&\n version.major > 0\n );\n },\n\n /**\n * Compare two protocol versions\n */\n compareVersions(\n a: import('../utils/types.js').MCPProtocolVersion,\n b: import('../utils/types.js').MCPProtocolVersion,\n ): number {\n if (a.major !== b.major) return a.major - b.major;\n if (a.minor !== b.minor) return a.minor - b.minor;\n return a.patch - b.patch;\n },\n\n /**\n * Format protocol version as string\n */\n formatVersion(version: import('../utils/types.js').MCPProtocolVersion): string {\n return `${version.major}.${version.minor}.${version.patch}`;\n },\n\n /**\n * Parse protocol version from string\n */\n parseVersion(versionString: string): import('../utils/types.js').MCPProtocolVersion {\n const parts = versionString.split('.').map((p) => parseInt(p, 10));\n if (parts.length !== 3 || parts.some((p) => isNaN(p))) {\n throw new Error(`Invalid version string: ${versionString}`);\n }\n return {\n major: parts[0],\n minor: parts[1],\n patch: parts[2],\n };\n },\n\n /**\n * Generate a random session ID\n */\n generateSessionId(): string {\n return `mcp_session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;\n },\n\n /**\n * Generate a random request ID\n */\n generateRequestId(): string {\n return `mcp_req_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;\n },\n};\n\n/**\n * Phase 6: Initialize MCP with in-process server for maximum performance\n *\n * Provides 10-100x performance improvement by eliminating IPC overhead.\n * All Claude-Flow MCP tools execute in-process with microsecond latency.\n */\nexport async function initializeInProcessMCP(orchestratorContext?: any) {\n const { initializeSDKIntegration } = await import('./sdk-integration.js');\n\n return initializeSDKIntegration({\n enableInProcess: true,\n enableMetrics: true,\n enableCaching: true,\n orchestratorContext,\n fallbackToStdio: true,\n });\n}\n\n/**\n * Phase 6: Get in-process server status and performance metrics\n */\nexport async function getInProcessMCPStatus() {\n const { getSDKIntegration } = await import('./sdk-integration.js');\n const integration = getSDKIntegration();\n\n if (!integration) {\n return {\n initialized: false,\n inProcess: false,\n message: 'In-process MCP not initialized',\n };\n }\n\n return {\n initialized: true,\n inProcess: integration.isInProcessAvailable(),\n metrics: integration.getMetrics(),\n performanceComparison: integration.getPerformanceComparison(),\n };\n}\n"],"names":["InProcessMCPServer","createInProcessServer","ClaudeFlowToolRegistry","createToolRegistry","createClaudeFlowSdkServer","SDKIntegration","initializeSDKIntegration","getSDKIntegration","createInProcessQuery","getInProcessServerConfig","measurePerformance","MCPServer","MCP2025Server","MCPServerFactory","createMCPServer","isMCP2025Available","getServerCapabilities","VersionNegotiator","BackwardCompatibilityAdapter","MCPAsyncJobManager","MCPRegistryClient","SchemaValidator","upgradeToolSchema","ProgressiveToolRegistry","createProgressiveToolRegistry","createProgressiveClaudeFlowSdkServer","DynamicToolLoader","MCPLifecycleManager","LifecycleState","ToolRegistry","MCPProtocolManager","AuthManager","Permissions","MCPPerformanceMonitor","MCPOrchestrationIntegration","StdioTransport","HttpTransport","RequestRouter","SessionManager","LoadBalancer","RequestQueue","createClaudeFlowTools","createSwarmTools","MCPIntegrationFactory","createIntegration","config","mcpConfig","orchestrationConfig","components","logger","integration","enabledIntegrations","orchestrator","swarm","agents","resources","memory","monitoring","terminals","autoStart","healthCheckInterval","reconnectAttempts","reconnectDelay","enableMetrics","enableAlerts","createStandaloneServer","enableLifecycleManagement","enablePerformanceMonitoring","eventBus","EventEmitter","server","lifecycleManager","performanceMonitor","createDevelopmentSetup","transport","auth","enabled","method","protocolManager","DefaultMCPConfigs","development","production","host","port","tlsEnabled","loadBalancer","maxRequestsPerSecond","maxConcurrentRequests","sessionTimeout","maxSessions","testing","MCPUtils","isValidProtocolVersion","version","major","minor","patch","compareVersions","a","b","formatVersion","parseVersion","versionString","parts","split","map","p","parseInt","length","some","isNaN","Error","generateSessionId","Date","now","Math","random","toString","substring","generateRequestId","initializeInProcessMCP","orchestratorContext","enableInProcess","enableCaching","fallbackToStdio","getInProcessMCPStatus","initialized","inProcess","message","isInProcessAvailable","metrics","getMetrics","performanceComparison","getPerformanceComparison"],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
export class VersionNegotiationError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(message, code){
|
|
4
|
+
super(message), this.code = code;
|
|
5
|
+
this.name = 'VersionNegotiationError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class VersionNegotiator {
|
|
9
|
+
logger;
|
|
10
|
+
supportedVersions = [
|
|
11
|
+
'2025-11',
|
|
12
|
+
'2024-11'
|
|
13
|
+
];
|
|
14
|
+
serverVersion = '2025-11';
|
|
15
|
+
serverCapabilities = [
|
|
16
|
+
'async',
|
|
17
|
+
'registry',
|
|
18
|
+
'code_exec',
|
|
19
|
+
'stream'
|
|
20
|
+
];
|
|
21
|
+
constructor(logger){
|
|
22
|
+
this.logger = logger;
|
|
23
|
+
}
|
|
24
|
+
async negotiate(clientHandshake) {
|
|
25
|
+
this.logger.info('Starting version negotiation', {
|
|
26
|
+
clientVersion: clientHandshake.mcp_version,
|
|
27
|
+
serverVersion: this.serverVersion,
|
|
28
|
+
clientCapabilities: clientHandshake.capabilities
|
|
29
|
+
});
|
|
30
|
+
if (!this.isValidHandshake(clientHandshake)) {
|
|
31
|
+
return {
|
|
32
|
+
success: false,
|
|
33
|
+
agreed_version: this.serverVersion,
|
|
34
|
+
agreed_capabilities: [],
|
|
35
|
+
error: 'Invalid handshake structure'
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const versionResult = this.checkVersionCompatibility(clientHandshake.mcp_version);
|
|
39
|
+
if (!versionResult.compatible) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
agreed_version: this.serverVersion,
|
|
43
|
+
agreed_capabilities: [],
|
|
44
|
+
error: versionResult.error
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const agreedCapabilities = this.negotiateCapabilities(clientHandshake.capabilities);
|
|
48
|
+
this.logger.info('Version negotiation successful', {
|
|
49
|
+
agreedVersion: versionResult.version,
|
|
50
|
+
agreedCapabilities
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
agreed_version: versionResult.version,
|
|
55
|
+
agreed_capabilities: agreedCapabilities
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
isValidHandshake(handshake) {
|
|
59
|
+
return !!(handshake.mcp_version && handshake.transport && Array.isArray(handshake.capabilities));
|
|
60
|
+
}
|
|
61
|
+
checkVersionCompatibility(clientVersion) {
|
|
62
|
+
if (clientVersion === this.serverVersion) {
|
|
63
|
+
return {
|
|
64
|
+
compatible: true,
|
|
65
|
+
version: clientVersion
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (this.supportedVersions.includes(clientVersion)) {
|
|
69
|
+
this.logger.warn('Client using older version, but compatible', {
|
|
70
|
+
clientVersion,
|
|
71
|
+
serverVersion: this.serverVersion
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
compatible: true,
|
|
75
|
+
version: clientVersion
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const clientDate = this.parseVersion(clientVersion);
|
|
79
|
+
const serverDate = this.parseVersion(this.serverVersion);
|
|
80
|
+
const monthsDiff = this.getMonthsDifference(clientDate, serverDate);
|
|
81
|
+
if (Math.abs(monthsDiff) > 1) {
|
|
82
|
+
return {
|
|
83
|
+
compatible: false,
|
|
84
|
+
version: this.serverVersion,
|
|
85
|
+
error: `Version mismatch: client ${clientVersion}, server ${this.serverVersion}. Difference exceeds 1 cycle.`
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
this.logger.warn('Version close enough, accepting', {
|
|
89
|
+
clientVersion,
|
|
90
|
+
serverVersion: this.serverVersion,
|
|
91
|
+
monthsDiff
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
compatible: true,
|
|
95
|
+
version: this.serverVersion
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
negotiateCapabilities(clientCapabilities) {
|
|
99
|
+
return clientCapabilities.filter((cap)=>this.serverCapabilities.includes(cap));
|
|
100
|
+
}
|
|
101
|
+
parseVersion(version) {
|
|
102
|
+
const [year, month] = version.split('-').map(Number);
|
|
103
|
+
return new Date(year, month - 1, 1);
|
|
104
|
+
}
|
|
105
|
+
getMonthsDifference(date1, date2) {
|
|
106
|
+
const months = (date2.getFullYear() - date1.getFullYear()) * 12;
|
|
107
|
+
return months + date2.getMonth() - date1.getMonth();
|
|
108
|
+
}
|
|
109
|
+
createServerHandshake(serverId, transport, metadata) {
|
|
110
|
+
return {
|
|
111
|
+
mcp_version: this.serverVersion,
|
|
112
|
+
server_id: serverId,
|
|
113
|
+
transport,
|
|
114
|
+
capabilities: this.serverCapabilities,
|
|
115
|
+
metadata
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
getServerVersion() {
|
|
119
|
+
return this.serverVersion;
|
|
120
|
+
}
|
|
121
|
+
getServerCapabilities() {
|
|
122
|
+
return [
|
|
123
|
+
...this.serverCapabilities
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
hasCapability(capability) {
|
|
127
|
+
return this.serverCapabilities.includes(capability);
|
|
128
|
+
}
|
|
129
|
+
addCapability(capability) {
|
|
130
|
+
if (!this.serverCapabilities.includes(capability)) {
|
|
131
|
+
this.serverCapabilities.push(capability);
|
|
132
|
+
this.logger.info('Capability added', {
|
|
133
|
+
capability
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
removeCapability(capability) {
|
|
138
|
+
const index = this.serverCapabilities.indexOf(capability);
|
|
139
|
+
if (index > -1) {
|
|
140
|
+
this.serverCapabilities.splice(index, 1);
|
|
141
|
+
this.logger.info('Capability removed', {
|
|
142
|
+
capability
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export class BackwardCompatibilityAdapter {
|
|
148
|
+
logger;
|
|
149
|
+
constructor(logger){
|
|
150
|
+
this.logger = logger;
|
|
151
|
+
}
|
|
152
|
+
isLegacyRequest(request) {
|
|
153
|
+
return !request.mcp_version || request.version;
|
|
154
|
+
}
|
|
155
|
+
convertToModern(legacyRequest) {
|
|
156
|
+
this.logger.info('Converting legacy request to MCP 2025-11 format');
|
|
157
|
+
return {
|
|
158
|
+
mcp_version: '2025-11',
|
|
159
|
+
client_id: legacyRequest.clientId || 'legacy-client',
|
|
160
|
+
transport: legacyRequest.transport || 'stdio',
|
|
161
|
+
capabilities: legacyRequest.capabilities || [],
|
|
162
|
+
metadata: {
|
|
163
|
+
name: legacyRequest.name || 'Legacy Client',
|
|
164
|
+
version: legacyRequest.version || '1.0.0'
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
convertToLegacy(modernResponse, requestedLegacy) {
|
|
169
|
+
if (!requestedLegacy) {
|
|
170
|
+
return modernResponse;
|
|
171
|
+
}
|
|
172
|
+
this.logger.info('Converting response to legacy format');
|
|
173
|
+
return {
|
|
174
|
+
version: modernResponse.mcp_version,
|
|
175
|
+
serverId: modernResponse.server_id,
|
|
176
|
+
capabilities: modernResponse.capabilities,
|
|
177
|
+
...modernResponse
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
//# sourceMappingURL=version-negotiation.js.map
|