@evolith/smart-cli 0.0.1-beta → 0.0.3-beta
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/ARCHITECTURE.md +667 -89
- package/dist/app.module.js +2 -2
- package/dist/app.module.js.map +1 -1
- package/dist/app.module.spec.d.ts +1 -0
- package/dist/app.module.spec.js +305 -0
- package/dist/app.module.spec.js.map +1 -0
- package/dist/application/services/index.d.ts +14 -5
- package/dist/application/services/index.js +41 -3
- package/dist/application/services/index.js.map +1 -1
- package/dist/application/services/phase-transition.use-case.spec.d.ts +1 -0
- package/dist/application/services/phase-transition.use-case.spec.js +297 -0
- package/dist/application/services/phase-transition.use-case.spec.js.map +1 -0
- package/dist/commands/adr/adr.command.spec.d.ts +1 -0
- package/dist/commands/adr/adr.command.spec.js +409 -0
- package/dist/commands/adr/adr.command.spec.js.map +1 -0
- package/dist/commands/architecture/scaffold.command.spec.d.ts +1 -0
- package/dist/commands/architecture/scaffold.command.spec.js +207 -0
- package/dist/commands/architecture/scaffold.command.spec.js.map +1 -0
- package/dist/commands/completion/completion.command.spec.d.ts +1 -0
- package/dist/commands/completion/completion.command.spec.js +240 -0
- package/dist/commands/completion/completion.command.spec.js.map +1 -0
- package/dist/commands/docs/docs.command.d.ts +5 -0
- package/dist/commands/docs/docs.command.js +159 -3
- package/dist/commands/docs/docs.command.js.map +1 -1
- package/dist/commands/docs/docs.command.spec.d.ts +1 -0
- package/dist/commands/docs/docs.command.spec.js +87 -0
- package/dist/commands/docs/docs.command.spec.js.map +1 -0
- package/dist/commands/drift/drift.command.d.ts +24 -0
- package/dist/commands/drift/drift.command.js +250 -0
- package/dist/commands/drift/drift.command.js.map +1 -0
- package/dist/commands/drift/drift.command.spec.d.ts +1 -0
- package/dist/commands/drift/drift.command.spec.js +327 -0
- package/dist/commands/drift/drift.command.spec.js.map +1 -0
- package/dist/commands/history/history.command.spec.d.ts +1 -0
- package/dist/commands/history/history.command.spec.js +392 -0
- package/dist/commands/history/history.command.spec.js.map +1 -0
- package/dist/commands/init/agents.command.spec.d.ts +1 -0
- package/dist/commands/init/agents.command.spec.js +550 -0
- package/dist/commands/init/agents.command.spec.js.map +1 -0
- package/dist/commands/init/init.command.spec.d.ts +1 -0
- package/dist/commands/init/init.command.spec.js +272 -0
- package/dist/commands/init/init.command.spec.js.map +1 -0
- package/dist/commands/init/upgrade.command.d.ts +10 -0
- package/dist/commands/init/upgrade.command.js +134 -1
- package/dist/commands/init/upgrade.command.js.map +1 -1
- package/dist/commands/init/upgrade.command.spec.d.ts +1 -0
- package/dist/commands/init/upgrade.command.spec.js +378 -0
- package/dist/commands/init/upgrade.command.spec.js.map +1 -0
- package/dist/commands/mcp/mcp-serve.command.spec.d.ts +1 -0
- package/dist/commands/mcp/mcp-serve.command.spec.js +58 -0
- package/dist/commands/mcp/mcp-serve.command.spec.js.map +1 -0
- package/dist/commands/sdlc/gate-status.command.d.ts +5 -0
- package/dist/commands/sdlc/gate-status.command.js +114 -0
- package/dist/commands/sdlc/gate-status.command.js.map +1 -0
- package/dist/commands/sdlc/generate-domain.command.spec.d.ts +1 -0
- package/dist/commands/sdlc/generate-domain.command.spec.js +47 -0
- package/dist/commands/sdlc/generate-domain.command.spec.js.map +1 -0
- package/dist/commands/sdlc/handoff.command.spec.d.ts +1 -0
- package/dist/commands/sdlc/handoff.command.spec.js +395 -0
- package/dist/commands/sdlc/handoff.command.spec.js.map +1 -0
- package/dist/commands/sdlc/sdlc.command.js +3 -1
- package/dist/commands/sdlc/sdlc.command.js.map +1 -1
- package/dist/commands/sdlc/sdlc.command.spec.d.ts +1 -0
- package/dist/commands/sdlc/sdlc.command.spec.js +45 -0
- package/dist/commands/sdlc/sdlc.command.spec.js.map +1 -0
- package/dist/commands/standards/standards.command.spec.d.ts +1 -0
- package/dist/commands/standards/standards.command.spec.js +311 -0
- package/dist/commands/standards/standards.command.spec.js.map +1 -0
- package/dist/commands/validate/validate.command.d.ts +4 -0
- package/dist/commands/validate/validate.command.js +39 -0
- package/dist/commands/validate/validate.command.js.map +1 -1
- package/dist/commands/validate/validate.command.spec.d.ts +1 -0
- package/dist/commands/validate/validate.command.spec.js +368 -0
- package/dist/commands/validate/validate.command.spec.js.map +1 -0
- package/dist/core/abstractions/providers/logger.provider.spec.d.ts +1 -0
- package/dist/core/abstractions/providers/logger.provider.spec.js +212 -0
- package/dist/core/abstractions/providers/logger.provider.spec.js.map +1 -0
- package/dist/core/agents/agent-ruleset-builder.d.ts +30 -0
- package/dist/core/agents/agent-ruleset-builder.js +75 -0
- package/dist/core/agents/agent-ruleset-builder.js.map +1 -0
- package/dist/core/agents/agent-ruleset-builder.spec.d.ts +1 -0
- package/dist/core/agents/agent-ruleset-builder.spec.js +135 -0
- package/dist/core/agents/agent-ruleset-builder.spec.js.map +1 -0
- package/dist/core/di/container.spec.js +164 -0
- package/dist/core/di/container.spec.js.map +1 -1
- package/dist/core/mcp/metrics.service.spec.d.ts +1 -0
- package/dist/core/mcp/metrics.service.spec.js +159 -0
- package/dist/core/mcp/metrics.service.spec.js.map +1 -0
- package/dist/core/mcp/prompts/index.js +36 -0
- package/dist/core/mcp/prompts/index.js.map +1 -1
- package/dist/core/mcp/prompts/index.spec.d.ts +1 -0
- package/dist/core/mcp/prompts/index.spec.js +150 -0
- package/dist/core/mcp/prompts/index.spec.js.map +1 -0
- package/dist/core/mcp/resources/index.js +16 -0
- package/dist/core/mcp/resources/index.js.map +1 -1
- package/dist/core/mcp/resources/index.spec.d.ts +1 -0
- package/dist/core/mcp/resources/index.spec.js +212 -0
- package/dist/core/mcp/resources/index.spec.js.map +1 -0
- package/dist/core/mcp/server.d.ts +15 -9
- package/dist/core/mcp/server.js +480 -174
- package/dist/core/mcp/server.js.map +1 -1
- package/dist/core/mcp/server.spec.d.ts +1 -0
- package/dist/core/mcp/server.spec.js +563 -0
- package/dist/core/mcp/server.spec.js.map +1 -0
- package/dist/core/mcp/tools/agent.spec.d.ts +1 -0
- package/dist/core/mcp/tools/agent.spec.js +171 -0
- package/dist/core/mcp/tools/agent.spec.js.map +1 -0
- package/dist/core/mcp/tools/architecture.d.ts +2 -0
- package/dist/core/mcp/tools/architecture.js +68 -0
- package/dist/core/mcp/tools/architecture.js.map +1 -1
- package/dist/core/mcp/tools/architecture.spec.d.ts +1 -0
- package/dist/core/mcp/tools/architecture.spec.js +145 -0
- package/dist/core/mcp/tools/architecture.spec.js.map +1 -0
- package/dist/core/mcp/tools/moscow.d.ts +30 -0
- package/dist/core/mcp/tools/moscow.js +113 -0
- package/dist/core/mcp/tools/moscow.js.map +1 -0
- package/dist/core/mcp/tools/moscow.spec.d.ts +1 -0
- package/dist/core/mcp/tools/moscow.spec.js +209 -0
- package/dist/core/mcp/tools/moscow.spec.js.map +1 -0
- package/dist/core/mcp/tools/sdlc.js +2 -1
- package/dist/core/mcp/tools/sdlc.js.map +1 -1
- package/dist/core/mcp/tools/sdlc.spec.d.ts +1 -0
- package/dist/core/mcp/tools/sdlc.spec.js +170 -0
- package/dist/core/mcp/tools/sdlc.spec.js.map +1 -0
- package/dist/core/mcp/tools/validate.spec.d.ts +1 -0
- package/dist/core/mcp/tools/validate.spec.js +130 -0
- package/dist/core/mcp/tools/validate.spec.js.map +1 -0
- package/dist/core/mcp/watcher.service.spec.js +109 -8
- package/dist/core/mcp/watcher.service.spec.js.map +1 -1
- package/dist/core/observability/error-reporter.spec.d.ts +1 -0
- package/dist/core/observability/error-reporter.spec.js +291 -0
- package/dist/core/observability/error-reporter.spec.js.map +1 -0
- package/dist/core/observability/structured-logger.spec.d.ts +1 -0
- package/dist/core/observability/structured-logger.spec.js +197 -0
- package/dist/core/observability/structured-logger.spec.js.map +1 -0
- package/dist/core/observability/timing.spec.d.ts +1 -0
- package/dist/core/observability/timing.spec.js +216 -0
- package/dist/core/observability/timing.spec.js.map +1 -0
- package/dist/core/services/command-history.service.spec.d.ts +1 -0
- package/dist/core/services/command-history.service.spec.js +166 -0
- package/dist/core/services/command-history.service.spec.js.map +1 -0
- package/dist/core/upgrade/satellite-upgrade.service.d.ts +48 -0
- package/dist/core/upgrade/satellite-upgrade.service.js +358 -0
- package/dist/core/upgrade/satellite-upgrade.service.js.map +1 -0
- package/dist/core/upgrade/satellite-upgrade.service.spec.d.ts +1 -0
- package/dist/core/upgrade/satellite-upgrade.service.spec.js +163 -0
- package/dist/core/upgrade/satellite-upgrade.service.spec.js.map +1 -0
- package/dist/core/validators/architecture-drift.service.d.ts +68 -0
- package/dist/core/validators/architecture-drift.service.js +266 -0
- package/dist/core/validators/architecture-drift.service.js.map +1 -0
- package/dist/core/validators/architecture-drift.service.spec.d.ts +1 -0
- package/dist/core/validators/architecture-drift.service.spec.js +315 -0
- package/dist/core/validators/architecture-drift.service.spec.js.map +1 -0
- package/dist/core/validators/deep-architecture-analyzer.d.ts +58 -0
- package/dist/core/validators/deep-architecture-analyzer.js +333 -0
- package/dist/core/validators/deep-architecture-analyzer.js.map +1 -0
- package/dist/core/validators/deep-architecture-analyzer.spec.d.ts +1 -0
- package/dist/core/validators/deep-architecture-analyzer.spec.js +216 -0
- package/dist/core/validators/deep-architecture-analyzer.spec.js.map +1 -0
- package/dist/core/validators/phase-gate-validator.service.d.ts +71 -0
- package/dist/core/validators/phase-gate-validator.service.js +273 -0
- package/dist/core/validators/phase-gate-validator.service.js.map +1 -0
- package/dist/core/validators/phase-gate-validator.service.spec.d.ts +1 -0
- package/dist/core/validators/phase-gate-validator.service.spec.js +326 -0
- package/dist/core/validators/phase-gate-validator.service.spec.js.map +1 -0
- package/dist/core/validators/ruleset-validator-architecture.spec.d.ts +1 -0
- package/dist/core/validators/ruleset-validator-architecture.spec.js +178 -0
- package/dist/core/validators/ruleset-validator-architecture.spec.js.map +1 -0
- package/dist/core/validators/ruleset-validator.service.d.ts +24 -0
- package/dist/core/validators/ruleset-validator.service.js +394 -0
- package/dist/core/validators/ruleset-validator.service.js.map +1 -1
- package/dist/core/validators/ruleset-validator.service.spec.js +351 -3
- package/dist/core/validators/ruleset-validator.service.spec.js.map +1 -1
- package/dist/domain/services/adr.service.spec.d.ts +1 -0
- package/dist/domain/services/adr.service.spec.js +141 -0
- package/dist/domain/services/adr.service.spec.js.map +1 -0
- package/dist/domain/services/agent-registry.service.spec.d.ts +1 -0
- package/dist/domain/services/agent-registry.service.spec.js +162 -0
- package/dist/domain/services/agent-registry.service.spec.js.map +1 -0
- package/dist/domain/services/index.d.ts +1 -0
- package/dist/domain/services/index.js +3 -1
- package/dist/domain/services/index.js.map +1 -1
- package/dist/domain/services/moscow-prioritization.service.d.ts +44 -0
- package/dist/domain/services/moscow-prioritization.service.js +213 -0
- package/dist/domain/services/moscow-prioritization.service.js.map +1 -0
- package/dist/domain/services/moscow-prioritization.service.spec.d.ts +1 -0
- package/dist/domain/services/moscow-prioritization.service.spec.js +285 -0
- package/dist/domain/services/moscow-prioritization.service.spec.js.map +1 -0
- package/dist/domain/services/standards.service.spec.d.ts +1 -0
- package/dist/domain/services/standards.service.spec.js +600 -0
- package/dist/domain/services/standards.service.spec.js.map +1 -0
- package/dist/domain/services/tool-usage-telemetry.service.spec.d.ts +1 -0
- package/dist/domain/services/tool-usage-telemetry.service.spec.js +180 -0
- package/dist/domain/services/tool-usage-telemetry.service.spec.js.map +1 -0
- package/dist/infrastructure/formatters/output-formatter.service.spec.d.ts +1 -0
- package/dist/infrastructure/formatters/output-formatter.service.spec.js +164 -0
- package/dist/infrastructure/formatters/output-formatter.service.spec.js.map +1 -0
- package/dist/main.js +0 -0
- package/package.json +2 -2
package/dist/core/mcp/server.js
CHANGED
|
@@ -33,175 +33,367 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.EvolithMcpServer = void 0;
|
|
37
36
|
exports.startMcpServer = startMcpServer;
|
|
38
37
|
const common_1 = require("@nestjs/common");
|
|
38
|
+
const http = __importStar(require("node:http"));
|
|
39
39
|
const ruleset_validator_service_1 = require("../validators/ruleset-validator.service");
|
|
40
40
|
const validate_1 = require("./tools/validate");
|
|
41
41
|
const agent_1 = require("./tools/agent");
|
|
42
42
|
const architecture_1 = require("./tools/architecture");
|
|
43
43
|
const sdlc_1 = require("./tools/sdlc");
|
|
44
|
-
const
|
|
45
|
-
const prompts_1 = require("./prompts");
|
|
44
|
+
const moscow_1 = require("./tools/moscow");
|
|
46
45
|
const metrics_service_1 = require("./metrics.service");
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const mcp = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk')));
|
|
55
|
-
ServerClass = mcp.Server;
|
|
56
|
-
StdioTransportClass = mcp.StdioServerTransport;
|
|
57
|
-
const httpTransport = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/streamableHttp')));
|
|
58
|
-
if (httpTransport.StreamableHTTPServerTransport) {
|
|
59
|
-
StreamableHttpTransportClass = httpTransport.StreamableHTTPServerTransport;
|
|
60
|
-
}
|
|
46
|
+
class MinimalStdioTransport {
|
|
47
|
+
constructor(stdin, stdout) {
|
|
48
|
+
this.readBuffer = '';
|
|
49
|
+
this.stdin = stdin || process.stdin;
|
|
50
|
+
this.stdout = stdout || process.stdout;
|
|
51
|
+
this.readBuffer = '';
|
|
52
|
+
this.started = false;
|
|
61
53
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
async start() {
|
|
55
|
+
if (this.started)
|
|
56
|
+
return;
|
|
57
|
+
this.started = true;
|
|
58
|
+
this.stdin.on('data', (chunk) => {
|
|
59
|
+
this.readBuffer += chunk.toString();
|
|
60
|
+
let newlineIndex;
|
|
61
|
+
while ((newlineIndex = this.readBuffer.indexOf('\n')) !== -1) {
|
|
62
|
+
const line = this.readBuffer.slice(0, newlineIndex).trim();
|
|
63
|
+
this.readBuffer = this.readBuffer.slice(newlineIndex + 1);
|
|
64
|
+
if (line) {
|
|
65
|
+
try {
|
|
66
|
+
const message = JSON.parse(line);
|
|
67
|
+
if (this.onmessage) {
|
|
68
|
+
this.onmessage(message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
if (this.onerror) {
|
|
73
|
+
this.onerror(new Error(`Invalid JSON: ${line}`));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
this.stdin.on('end', () => {
|
|
80
|
+
if (this.onclose) {
|
|
81
|
+
this.onclose();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
this.stdin.on('error', (err) => {
|
|
85
|
+
if (this.onerror) {
|
|
86
|
+
this.onerror(err);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async close() {
|
|
91
|
+
this.started = false;
|
|
92
|
+
}
|
|
93
|
+
async send(message) {
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
const json = JSON.stringify(message) + '\n';
|
|
96
|
+
this.stdout.write(json, (err) => {
|
|
97
|
+
if (err)
|
|
98
|
+
reject(err);
|
|
99
|
+
else
|
|
100
|
+
resolve();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
65
103
|
}
|
|
66
104
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
name: 'tools/list',
|
|
76
|
-
description: 'List available tools',
|
|
77
|
-
};
|
|
78
|
-
const CALL_TOOL_REQUEST_SCHEMA = {
|
|
79
|
-
name: 'tools/call',
|
|
80
|
-
description: 'Call a tool by name',
|
|
81
|
-
};
|
|
82
|
-
const LIST_RESOURCES_REQUEST_SCHEMA = {
|
|
83
|
-
name: 'resources/list',
|
|
84
|
-
description: 'List available resources',
|
|
85
|
-
};
|
|
86
|
-
const READ_RESOURCE_REQUEST_SCHEMA = {
|
|
87
|
-
name: 'resources/read',
|
|
88
|
-
description: 'Read a resource',
|
|
89
|
-
};
|
|
90
|
-
const LIST_PROMPTS_REQUEST_SCHEMA = {
|
|
91
|
-
name: 'prompts/list',
|
|
92
|
-
description: 'List available prompts',
|
|
93
|
-
};
|
|
94
|
-
const GET_PROMPT_REQUEST_SCHEMA = {
|
|
95
|
-
name: 'prompts/get',
|
|
96
|
-
description: 'Get a prompt template',
|
|
97
|
-
};
|
|
98
|
-
class EvolithMcpServer {
|
|
99
|
-
constructor(options = {}) {
|
|
100
|
-
this.logger = new common_1.Logger(EvolithMcpServer.name);
|
|
101
|
-
this.serverInstance = null;
|
|
102
|
-
this.rulesetValidator = options.rulesetValidator || new ruleset_validator_service_1.RulesetValidatorService();
|
|
103
|
-
this.metricsService = options.metricsService || new metrics_service_1.McpMetricsService();
|
|
104
|
-
this.apiKey = options.apiKey || process.env.EVOLITH_API_KEY;
|
|
105
|
-
this.port = options.port || parseInt(process.env.PORT || '3000', 10);
|
|
105
|
+
class MinimalHttpTransport {
|
|
106
|
+
constructor(port, apiKey) {
|
|
107
|
+
this.server = null;
|
|
108
|
+
this.logger = new common_1.Logger(MinimalHttpTransport.name);
|
|
109
|
+
this.sseClients = [];
|
|
110
|
+
this.started = false;
|
|
111
|
+
this.port = port;
|
|
112
|
+
this.apiKey = apiKey;
|
|
106
113
|
}
|
|
107
|
-
async
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
async start() {
|
|
115
|
+
if (this.started)
|
|
116
|
+
return;
|
|
117
|
+
this.started = true;
|
|
118
|
+
this.server = http.createServer((req, res) => {
|
|
119
|
+
this.handleRequest(req, res);
|
|
112
120
|
});
|
|
113
|
-
this.
|
|
114
|
-
|
|
121
|
+
this.server.on('error', (error) => {
|
|
122
|
+
this.logger.error(`HTTP server error: ${error.message}`);
|
|
123
|
+
if (this.onerror) {
|
|
124
|
+
this.onerror(error);
|
|
125
|
+
}
|
|
115
126
|
});
|
|
116
|
-
this.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
this.server.on('close', () => {
|
|
128
|
+
if (this.onclose) {
|
|
129
|
+
this.onclose();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
await new Promise((resolve, reject) => {
|
|
133
|
+
this.server.listen(this.port, '127.0.0.1', () => {
|
|
134
|
+
this.logger.log(`Evolith MCP HTTP server listening on http://127.0.0.1:${this.port}`);
|
|
135
|
+
resolve();
|
|
136
|
+
});
|
|
137
|
+
this.server.on('error', reject);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async close() {
|
|
141
|
+
this.started = false;
|
|
142
|
+
for (const client of this.sseClients) {
|
|
143
|
+
client.res.end();
|
|
144
|
+
}
|
|
145
|
+
this.sseClients = [];
|
|
146
|
+
if (this.server) {
|
|
147
|
+
await new Promise((resolve) => {
|
|
148
|
+
this.server.close(() => resolve());
|
|
149
|
+
});
|
|
150
|
+
this.server = null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async send(message) {
|
|
154
|
+
const data = `event: message\ndata: ${JSON.stringify(message)}\n\n`;
|
|
155
|
+
const clientsToRemove = [];
|
|
156
|
+
for (const client of this.sseClients) {
|
|
157
|
+
try {
|
|
158
|
+
client.res.write(data);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
clientsToRemove.push(client);
|
|
123
162
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
163
|
+
}
|
|
164
|
+
for (const client of clientsToRemove) {
|
|
165
|
+
const index = this.sseClients.indexOf(client);
|
|
166
|
+
if (index > -1) {
|
|
167
|
+
this.sseClients.splice(index, 1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
handleRequest(req, res) {
|
|
172
|
+
const url = new URL(req.url || '/', `http://127.0.0.1:${this.port}`);
|
|
173
|
+
if (!this.validateAuth(req, res)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (req.method === 'POST' && url.pathname === '/message') {
|
|
177
|
+
this.handlePostMessage(req, res);
|
|
178
|
+
}
|
|
179
|
+
else if (req.method === 'GET' && url.pathname === '/sse') {
|
|
180
|
+
this.handleSseConnection(req, res);
|
|
181
|
+
}
|
|
182
|
+
else if (req.method === 'GET' && url.pathname === '/health') {
|
|
183
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
184
|
+
res.end(JSON.stringify({ status: 'ok', transport: 'http', protocol: 'mcp' }));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
188
|
+
res.end(JSON.stringify({ error: 'Not found' }));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
validateAuth(req, res) {
|
|
192
|
+
if (!this.apiKey)
|
|
193
|
+
return true;
|
|
194
|
+
const authHeader = req.headers.authorization || '';
|
|
195
|
+
const bearerToken = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : '';
|
|
196
|
+
const apiKeyHeader = req.headers['x-api-key'];
|
|
197
|
+
if (bearerToken !== this.apiKey && apiKeyHeader !== this.apiKey) {
|
|
198
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
199
|
+
res.end(JSON.stringify({ error: 'Unauthorized', message: 'Invalid or missing API key' }));
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
async handlePostMessage(req, res) {
|
|
205
|
+
let body = '';
|
|
206
|
+
req.on('data', (chunk) => {
|
|
207
|
+
body += chunk.toString();
|
|
127
208
|
});
|
|
128
|
-
|
|
129
|
-
|
|
209
|
+
req.on('end', async () => {
|
|
210
|
+
try {
|
|
211
|
+
const message = JSON.parse(body);
|
|
212
|
+
if (this.onmessage) {
|
|
213
|
+
await this.onmessage(message);
|
|
214
|
+
}
|
|
215
|
+
res.writeHead(202, { 'Content-Type': 'application/json' });
|
|
216
|
+
res.end(JSON.stringify({ status: 'accepted' }));
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
this.logger.error(`Invalid POST message: ${error}`);
|
|
220
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
221
|
+
res.end(JSON.stringify({ error: 'Invalid JSON' }));
|
|
222
|
+
}
|
|
130
223
|
});
|
|
131
|
-
|
|
132
|
-
|
|
224
|
+
req.on('error', (error) => {
|
|
225
|
+
this.logger.error(`Request error: ${error.message}`);
|
|
226
|
+
if (this.onerror) {
|
|
227
|
+
this.onerror(error);
|
|
228
|
+
}
|
|
229
|
+
if (!res.headersSent) {
|
|
230
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
231
|
+
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
232
|
+
}
|
|
133
233
|
});
|
|
134
|
-
|
|
135
|
-
|
|
234
|
+
}
|
|
235
|
+
handleSseConnection(req, res) {
|
|
236
|
+
const clientId = `client-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;
|
|
237
|
+
res.writeHead(200, {
|
|
238
|
+
'Content-Type': 'text/event-stream',
|
|
239
|
+
'Cache-Control': 'no-cache',
|
|
240
|
+
'Connection': 'keep-alive',
|
|
241
|
+
'Access-Control-Allow-Origin': '*',
|
|
136
242
|
});
|
|
137
|
-
|
|
138
|
-
|
|
243
|
+
res.write(': connected\n\n');
|
|
244
|
+
this.sseClients.push({ id: clientId, res });
|
|
245
|
+
req.on('close', () => {
|
|
246
|
+
const index = this.sseClients.findIndex(c => c.id === clientId);
|
|
247
|
+
if (index > -1) {
|
|
248
|
+
this.sseClients.splice(index, 1);
|
|
249
|
+
}
|
|
250
|
+
this.logger.debug(`SSE client disconnected: ${clientId}`);
|
|
139
251
|
});
|
|
140
|
-
this.logger.
|
|
252
|
+
this.logger.debug(`SSE client connected: ${clientId}`);
|
|
141
253
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
254
|
+
}
|
|
255
|
+
class DirectMcpServer {
|
|
256
|
+
constructor(transportType = 'stdio', port = 49100, apiKey, rulesetValidator, metricsService) {
|
|
257
|
+
this.logger = new common_1.Logger(DirectMcpServer.name);
|
|
258
|
+
this.transportType = transportType;
|
|
259
|
+
this.rulesetValidator = rulesetValidator || new ruleset_validator_service_1.RulesetValidatorService();
|
|
260
|
+
this.metricsService = metricsService || new metrics_service_1.McpMetricsService();
|
|
261
|
+
if (transportType === 'http') {
|
|
262
|
+
this.transport = new MinimalHttpTransport(port, apiKey);
|
|
148
263
|
}
|
|
149
264
|
else {
|
|
150
|
-
|
|
151
|
-
await this.serverInstance.connect(stdioTransport);
|
|
265
|
+
this.transport = new MinimalStdioTransport();
|
|
152
266
|
}
|
|
153
267
|
}
|
|
154
|
-
async
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
268
|
+
async start() {
|
|
269
|
+
const transport = this.transport;
|
|
270
|
+
transport.onmessage = async (message) => {
|
|
271
|
+
await this.handleMessage(message);
|
|
272
|
+
};
|
|
273
|
+
transport.onerror = (error) => {
|
|
274
|
+
this.logger.error(`Transport error: ${error.message}`);
|
|
275
|
+
};
|
|
276
|
+
await transport.start();
|
|
277
|
+
this.logger.log(`Evolith MCP Server started on ${this.transportType}`);
|
|
278
|
+
}
|
|
279
|
+
async stop() {
|
|
280
|
+
await this.transport.close();
|
|
281
|
+
}
|
|
282
|
+
async handleMessage(rawMessage) {
|
|
283
|
+
try {
|
|
284
|
+
const request = rawMessage;
|
|
285
|
+
this.logger.debug(`Received: ${JSON.stringify(request)}`);
|
|
286
|
+
if (request.method === 'initialize') {
|
|
287
|
+
const response = {
|
|
288
|
+
jsonrpc: '2.0',
|
|
289
|
+
id: request.id,
|
|
290
|
+
result: {
|
|
291
|
+
protocolVersion: '2024-11-05',
|
|
292
|
+
capabilities: {
|
|
293
|
+
tools: {},
|
|
294
|
+
resources: {},
|
|
295
|
+
prompts: {},
|
|
296
|
+
},
|
|
297
|
+
serverInfo: {
|
|
298
|
+
name: 'evolith-mcp-server',
|
|
299
|
+
version: '1.0.0',
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
await this.transport.send(response);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
let result;
|
|
307
|
+
try {
|
|
308
|
+
result = await this.dispatchRequest(request.method, request.params || {});
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
const errorResponse = {
|
|
312
|
+
jsonrpc: '2.0',
|
|
313
|
+
id: request.id,
|
|
314
|
+
error: {
|
|
315
|
+
code: -32603,
|
|
316
|
+
message: error instanceof Error ? error.message : String(error),
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
await this.transport.send(errorResponse);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const response = {
|
|
323
|
+
jsonrpc: '2.0',
|
|
324
|
+
id: request.id,
|
|
325
|
+
result,
|
|
326
|
+
};
|
|
327
|
+
await this.transport.send(response);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
this.logger.error(`Error handling message: ${error}`);
|
|
331
|
+
const errorResponse = {
|
|
332
|
+
jsonrpc: '2.0',
|
|
333
|
+
id: null,
|
|
334
|
+
error: {
|
|
335
|
+
code: -32603,
|
|
336
|
+
message: error instanceof Error ? error.message : String(error),
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
await this.transport.send(errorResponse);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
async dispatchRequest(method, params) {
|
|
343
|
+
switch (method) {
|
|
344
|
+
case 'tools/list':
|
|
345
|
+
return this.handleListTools();
|
|
346
|
+
case 'tools/call':
|
|
347
|
+
return this.handleCallTool(params);
|
|
348
|
+
case 'resources/list':
|
|
349
|
+
return this.handleListResources();
|
|
350
|
+
case 'resources/read':
|
|
351
|
+
return this.handleReadResource(params);
|
|
352
|
+
case 'prompts/list':
|
|
353
|
+
return this.handleListPrompts();
|
|
354
|
+
case 'prompts/get':
|
|
355
|
+
return this.handleGetPrompt(params);
|
|
356
|
+
default:
|
|
357
|
+
throw new Error(`Method not found: ${method}`);
|
|
160
358
|
}
|
|
161
|
-
this.logger.log(`Starting HTTP MCP server on port ${this.port}`);
|
|
162
|
-
const httpTransport = new StreamableHttpTransportClass({
|
|
163
|
-
port: this.port,
|
|
164
|
-
host: '0.0.0.0',
|
|
165
|
-
});
|
|
166
|
-
await this.serverInstance.connect(httpTransport);
|
|
167
359
|
}
|
|
168
|
-
|
|
360
|
+
handleListTools() {
|
|
169
361
|
return {
|
|
170
362
|
tools: [
|
|
171
363
|
{
|
|
172
364
|
name: 'evolith-validate',
|
|
173
|
-
description: 'Validate a repository against Evolith governance rules
|
|
365
|
+
description: 'Validate a repository against Evolith governance rules',
|
|
174
366
|
inputSchema: {
|
|
175
367
|
type: 'object',
|
|
176
368
|
properties: {
|
|
177
369
|
path: { type: 'string', description: 'Path to the repository to validate' },
|
|
178
370
|
format: { type: 'string', description: 'Output format: json, summary, table', default: 'json' },
|
|
179
|
-
ruleset: { type: 'string', description: 'Specific ruleset to validate
|
|
180
|
-
corePath: { type: 'string', description: 'Path to Evolith Core
|
|
371
|
+
ruleset: { type: 'string', description: 'Specific ruleset to validate' },
|
|
372
|
+
corePath: { type: 'string', description: 'Path to Evolith Core' },
|
|
181
373
|
},
|
|
182
374
|
required: ['path'],
|
|
183
375
|
},
|
|
184
376
|
},
|
|
185
377
|
{
|
|
186
378
|
name: 'evolith-agent-install',
|
|
187
|
-
description: 'Install a new Evolith agent
|
|
379
|
+
description: 'Install a new Evolith agent',
|
|
188
380
|
inputSchema: {
|
|
189
381
|
type: 'object',
|
|
190
382
|
properties: {
|
|
191
383
|
name: { type: 'string', description: 'Name of the agent to install' },
|
|
192
|
-
template: { type: 'string', description: 'Template
|
|
193
|
-
dir: { type: 'string', description: 'Directory to install into
|
|
384
|
+
template: { type: 'string', description: 'Template: standard, minimal, enterprise', default: 'standard' },
|
|
385
|
+
dir: { type: 'string', description: 'Directory to install into' },
|
|
194
386
|
},
|
|
195
387
|
required: ['name'],
|
|
196
388
|
},
|
|
197
389
|
},
|
|
198
390
|
{
|
|
199
391
|
name: 'evolith-agent-list',
|
|
200
|
-
description: 'List all installed Evolith agents
|
|
392
|
+
description: 'List all installed Evolith agents',
|
|
201
393
|
inputSchema: {
|
|
202
394
|
type: 'object',
|
|
203
395
|
properties: {
|
|
204
|
-
dir: { type: 'string', description: 'Directory to search
|
|
396
|
+
dir: { type: 'string', description: 'Directory to search' },
|
|
205
397
|
},
|
|
206
398
|
},
|
|
207
399
|
},
|
|
@@ -211,44 +403,45 @@ class EvolithMcpServer {
|
|
|
211
403
|
inputSchema: {
|
|
212
404
|
type: 'object',
|
|
213
405
|
properties: {
|
|
214
|
-
name: { type: 'string'
|
|
215
|
-
dir: { type: 'string'
|
|
406
|
+
name: { type: 'string' },
|
|
407
|
+
dir: { type: 'string' },
|
|
216
408
|
},
|
|
217
409
|
required: ['name'],
|
|
218
410
|
},
|
|
219
411
|
},
|
|
220
412
|
{
|
|
221
413
|
name: 'evolith-agent-upgrade',
|
|
222
|
-
description: 'Upgrade an existing Evolith agent
|
|
414
|
+
description: 'Upgrade an existing Evolith agent',
|
|
223
415
|
inputSchema: {
|
|
224
416
|
type: 'object',
|
|
225
417
|
properties: {
|
|
226
|
-
name: { type: 'string'
|
|
227
|
-
dir: { type: 'string'
|
|
418
|
+
name: { type: 'string' },
|
|
419
|
+
dir: { type: 'string' },
|
|
228
420
|
},
|
|
229
421
|
required: ['name'],
|
|
230
422
|
},
|
|
231
423
|
},
|
|
232
424
|
{
|
|
233
425
|
name: 'evolith-agent-remove',
|
|
234
|
-
description: 'Remove an Evolith agent
|
|
426
|
+
description: 'Remove an Evolith agent',
|
|
235
427
|
inputSchema: {
|
|
236
428
|
type: 'object',
|
|
237
429
|
properties: {
|
|
238
|
-
name: { type: 'string'
|
|
239
|
-
dir: { type: 'string'
|
|
430
|
+
name: { type: 'string' },
|
|
431
|
+
dir: { type: 'string' },
|
|
240
432
|
},
|
|
241
433
|
required: ['name'],
|
|
242
434
|
},
|
|
243
435
|
},
|
|
244
436
|
{
|
|
245
437
|
name: 'evolith-architecture-validate',
|
|
246
|
-
description: 'Validate repository architecture against F1/F2/F3 rules',
|
|
438
|
+
description: 'Validate repository architecture against F1/F2/F3 rules. Use deep=true for import graph analysis, layer violations, and coupling metrics.',
|
|
247
439
|
inputSchema: {
|
|
248
440
|
type: 'object',
|
|
249
441
|
properties: {
|
|
250
|
-
path: { type: 'string'
|
|
251
|
-
level: { type: 'string', description: '
|
|
442
|
+
path: { type: 'string' },
|
|
443
|
+
level: { type: 'string', description: 'F1, F2, or F3' },
|
|
444
|
+
deep: { type: 'boolean', description: 'Enable deep static analysis (import graph, layer violations, coupling metrics)', default: false },
|
|
252
445
|
},
|
|
253
446
|
required: ['path'],
|
|
254
447
|
},
|
|
@@ -259,20 +452,20 @@ class EvolithMcpServer {
|
|
|
259
452
|
inputSchema: {
|
|
260
453
|
type: 'object',
|
|
261
454
|
properties: {
|
|
262
|
-
path: { type: 'string'
|
|
263
|
-
fromPhase: { type: 'string'
|
|
264
|
-
toPhase: { type: 'string'
|
|
455
|
+
path: { type: 'string' },
|
|
456
|
+
fromPhase: { type: 'string' },
|
|
457
|
+
toPhase: { type: 'string' },
|
|
265
458
|
},
|
|
266
459
|
required: ['path', 'fromPhase', 'toPhase'],
|
|
267
460
|
},
|
|
268
461
|
},
|
|
269
462
|
{
|
|
270
463
|
name: 'evolith-sdlc-status',
|
|
271
|
-
description: 'Show current SDLC phase gate status
|
|
464
|
+
description: 'Show current SDLC phase gate status',
|
|
272
465
|
inputSchema: {
|
|
273
466
|
type: 'object',
|
|
274
467
|
properties: {
|
|
275
|
-
path: { type: 'string'
|
|
468
|
+
path: { type: 'string' },
|
|
276
469
|
},
|
|
277
470
|
required: ['path'],
|
|
278
471
|
},
|
|
@@ -283,8 +476,8 @@ class EvolithMcpServer {
|
|
|
283
476
|
inputSchema: {
|
|
284
477
|
type: 'object',
|
|
285
478
|
properties: {
|
|
286
|
-
key: { type: 'string'
|
|
287
|
-
dir: { type: 'string'
|
|
479
|
+
key: { type: 'string' },
|
|
480
|
+
dir: { type: 'string' },
|
|
288
481
|
},
|
|
289
482
|
required: ['key'],
|
|
290
483
|
},
|
|
@@ -295,26 +488,114 @@ class EvolithMcpServer {
|
|
|
295
488
|
inputSchema: {
|
|
296
489
|
type: 'object',
|
|
297
490
|
properties: {
|
|
298
|
-
key: { type: 'string'
|
|
299
|
-
value: { type: 'string'
|
|
300
|
-
dir: { type: 'string'
|
|
491
|
+
key: { type: 'string' },
|
|
492
|
+
value: { type: 'string' },
|
|
493
|
+
dir: { type: 'string' },
|
|
301
494
|
},
|
|
302
495
|
required: ['key', 'value'],
|
|
303
496
|
},
|
|
304
497
|
},
|
|
305
498
|
{
|
|
306
499
|
name: 'evolith-metrics',
|
|
307
|
-
description: 'Get MCP server metrics
|
|
500
|
+
description: 'Get MCP server metrics',
|
|
308
501
|
inputSchema: {
|
|
309
502
|
type: 'object',
|
|
310
503
|
properties: {},
|
|
311
504
|
},
|
|
312
505
|
},
|
|
506
|
+
{
|
|
507
|
+
name: 'evolith-moscow-create',
|
|
508
|
+
description: 'Create a new MoSCoW prioritization analysis for a phase',
|
|
509
|
+
inputSchema: {
|
|
510
|
+
type: 'object',
|
|
511
|
+
properties: {
|
|
512
|
+
path: { type: 'string', description: 'Path to the repository' },
|
|
513
|
+
phase: { type: 'string', description: 'Phase identifier (e.g., phase-0)', default: 'phase-0' },
|
|
514
|
+
items: { type: 'array', description: 'Array of MoSCoW items with description, priority, category, rationale' },
|
|
515
|
+
},
|
|
516
|
+
required: ['path', 'items'],
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
name: 'evolith-moscow-load',
|
|
521
|
+
description: 'Load an existing MoSCoW analysis for a phase',
|
|
522
|
+
inputSchema: {
|
|
523
|
+
type: 'object',
|
|
524
|
+
properties: {
|
|
525
|
+
path: { type: 'string' },
|
|
526
|
+
phase: { type: 'string', default: 'phase-0' },
|
|
527
|
+
},
|
|
528
|
+
required: ['path'],
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: 'evolith-moscow-update',
|
|
533
|
+
description: 'Update an item in a MoSCoW analysis',
|
|
534
|
+
inputSchema: {
|
|
535
|
+
type: 'object',
|
|
536
|
+
properties: {
|
|
537
|
+
path: { type: 'string' },
|
|
538
|
+
phase: { type: 'string', default: 'phase-0' },
|
|
539
|
+
itemId: { type: 'string' },
|
|
540
|
+
updates: { type: 'object' },
|
|
541
|
+
},
|
|
542
|
+
required: ['path', 'itemId'],
|
|
543
|
+
},
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
name: 'evolith-moscow-remove',
|
|
547
|
+
description: 'Remove an item from a MoSCoW analysis',
|
|
548
|
+
inputSchema: {
|
|
549
|
+
type: 'object',
|
|
550
|
+
properties: {
|
|
551
|
+
path: { type: 'string' },
|
|
552
|
+
phase: { type: 'string', default: 'phase-0' },
|
|
553
|
+
itemId: { type: 'string' },
|
|
554
|
+
},
|
|
555
|
+
required: ['path', 'itemId'],
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
name: 'evolith-moscow-list',
|
|
560
|
+
description: 'List all MoSCoW analyses for a repository',
|
|
561
|
+
inputSchema: {
|
|
562
|
+
type: 'object',
|
|
563
|
+
properties: {
|
|
564
|
+
path: { type: 'string' },
|
|
565
|
+
},
|
|
566
|
+
required: ['path'],
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
name: 'evolith-moscow-validate',
|
|
571
|
+
description: 'Validate a MoSCoW analysis for correctness',
|
|
572
|
+
inputSchema: {
|
|
573
|
+
type: 'object',
|
|
574
|
+
properties: {
|
|
575
|
+
path: { type: 'string' },
|
|
576
|
+
phase: { type: 'string', default: 'phase-0' },
|
|
577
|
+
},
|
|
578
|
+
required: ['path'],
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
name: 'evolith-moscow-report',
|
|
583
|
+
description: 'Generate a markdown report from a MoSCoW analysis',
|
|
584
|
+
inputSchema: {
|
|
585
|
+
type: 'object',
|
|
586
|
+
properties: {
|
|
587
|
+
path: { type: 'string' },
|
|
588
|
+
phase: { type: 'string', default: 'phase-0' },
|
|
589
|
+
},
|
|
590
|
+
required: ['path'],
|
|
591
|
+
},
|
|
592
|
+
},
|
|
313
593
|
],
|
|
314
594
|
};
|
|
315
595
|
}
|
|
316
|
-
async handleCallTool(
|
|
317
|
-
|
|
596
|
+
async handleCallTool(params) {
|
|
597
|
+
const name = params.name;
|
|
598
|
+
const args = params.arguments || {};
|
|
318
599
|
const startTime = Date.now();
|
|
319
600
|
try {
|
|
320
601
|
let result;
|
|
@@ -331,11 +612,14 @@ class EvolithMcpServer {
|
|
|
331
612
|
result = await (0, sdlc_1.handleSdlcTools)(name, args);
|
|
332
613
|
}
|
|
333
614
|
else if (name === 'evolith-config-get' || name === 'evolith-config-set') {
|
|
334
|
-
result = await handleConfigTools(name, args);
|
|
615
|
+
result = await this.handleConfigTools(name, args);
|
|
335
616
|
}
|
|
336
617
|
else if (name === 'evolith-metrics') {
|
|
337
618
|
result = this.metricsService.getMetrics();
|
|
338
619
|
}
|
|
620
|
+
else if (name.startsWith('evolith-moscow')) {
|
|
621
|
+
result = await (0, moscow_1.handleMoscowTools)(name, args);
|
|
622
|
+
}
|
|
339
623
|
else {
|
|
340
624
|
throw new Error(`Unknown tool: ${name}`);
|
|
341
625
|
}
|
|
@@ -353,7 +637,6 @@ class EvolithMcpServer {
|
|
|
353
637
|
catch (error) {
|
|
354
638
|
const latencyMs = Date.now() - startTime;
|
|
355
639
|
const message = error instanceof Error ? error.message : String(error);
|
|
356
|
-
this.logger.error(`Tool ${name} failed: ${message}`);
|
|
357
640
|
this.metricsService.recordToolCall(name, latencyMs, false);
|
|
358
641
|
this.metricsService.recordError(message.substring(0, 50));
|
|
359
642
|
return {
|
|
@@ -367,47 +650,70 @@ class EvolithMcpServer {
|
|
|
367
650
|
};
|
|
368
651
|
}
|
|
369
652
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
if (!(await fs.pathExists(configPath))) {
|
|
379
|
-
throw new Error('evolith.yaml not found');
|
|
380
|
-
}
|
|
381
|
-
const config = yaml.parse(await fs.readFile(configPath, 'utf-8'));
|
|
382
|
-
if (name === 'evolith-config-get') {
|
|
383
|
-
const key = args.key;
|
|
384
|
-
const keys = key.split('.');
|
|
385
|
-
let value = config;
|
|
386
|
-
for (const k of keys) {
|
|
387
|
-
value = value?.[k];
|
|
653
|
+
async handleConfigTools(name, args) {
|
|
654
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
|
|
655
|
+
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
656
|
+
const yaml = await Promise.resolve().then(() => __importStar(require('yaml')));
|
|
657
|
+
const dir = args.dir || process.cwd();
|
|
658
|
+
const configPath = path.join(dir, 'evolith.yaml');
|
|
659
|
+
if (!(await fs.pathExists(configPath))) {
|
|
660
|
+
throw new Error('evolith.yaml not found');
|
|
388
661
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
397
|
-
if (!target[keys[i]]) {
|
|
398
|
-
target[keys[i]] = {};
|
|
662
|
+
const config = yaml.parse(await fs.readFile(configPath, 'utf-8'));
|
|
663
|
+
if (name === 'evolith-config-get') {
|
|
664
|
+
const key = args.key;
|
|
665
|
+
const keys = key.split('.');
|
|
666
|
+
let value = config;
|
|
667
|
+
for (const k of keys) {
|
|
668
|
+
value = value?.[k];
|
|
399
669
|
}
|
|
400
|
-
|
|
670
|
+
return { key, value: value ?? null };
|
|
401
671
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
672
|
+
else {
|
|
673
|
+
const key = args.key;
|
|
674
|
+
const value = args.value;
|
|
675
|
+
const keys = key.split('.');
|
|
676
|
+
let target = config;
|
|
677
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
678
|
+
if (!target[keys[i]]) {
|
|
679
|
+
target[keys[i]] = {};
|
|
680
|
+
}
|
|
681
|
+
target = target[keys[i]];
|
|
682
|
+
}
|
|
683
|
+
target[keys[keys.length - 1]] = value;
|
|
684
|
+
await fs.writeFile(configPath, yaml.stringify(config));
|
|
685
|
+
return { key, value, updated: true };
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
async handleListResources() {
|
|
689
|
+
const { listResources } = await Promise.resolve().then(() => __importStar(require('./resources')));
|
|
690
|
+
return listResources();
|
|
691
|
+
}
|
|
692
|
+
async handleReadResource(params) {
|
|
693
|
+
const { readResource } = await Promise.resolve().then(() => __importStar(require('./resources')));
|
|
694
|
+
return readResource(params);
|
|
405
695
|
}
|
|
696
|
+
async handleListPrompts() {
|
|
697
|
+
const { listPrompts } = await Promise.resolve().then(() => __importStar(require('./prompts')));
|
|
698
|
+
return listPrompts();
|
|
699
|
+
}
|
|
700
|
+
async handleGetPrompt(params) {
|
|
701
|
+
const { getPrompt } = await Promise.resolve().then(() => __importStar(require('./prompts')));
|
|
702
|
+
return getPrompt(params);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
function validateApiKey(apiKey, validKey) {
|
|
706
|
+
if (!validKey)
|
|
707
|
+
return true;
|
|
708
|
+
if (!apiKey)
|
|
709
|
+
return false;
|
|
710
|
+
return apiKey === validKey;
|
|
406
711
|
}
|
|
407
712
|
async function startMcpServer(options = {}) {
|
|
408
|
-
const server = new EvolithMcpServer(options);
|
|
409
713
|
const transport = options.transport || 'stdio';
|
|
410
|
-
|
|
714
|
+
const port = options.port || 49100;
|
|
715
|
+
const server = new DirectMcpServer(transport, port, options.apiKey, options.rulesetValidator, options.metricsService);
|
|
716
|
+
await server.start();
|
|
411
717
|
return server;
|
|
412
718
|
}
|
|
413
719
|
//# sourceMappingURL=server.js.map
|