@corva/ui 3.78.0-1 → 3.78.0-2
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/mcp-server/server.mjs +49 -22
- package/package.json +1 -1
package/mcp-server/server.mjs
CHANGED
|
@@ -224,7 +224,7 @@ const MCP_PROTOCOL_VERSION = '2025-03-26';
|
|
|
224
224
|
const MCP_NETWORK_TRANSPORT = 'pipe';
|
|
225
225
|
const UNKNOWN_CLIENT_ATTR = 'unknown';
|
|
226
226
|
const DEFAULT_SAMPLING_RATE = 1.0;
|
|
227
|
-
const TELEMETRY_CONFIG_TIMEOUT_MS =
|
|
227
|
+
const TELEMETRY_CONFIG_TIMEOUT_MS = 5000;
|
|
228
228
|
const TELEMETRY_INIT_TIMEOUT_MS = 10_000;
|
|
229
229
|
const TELEMETRY_SHUTDOWN_TIMEOUT_MS = 5000;
|
|
230
230
|
const OTLP_TRACES_ENDPOINT = 'https://otlp.uptrace.dev/v1/traces';
|
|
@@ -246,9 +246,9 @@ const validateDsn = dsn => {
|
|
|
246
246
|
return url.href;
|
|
247
247
|
};
|
|
248
248
|
|
|
249
|
-
const MCP_SERVER_VERSION = '1.5.
|
|
249
|
+
const MCP_SERVER_VERSION = '1.5.2';
|
|
250
250
|
|
|
251
|
-
var version = "3.78.0-
|
|
251
|
+
var version = "3.78.0-2";
|
|
252
252
|
|
|
253
253
|
const CORVA_UI_VERSION = version;
|
|
254
254
|
|
|
@@ -38053,6 +38053,7 @@ const formatUptime = ms => {
|
|
|
38053
38053
|
}
|
|
38054
38054
|
return `${seconds}s`;
|
|
38055
38055
|
};
|
|
38056
|
+
const formatSeconds = ms => `${(ms / 1000).toFixed(2)}s`;
|
|
38056
38057
|
const formatBytes = bytes => {
|
|
38057
38058
|
const mb = bytes / (1024 * 1024);
|
|
38058
38059
|
return `${mb.toFixed(1)} MB`;
|
|
@@ -38069,7 +38070,15 @@ const handleGetDiagnostics = (stats, telemetry, identity, registeredPromptNames)
|
|
|
38069
38070
|
text += h2('Server');
|
|
38070
38071
|
text += `${bold('Version')}: ${MCP_SERVER_VERSION}\n\n`;
|
|
38071
38072
|
text += h2('Uptime');
|
|
38072
|
-
text += `${bold('Server running for')}: ${formatUptime(uptimeMs)}\n
|
|
38073
|
+
text += `${bold('Server running for')}: ${formatUptime(uptimeMs)}\n`;
|
|
38074
|
+
if (stats.startupMs !== undefined) {
|
|
38075
|
+
text += `${bold('Startup')}: ${formatSeconds(stats.startupMs)} from process start to transport connected`;
|
|
38076
|
+
if (stats.telemetryInitMs !== undefined) {
|
|
38077
|
+
text += `, of which telemetry init ${formatSeconds(stats.telemetryInitMs)}`;
|
|
38078
|
+
}
|
|
38079
|
+
text += '\n';
|
|
38080
|
+
}
|
|
38081
|
+
text += '\n';
|
|
38073
38082
|
text += h2('Memory Usage');
|
|
38074
38083
|
text += table(['Metric', 'Value'], [['Heap Used', formatBytes(heapUsed)], ['Heap Total', formatBytes(heapTotal)], ['Resident Set Size', formatBytes(rss)]]);
|
|
38075
38084
|
text += '\n\n';
|
|
@@ -38888,6 +38897,9 @@ class CorvaUiMcpServer {
|
|
|
38888
38897
|
isConnected = false;
|
|
38889
38898
|
startTime = Date.now();
|
|
38890
38899
|
requestCount = 0;
|
|
38900
|
+
|
|
38901
|
+
/** Process start → transport connected, in ms. Set once run() has connected. */
|
|
38902
|
+
|
|
38891
38903
|
telemetry = createNoopTelemetryClient();
|
|
38892
38904
|
telemetryInfo = null;
|
|
38893
38905
|
telemetryInitPromise = null;
|
|
@@ -39123,29 +39135,39 @@ class CorvaUiMcpServer {
|
|
|
39123
39135
|
});
|
|
39124
39136
|
}
|
|
39125
39137
|
async run() {
|
|
39126
|
-
|
|
39127
|
-
|
|
39128
|
-
|
|
39129
|
-
|
|
39130
|
-
|
|
39131
|
-
this.mcpLogger.
|
|
39132
|
-
// Non-blocking: tool calls can begin; first calls within the 10s window may miss telemetry
|
|
39138
|
+
// Telemetry settles before the transport connects, so no request can reach a handler while
|
|
39139
|
+
// telemetry initialization is pending. Agents call tools right after initialize, and the
|
|
39140
|
+
// calls that landed during the config fetch used to get no span and no metric (AI-369). The
|
|
39141
|
+
// cost is an initialize response delayed by the fetch: ~2 s, at most the config timeout.
|
|
39142
|
+
// stdin stays paused until connect(), so nothing the client sends meanwhile is lost.
|
|
39143
|
+
const telemetryTimer = this.mcpLogger.time('telemetry-init');
|
|
39133
39144
|
this.telemetryInitPromise = initTelemetry(this.mcpLogger).then(({
|
|
39134
39145
|
client,
|
|
39135
39146
|
info
|
|
39136
39147
|
}) => {
|
|
39137
|
-
|
|
39138
|
-
|
|
39139
|
-
/* shutting down anyway — a failed shutdown of a discarded client changes nothing */
|
|
39140
|
-
});
|
|
39141
|
-
} else {
|
|
39142
|
-
this.telemetry = client;
|
|
39143
|
-
this.telemetryInfo = info;
|
|
39144
|
-
this.flushPendingInitData();
|
|
39145
|
-
}
|
|
39148
|
+
this.telemetry = client;
|
|
39149
|
+
this.telemetryInfo = info;
|
|
39146
39150
|
}).catch(() => {
|
|
39147
39151
|
/* telemetry is best-effort — it must never take the server down */
|
|
39148
39152
|
});
|
|
39153
|
+
await this.telemetryInitPromise;
|
|
39154
|
+
this.telemetryInitMs = telemetryTimer.stop();
|
|
39155
|
+
this.mcpLogger.timeEnd('telemetry-init', telemetryTimer);
|
|
39156
|
+
|
|
39157
|
+
// If shutdown was requested during the wait (a signal; a closed stdin is usually noticed only
|
|
39158
|
+
// once reading starts), shutdown() already runs and owns the client.
|
|
39159
|
+
if (this.shutdownRequested) {
|
|
39160
|
+
return;
|
|
39161
|
+
}
|
|
39162
|
+
const connectTimer = this.mcpLogger.time('transport-connect');
|
|
39163
|
+
this.transport = new StdioServerTransport();
|
|
39164
|
+
await this.server.connect(this.transport);
|
|
39165
|
+
this.isConnected = true;
|
|
39166
|
+
// performance.now() counts from process start, so this is the time to ready as the client saw
|
|
39167
|
+
// it, minus whatever ran before the process (the data regeneration in `yarn mcp:dev`).
|
|
39168
|
+
this.startupMs = performance.now();
|
|
39169
|
+
this.mcpLogger.timeEnd('transport-connect', connectTimer);
|
|
39170
|
+
this.mcpLogger.info('Corva UI MCP Server running on stdio');
|
|
39149
39171
|
}
|
|
39150
39172
|
async shutdown() {
|
|
39151
39173
|
this.mcpLogger.info('Shutting down MCP server...');
|
|
@@ -39157,7 +39179,10 @@ class CorvaUiMcpServer {
|
|
|
39157
39179
|
if (this.identityPromise) {
|
|
39158
39180
|
await withTimeout(this.identityPromise, TELEMETRY_INIT_TIMEOUT_MS);
|
|
39159
39181
|
}
|
|
39160
|
-
|
|
39182
|
+
|
|
39183
|
+
// No transport means shutdown came during the telemetry wait: the client never connected, so
|
|
39184
|
+
// there is no session to end.
|
|
39185
|
+
if (this.telemetry.isEnabled() && this.transport) {
|
|
39161
39186
|
const sessionDurationMs = Date.now() - this.startTime;
|
|
39162
39187
|
const clientInfo = this.server.server.getClientVersion();
|
|
39163
39188
|
this.telemetry.metrics.recordSessionEnd(sessionDurationMs, this.requestCount, clientInfo?.name, clientInfo?.version, this.projectIdentity);
|
|
@@ -39179,7 +39204,9 @@ class CorvaUiMcpServer {
|
|
|
39179
39204
|
getStats() {
|
|
39180
39205
|
return {
|
|
39181
39206
|
startTime: this.startTime,
|
|
39182
|
-
requestCount: this.requestCount
|
|
39207
|
+
requestCount: this.requestCount,
|
|
39208
|
+
startupMs: this.startupMs,
|
|
39209
|
+
telemetryInitMs: this.telemetryInitMs
|
|
39183
39210
|
};
|
|
39184
39211
|
}
|
|
39185
39212
|
}
|