ultra-lean-mcp-proxy 0.3.0

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/src/proxy.mjs ADDED
@@ -0,0 +1,1122 @@
1
+ /**
2
+ * Ultra Lean MCP Proxy - stdio proxy with composable v2 optimization pipeline.
3
+ */
4
+
5
+ import { spawn } from 'node:child_process';
6
+ import { compressDescription, compressSchema } from './compress.mjs';
7
+ import { loadProxyConfig, featureEnabledForTool, cacheTtlForTool } from './config.mjs';
8
+ import { ProxyState, cloneJson, isMutatingToolName, makeCacheKey } from './state.mjs';
9
+ import { createDelta, stableHash } from './delta.mjs';
10
+ import {
11
+ TokenCounter,
12
+ makeCompressionOptions,
13
+ compressResult,
14
+ estimateCompressibility,
15
+ tokenSavings,
16
+ } from './result-compression.mjs';
17
+ import { computeToolsHash, parseIfNoneMatch } from './tools-hash-sync.mjs';
18
+
19
+ const SEARCH_TOOL_NAME = 'ultra_lean_mcp_proxy.search_tools';
20
+
21
+ function createLineReader(stream, onLine) {
22
+ let buffer = '';
23
+ stream.on('data', (chunk) => {
24
+ buffer += chunk.toString('utf-8');
25
+ let idx;
26
+ while ((idx = buffer.indexOf('\n')) !== -1) {
27
+ const line = buffer.slice(0, idx).trim();
28
+ buffer = buffer.slice(idx + 1);
29
+ if (line) onLine(line);
30
+ }
31
+ });
32
+ stream.on('end', () => {
33
+ const remaining = buffer.trim();
34
+ if (remaining) onLine(remaining);
35
+ });
36
+ }
37
+
38
+ function jsonSize(value) {
39
+ return Buffer.byteLength(JSON.stringify(value), 'utf-8');
40
+ }
41
+
42
+ function runtimeMetricsSnapshot(metrics) {
43
+ return {
44
+ upstream_requests: Number(metrics.upstreamRequests),
45
+ upstream_request_tokens: Number(metrics.upstreamRequestTokens),
46
+ upstream_request_bytes: Number(metrics.upstreamRequestBytes),
47
+ upstream_responses: Number(metrics.upstreamResponses),
48
+ upstream_response_tokens: Number(metrics.upstreamResponseTokens),
49
+ upstream_response_bytes: Number(metrics.upstreamResponseBytes),
50
+ };
51
+ }
52
+
53
+ function featureHealthKey(feature, toolName) {
54
+ return `${feature}:${toolName || '_global'}`;
55
+ }
56
+
57
+ function featureIsActive(featureStates, key, cfg) {
58
+ if (!cfg.autoDisableEnabled) return true;
59
+ const state = featureStates[key] || { regressionStreak: 0, cooldownRemaining: 0 };
60
+ featureStates[key] = state;
61
+ if (state.cooldownRemaining > 0) {
62
+ state.cooldownRemaining -= 1;
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+
68
+ function recordFeatureOutcome(featureStates, key, outcome, cfg) {
69
+ if (!cfg.autoDisableEnabled) return;
70
+ const state = featureStates[key] || { regressionStreak: 0, cooldownRemaining: 0 };
71
+ featureStates[key] = state;
72
+ if (outcome === 'success') {
73
+ state.regressionStreak = 0;
74
+ return;
75
+ }
76
+ if (outcome === 'neutral') {
77
+ state.regressionStreak = Math.max(0, state.regressionStreak - 1);
78
+ return;
79
+ }
80
+ if (outcome === 'hurt') {
81
+ state.regressionStreak += 1;
82
+ if (state.regressionStreak >= cfg.autoDisableThreshold) {
83
+ state.regressionStreak = 0;
84
+ state.cooldownRemaining = cfg.autoDisableCooldownRequests;
85
+ }
86
+ }
87
+ }
88
+
89
+ function extractToolCall(msg) {
90
+ const params = msg?.params;
91
+ if (!params || typeof params !== 'object' || Array.isArray(params)) {
92
+ return [null, {}];
93
+ }
94
+ const name = typeof params.name === 'string' ? params.name : null;
95
+ const argumentsValue = params.arguments;
96
+ const argumentsObj = argumentsValue && typeof argumentsValue === 'object' && !Array.isArray(argumentsValue)
97
+ ? argumentsValue
98
+ : {};
99
+ return [name, argumentsObj];
100
+ }
101
+
102
+ function clientSupportsToolsHashSync(params) {
103
+ if (!params || typeof params !== 'object' || Array.isArray(params)) return false;
104
+ const caps = params.capabilities;
105
+ if (!caps || typeof caps !== 'object' || Array.isArray(caps)) return false;
106
+ const experimental = caps.experimental;
107
+ if (!experimental || typeof experimental !== 'object' || Array.isArray(experimental)) return false;
108
+ const proxyExt = experimental.ultra_lean_mcp_proxy;
109
+ if (!proxyExt || typeof proxyExt !== 'object' || Array.isArray(proxyExt)) return false;
110
+ const toolsHashSync = proxyExt.tools_hash_sync;
111
+ if (!toolsHashSync || typeof toolsHashSync !== 'object' || Array.isArray(toolsHashSync)) return false;
112
+ const version = toolsHashSync.version;
113
+ if (typeof version === 'number') return version === 1;
114
+ if (typeof version === 'string') return version.trim() === '1';
115
+ return false;
116
+ }
117
+
118
+ function extractToolsHashIfNoneMatch(params, algorithm) {
119
+ if (!params || typeof params !== 'object' || Array.isArray(params)) {
120
+ return { provided: false, valid: false, value: null };
121
+ }
122
+ const proxyExt = params._ultra_lean_mcp_proxy;
123
+ if (!proxyExt || typeof proxyExt !== 'object' || Array.isArray(proxyExt)) {
124
+ return { provided: false, valid: false, value: null };
125
+ }
126
+ const toolsHashSync = proxyExt.tools_hash_sync;
127
+ if (!toolsHashSync || typeof toolsHashSync !== 'object' || Array.isArray(toolsHashSync)) {
128
+ return { provided: false, valid: false, value: null };
129
+ }
130
+ if (!Object.prototype.hasOwnProperty.call(toolsHashSync, 'if_none_match')) {
131
+ return { provided: false, valid: false, value: null };
132
+ }
133
+ const normalized = parseIfNoneMatch(toolsHashSync.if_none_match, { expectedAlgorithm: algorithm });
134
+ if (!normalized) {
135
+ return { provided: true, valid: false, value: null };
136
+ }
137
+ return { provided: true, valid: true, value: normalized };
138
+ }
139
+
140
+ function injectInitializeToolsHashCapability(result, algorithm) {
141
+ if (!result || typeof result !== 'object' || Array.isArray(result)) return result;
142
+ const out = cloneJson(result);
143
+ if (!out.capabilities || typeof out.capabilities !== 'object' || Array.isArray(out.capabilities)) {
144
+ out.capabilities = {};
145
+ }
146
+ if (
147
+ !out.capabilities.experimental
148
+ || typeof out.capabilities.experimental !== 'object'
149
+ || Array.isArray(out.capabilities.experimental)
150
+ ) {
151
+ out.capabilities.experimental = {};
152
+ }
153
+ if (
154
+ !out.capabilities.experimental.ultra_lean_mcp_proxy
155
+ || typeof out.capabilities.experimental.ultra_lean_mcp_proxy !== 'object'
156
+ || Array.isArray(out.capabilities.experimental.ultra_lean_mcp_proxy)
157
+ ) {
158
+ out.capabilities.experimental.ultra_lean_mcp_proxy = {};
159
+ }
160
+ out.capabilities.experimental.ultra_lean_mcp_proxy.tools_hash_sync = {
161
+ version: 1,
162
+ algorithm,
163
+ };
164
+ return out;
165
+ }
166
+
167
+ function toolsHashScopeKey(cfg, profileFingerprint) {
168
+ return `${cfg.sessionId}:${cfg.serverName}:${profileFingerprint}`;
169
+ }
170
+
171
+ function buildProfileFingerprint(cfg, upstreamCommand) {
172
+ return stableHash({
173
+ server_name: cfg.serverName,
174
+ command: upstreamCommand.join(' '),
175
+ });
176
+ }
177
+
178
+ function buildSearchToolDefinition(toolNames = null) {
179
+ const baseDesc = 'Search available tools and return full schemas on demand.';
180
+ let description = baseDesc;
181
+ if (toolNames && toolNames.length > 0) {
182
+ description = baseDesc
183
+ + ' Use "select:<tool_name>" for direct selection, or keywords to search.\n\n'
184
+ + 'Available tools (must be loaded via this tool before use):\n'
185
+ + toolNames.join('\n');
186
+ }
187
+ return {
188
+ name: SEARCH_TOOL_NAME,
189
+ description,
190
+ inputSchema: {
191
+ type: 'object',
192
+ properties: {
193
+ query: { type: 'string', description: 'Search query' },
194
+ server: { type: 'string', description: 'Optional server name' },
195
+ top_k: { type: 'integer', description: 'Max number of results', default: 8 },
196
+ include_schemas: {
197
+ type: 'boolean',
198
+ description: 'Include inputSchema in matches',
199
+ default: false,
200
+ },
201
+ },
202
+ required: ['query'],
203
+ },
204
+ };
205
+ }
206
+
207
+ function applyDefinitionCompression(tools) {
208
+ const out = [];
209
+ for (const tool of tools) {
210
+ const item = cloneJson(tool);
211
+ if (Object.prototype.hasOwnProperty.call(item, 'description')) {
212
+ item.description = compressDescription(String(item.description));
213
+ }
214
+ const schema = item.inputSchema || item.input_schema;
215
+ if (schema && typeof schema === 'object') {
216
+ compressSchema(schema);
217
+ }
218
+ out.push(item);
219
+ }
220
+ return out;
221
+ }
222
+
223
+ function stripSchemaMetadata(schema, depth = 0) {
224
+ if (typeof schema !== 'object' || schema === null) return schema;
225
+ const out = {};
226
+ if (schema.type !== undefined) out.type = schema.type;
227
+ if (Array.isArray(schema.required) && schema.required.length > 0) out.required = [...schema.required];
228
+ if (Array.isArray(schema.enum)) out.enum = [...schema.enum];
229
+ if (typeof schema.format === 'string') out.format = schema.format;
230
+ if (typeof schema.pattern === 'string') out.pattern = schema.pattern;
231
+ if (schema.const !== undefined) out.const = schema.const;
232
+ if (typeof schema.$ref === 'string') out.$ref = schema.$ref;
233
+ if (typeof schema.minimum === 'number') out.minimum = schema.minimum;
234
+ if (typeof schema.maximum === 'number') out.maximum = schema.maximum;
235
+ if (typeof schema.minLength === 'number') out.minLength = schema.minLength;
236
+ if (typeof schema.maxLength === 'number') out.maxLength = schema.maxLength;
237
+ if (typeof schema.minItems === 'number') out.minItems = schema.minItems;
238
+ if (typeof schema.maxItems === 'number') out.maxItems = schema.maxItems;
239
+ if (typeof schema.description === 'string' && depth <= 1) {
240
+ out.description = compressDescription(schema.description);
241
+ }
242
+ if (schema.properties && typeof schema.properties === 'object' && !Array.isArray(schema.properties)) {
243
+ out.properties = {};
244
+ for (const [key, value] of Object.entries(schema.properties)) {
245
+ out.properties[key] = stripSchemaMetadata(value, depth + 1);
246
+ }
247
+ }
248
+ if (Array.isArray(schema.items)) {
249
+ out.items = schema.items.map(s => stripSchemaMetadata(s, depth + 1));
250
+ } else if (schema.items && typeof schema.items === 'object') {
251
+ out.items = stripSchemaMetadata(schema.items, depth + 1);
252
+ }
253
+ for (const key of ['anyOf', 'oneOf', 'allOf']) {
254
+ if (Array.isArray(schema[key])) {
255
+ out[key] = schema[key].map(s => stripSchemaMetadata(s, depth + 1));
256
+ }
257
+ }
258
+ if (schema.not && typeof schema.not === 'object' && !Array.isArray(schema.not)) {
259
+ out.not = stripSchemaMetadata(schema.not, depth + 1);
260
+ }
261
+ return out;
262
+ }
263
+
264
+ function minimalTool(tool) {
265
+ const name = tool?.name || '';
266
+ const description = tool?.description || '';
267
+ const schema = tool?.inputSchema || tool?.input_schema || {};
268
+ return {
269
+ name,
270
+ description: compressDescription(description) || description,
271
+ inputSchema: stripSchemaMetadata(schema, 0),
272
+ };
273
+ }
274
+
275
+ function handleToolsListResult(
276
+ result,
277
+ state,
278
+ cfg,
279
+ metrics,
280
+ tokenCounter,
281
+ {
282
+ toolsHashSyncNegotiated,
283
+ profileFingerprint,
284
+ ifNoneMatch = null,
285
+ ifNoneMatchProvided = false,
286
+ ifNoneMatchValid = false,
287
+ } = {}
288
+ ) {
289
+ const tools = result?.tools;
290
+ if (!Array.isArray(tools)) return result;
291
+
292
+ metrics.toolsListRequests += 1;
293
+ const originalSize = jsonSize(result);
294
+
295
+ let processedTools = cloneJson(tools);
296
+ if (cfg.definitionCompressionEnabled) {
297
+ processedTools = applyDefinitionCompression(processedTools);
298
+ }
299
+ state.setTools(processedTools);
300
+
301
+ let visibleTools = processedTools;
302
+ let lazyAllowed = false;
303
+ if (cfg.lazyLoadingEnabled) {
304
+ const toolCount = processedTools.length;
305
+ const toolTokens = tokenCounter.count({ tools: processedTools });
306
+ lazyAllowed = toolCount >= cfg.lazyMinTools || toolTokens >= cfg.lazyMinTokens;
307
+ }
308
+ if (lazyAllowed) {
309
+ if (cfg.lazyMode === 'search_only') {
310
+ visibleTools = [];
311
+ } else if (cfg.lazyMode === 'catalog') {
312
+ visibleTools = processedTools.map((t) => ({ name: t.name, inputSchema: { type: 'object' } }));
313
+ } else if (cfg.lazyMode === 'minimal') {
314
+ visibleTools = processedTools.map((tool) => minimalTool(tool));
315
+ }
316
+ const toolNames = cfg.lazyMode === 'catalog'
317
+ ? processedTools.map((t) => t.name)
318
+ : null;
319
+ visibleTools = [...visibleTools, buildSearchToolDefinition(toolNames)];
320
+ }
321
+
322
+ const out = cloneJson(result);
323
+ out.tools = visibleTools;
324
+ const compressedSize = jsonSize(out);
325
+ const saved = originalSize - compressedSize;
326
+ if (saved > 0) {
327
+ metrics.toolsListSavedBytes += saved;
328
+ }
329
+
330
+ if (!(cfg.toolsHashSyncEnabled && toolsHashSyncNegotiated)) {
331
+ return out;
332
+ }
333
+
334
+ const scopeKey = toolsHashScopeKey(cfg, profileFingerprint);
335
+ try {
336
+ const toolsHash = computeToolsHash(visibleTools, {
337
+ algorithm: cfg.toolsHashSyncAlgorithm,
338
+ includeServerFingerprint: cfg.toolsHashSyncIncludeServerFingerprint,
339
+ serverFingerprint: profileFingerprint,
340
+ });
341
+ state.toolsHashSetLast(scopeKey, toolsHash);
342
+
343
+ const conditionalMatch = Boolean(ifNoneMatchValid && ifNoneMatch === toolsHash);
344
+ if (conditionalMatch) {
345
+ const hitCount = state.toolsHashRecordHit(scopeKey);
346
+ metrics.toolsHashSyncHits += 1;
347
+ const forceRefresh = (hitCount % cfg.toolsHashSyncRefreshInterval) === 0;
348
+ if (!forceRefresh) {
349
+ const notModified = cloneJson(out);
350
+ notModified.tools = [];
351
+ if (!notModified._ultra_lean_mcp_proxy || typeof notModified._ultra_lean_mcp_proxy !== 'object') {
352
+ notModified._ultra_lean_mcp_proxy = {};
353
+ }
354
+ notModified._ultra_lean_mcp_proxy.tools_hash_sync = {
355
+ not_modified: true,
356
+ tools_hash: toolsHash,
357
+ };
358
+ metrics.toolsHashSyncNotModified += 1;
359
+ const byteDelta = Math.max(0, jsonSize(out) - jsonSize(notModified));
360
+ if (byteDelta > 0) metrics.toolsHashSyncSavedBytes += byteDelta;
361
+ const tokenDelta = Math.max(0, tokenCounter.count(out) - tokenCounter.count(notModified));
362
+ if (tokenDelta > 0) metrics.toolsHashSyncSavedTokens += tokenDelta;
363
+ return notModified;
364
+ }
365
+ } else if (ifNoneMatchProvided && ifNoneMatchValid) {
366
+ metrics.toolsHashSyncMisses += 1;
367
+ }
368
+
369
+ state.toolsHashResetHits(scopeKey);
370
+ if (!out._ultra_lean_mcp_proxy || typeof out._ultra_lean_mcp_proxy !== 'object') {
371
+ out._ultra_lean_mcp_proxy = {};
372
+ }
373
+ out._ultra_lean_mcp_proxy.tools_hash_sync = {
374
+ not_modified: false,
375
+ tools_hash: toolsHash,
376
+ };
377
+ return out;
378
+ } catch {
379
+ return out;
380
+ }
381
+ }
382
+
383
+ function buildSearchResult(state, cfg, argumentsValue) {
384
+ const query = String(argumentsValue?.query || '').trim();
385
+ const topKRaw = argumentsValue?.top_k ?? cfg.lazyTopK;
386
+ const includeSchemas = Boolean(argumentsValue?.include_schemas);
387
+ const parsedTopK = Number.parseInt(String(topKRaw), 10);
388
+ const topK = Number.isFinite(parsedTopK) && parsedTopK > 0 ? parsedTopK : cfg.lazyTopK;
389
+
390
+ const matches = state.searchTools(query, topK, includeSchemas);
391
+ const topScore = matches.length > 0 ? Number(matches[0].score || 0) : 0;
392
+ const payload = {
393
+ server: cfg.serverName,
394
+ query,
395
+ count: matches.length,
396
+ matches,
397
+ };
398
+ if (cfg.lazyFallbackFullOnLowConfidence && topScore < cfg.lazyMinConfidenceScore) {
399
+ payload.fallback = 'full_tools_due_low_confidence';
400
+ payload.top_score = topScore;
401
+ payload.tools = state.getTools();
402
+ }
403
+ return {
404
+ structuredContent: payload,
405
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
406
+ };
407
+ }
408
+
409
+ function toolCacheAllowed(cfg, toolName) {
410
+ if (!toolName || !cfg.cachingEnabled) return false;
411
+ if (!featureEnabledForTool(cfg, toolName, 'caching', true)) return false;
412
+ if (!cfg.cacheMutatingTools && isMutatingToolName(toolName)) return false;
413
+ return true;
414
+ }
415
+
416
+ function minifyRedundantTextContent(content, originalPayload) {
417
+ const kept = [];
418
+ let removed = 0;
419
+ for (const item of content) {
420
+ if (!item || typeof item !== 'object' || item.type !== 'text') {
421
+ kept.push(item);
422
+ continue;
423
+ }
424
+ const text = item.text;
425
+ if (typeof text !== 'string') {
426
+ kept.push(item);
427
+ continue;
428
+ }
429
+ const trimmed = text.trim();
430
+ if (!(trimmed.startsWith('{') || trimmed.startsWith('['))) {
431
+ kept.push(item);
432
+ continue;
433
+ }
434
+ try {
435
+ const parsed = JSON.parse(trimmed);
436
+ if (JSON.stringify(parsed) === JSON.stringify(originalPayload)) {
437
+ removed += 1;
438
+ continue;
439
+ }
440
+ } catch {
441
+ // keep on parse errors
442
+ }
443
+ kept.push(item);
444
+ }
445
+ if (removed > 0 && kept.length === 0) {
446
+ kept.push({ type: 'text', text: '[ultra-lean-mcp-proxy] structured result' });
447
+ }
448
+ return { content: kept, changed: removed > 0 };
449
+ }
450
+
451
+ function applyResultCompression(
452
+ result,
453
+ toolName,
454
+ cfg,
455
+ metrics,
456
+ tokenCounter,
457
+ featureStates,
458
+ keyRegistry,
459
+ keyRegistryCounter
460
+ ) {
461
+ if (!cfg.resultCompressionEnabled) return result;
462
+ if (!featureEnabledForTool(cfg, toolName, 'result_compression', true)) return result;
463
+
464
+ const featureKey = featureHealthKey('result_compression', toolName);
465
+ if (!featureIsActive(featureStates, featureKey, cfg)) return result;
466
+
467
+ const options = makeCompressionOptions({
468
+ mode: cfg.resultCompressionMode,
469
+ stripNulls: cfg.resultStripNulls,
470
+ stripDefaults: cfg.resultStripDefaults,
471
+ minPayloadBytes: cfg.resultMinPayloadBytes,
472
+ });
473
+
474
+ let outcome = 'neutral';
475
+ try {
476
+ if (
477
+ result
478
+ && typeof result === 'object'
479
+ && !Array.isArray(result)
480
+ && (Array.isArray(result.structuredContent) || (
481
+ result.structuredContent
482
+ && typeof result.structuredContent === 'object'
483
+ ))
484
+ ) {
485
+ const out = cloneJson(result);
486
+ const original = out.structuredContent;
487
+ if (estimateCompressibility(original) < cfg.resultMinCompressibility) {
488
+ recordFeatureOutcome(featureStates, featureKey, 'neutral', cfg);
489
+ return result;
490
+ }
491
+ const env = compressResult(original, options, {
492
+ keyRegistry,
493
+ registryCounter: keyRegistryCounter,
494
+ reuseKeys: cfg.resultSharedKeyRegistry,
495
+ keyBootstrapInterval: cfg.resultKeyBootstrapInterval,
496
+ });
497
+ if (env.compressed) {
498
+ const tokenDelta = tokenSavings(original, env, tokenCounter);
499
+ const minRequired = Math.max(
500
+ cfg.resultMinTokenSavingsAbs,
501
+ Math.floor(tokenCounter.count(original) * cfg.resultMinTokenSavingsRatio)
502
+ );
503
+ if (tokenDelta >= minRequired) {
504
+ out.structuredContent = env;
505
+ if (!out._ultra_lean_mcp_proxy || typeof out._ultra_lean_mcp_proxy !== 'object') {
506
+ out._ultra_lean_mcp_proxy = {};
507
+ }
508
+ out._ultra_lean_mcp_proxy.result_compression = {
509
+ saved_bytes: env.savedBytes || 0,
510
+ saved_ratio: env.savedRatio || 0,
511
+ saved_tokens: tokenDelta,
512
+ };
513
+ metrics.resultCompressions += 1;
514
+ metrics.resultSavedBytes += Number(env.savedBytes || 0);
515
+ outcome = 'success';
516
+ if (cfg.resultMinifyRedundantText && Array.isArray(out.content)) {
517
+ const minified = minifyRedundantTextContent(out.content, original);
518
+ if (minified.changed) {
519
+ out.content = minified.content;
520
+ }
521
+ }
522
+ recordFeatureOutcome(featureStates, featureKey, outcome, cfg);
523
+ return out;
524
+ }
525
+ if (tokenDelta < 0) outcome = 'hurt';
526
+ }
527
+ recordFeatureOutcome(featureStates, featureKey, outcome, cfg);
528
+ return result;
529
+ }
530
+
531
+ if (result && typeof result === 'object' && !Array.isArray(result) && Array.isArray(result.content)) {
532
+ const out = cloneJson(result);
533
+ let changed = false;
534
+ let totalSavedBytes = 0;
535
+ let totalSavedTokens = 0;
536
+ for (const item of out.content) {
537
+ if (!item || typeof item !== 'object' || item.type !== 'text') continue;
538
+ if (typeof item.text !== 'string') continue;
539
+ const trimmed = item.text.trim();
540
+ if (!(trimmed.startsWith('{') || trimmed.startsWith('['))) continue;
541
+ let parsed;
542
+ try {
543
+ parsed = JSON.parse(trimmed);
544
+ } catch {
545
+ continue;
546
+ }
547
+ if (estimateCompressibility(parsed) < cfg.resultMinCompressibility) continue;
548
+ const env = compressResult(parsed, options, {
549
+ keyRegistry,
550
+ registryCounter: keyRegistryCounter,
551
+ reuseKeys: cfg.resultSharedKeyRegistry,
552
+ keyBootstrapInterval: cfg.resultKeyBootstrapInterval,
553
+ });
554
+ if (!env.compressed) continue;
555
+ const tokenDelta = tokenSavings(parsed, env, tokenCounter);
556
+ const minRequired = Math.max(
557
+ cfg.resultMinTokenSavingsAbs,
558
+ Math.floor(tokenCounter.count(parsed) * cfg.resultMinTokenSavingsRatio)
559
+ );
560
+ if (tokenDelta >= minRequired) {
561
+ item.text = JSON.stringify(env);
562
+ changed = true;
563
+ totalSavedBytes += Number(env.savedBytes || 0);
564
+ totalSavedTokens += tokenDelta;
565
+ outcome = 'success';
566
+ } else if (tokenDelta < 0 && outcome !== 'success') {
567
+ outcome = 'hurt';
568
+ }
569
+ }
570
+ if (changed) {
571
+ if (!out._ultra_lean_mcp_proxy || typeof out._ultra_lean_mcp_proxy !== 'object') {
572
+ out._ultra_lean_mcp_proxy = {};
573
+ }
574
+ out._ultra_lean_mcp_proxy.result_compression = {
575
+ saved_bytes: totalSavedBytes,
576
+ saved_tokens: totalSavedTokens,
577
+ };
578
+ metrics.resultCompressions += 1;
579
+ metrics.resultSavedBytes += totalSavedBytes;
580
+ recordFeatureOutcome(featureStates, featureKey, 'success', cfg);
581
+ return out;
582
+ }
583
+ recordFeatureOutcome(featureStates, featureKey, outcome, cfg);
584
+ return result;
585
+ }
586
+ } catch {
587
+ recordFeatureOutcome(featureStates, featureKey, 'neutral', cfg);
588
+ return result;
589
+ }
590
+
591
+ recordFeatureOutcome(featureStates, featureKey, 'neutral', cfg);
592
+ return result;
593
+ }
594
+
595
+ function applyDeltaResponse(result, historyKey, toolName, state, cfg, metrics, deltaCounters, tokenCounter) {
596
+ const previous = state.historyGet(historyKey);
597
+ state.historySet(historyKey, result);
598
+
599
+ if (!cfg.deltaResponsesEnabled) return result;
600
+ if (!featureEnabledForTool(cfg, toolName, 'delta_responses', true)) return result;
601
+ if (previous === null) {
602
+ deltaCounters[historyKey] = 0;
603
+ return result;
604
+ }
605
+ if ((deltaCounters[historyKey] || 0) >= cfg.deltaSnapshotInterval) {
606
+ deltaCounters[historyKey] = 0;
607
+ return result;
608
+ }
609
+
610
+ const fullTokens = tokenCounter.count(result);
611
+
612
+ if (JSON.stringify(previous) === JSON.stringify(result)) {
613
+ const delta = {
614
+ encoding: 'lapc-delta-v1',
615
+ unchanged: true,
616
+ currentHash: stableHash(result),
617
+ };
618
+ const payload = { delta };
619
+ if (tokenCounter.count(payload) >= fullTokens) return result;
620
+ deltaCounters[historyKey] = (deltaCounters[historyKey] || 0) + 1;
621
+ metrics.deltaResponses += 1;
622
+ metrics.deltaSavedBytes += Math.max(0, jsonSize(result) - jsonSize(payload));
623
+ return {
624
+ structuredContent: payload,
625
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
626
+ };
627
+ }
628
+
629
+ try {
630
+ const delta = createDelta(previous, result, cfg.deltaMinSavingsRatio, cfg.deltaMaxPatchBytes);
631
+ if (!delta) return result;
632
+ const patchRatio = Number(delta.fullBytes || 0) > 0
633
+ ? Number(delta.patchBytes || 0) / Number(delta.fullBytes || 1)
634
+ : 0;
635
+ if (patchRatio > cfg.deltaMaxPatchRatio) return result;
636
+ const payload = { delta };
637
+ if (tokenCounter.count(payload) >= fullTokens) return result;
638
+ deltaCounters[historyKey] = (deltaCounters[historyKey] || 0) + 1;
639
+ metrics.deltaResponses += 1;
640
+ metrics.deltaSavedBytes += Number(delta.savedBytes || 0);
641
+ return {
642
+ structuredContent: payload,
643
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
644
+ };
645
+ } catch {
646
+ return result;
647
+ }
648
+ }
649
+
650
+ function resolveSpawnOptions(commandName) {
651
+ const normalized = typeof commandName === 'string' ? commandName.trim().toLowerCase() : '';
652
+ const isCmdShim = normalized === 'cmd' || normalized === 'cmd.exe';
653
+ const useShellOnWindows = process.platform === 'win32'
654
+ && typeof commandName === 'string'
655
+ && !isCmdShim
656
+ && !/[\\/]/.test(commandName)
657
+ && !/^[A-Za-z]:/.test(commandName);
658
+ return {
659
+ stdio: ['pipe', 'pipe', 'pipe'],
660
+ ...(useShellOnWindows ? { shell: true } : {}),
661
+ };
662
+ }
663
+
664
+ function parseMessageLine(line) {
665
+ try {
666
+ return JSON.parse(line);
667
+ } catch {
668
+ return null;
669
+ }
670
+ }
671
+
672
+ function traceInbound(traceRpc, msg) {
673
+ if (!traceRpc) return;
674
+ if (msg.method) {
675
+ const idPart = msg.id !== undefined ? ` id=${msg.id}` : '';
676
+ const kind = msg.id !== undefined ? 'request' : 'notification';
677
+ process.stderr.write(`[ultra-lean-mcp-proxy] rpc<- client ${kind} method=${msg.method}${idPart}\n`);
678
+ } else if (msg.id !== undefined) {
679
+ process.stderr.write(`[ultra-lean-mcp-proxy] rpc<- client response id=${msg.id}\n`);
680
+ }
681
+ }
682
+
683
+ function traceUpstream(traceRpc, msg, pending) {
684
+ if (!traceRpc) return;
685
+ if (msg.method) {
686
+ const idPart = msg.id !== undefined ? ` id=${msg.id}` : '';
687
+ const kind = msg.id !== undefined ? 'request' : 'notification';
688
+ process.stderr.write(`[ultra-lean-mcp-proxy] rpc<- upstream ${kind} method=${msg.method}${idPart}\n`);
689
+ } else if (msg.id !== undefined) {
690
+ const req = pending.get(msg.id);
691
+ const methodPart = req?.method ? ` method=${req.method}` : '';
692
+ const status = msg.error ? 'error' : 'result';
693
+ process.stderr.write(
694
+ `[ultra-lean-mcp-proxy] rpc<- upstream response id=${msg.id}${methodPart} status=${status}\n`
695
+ );
696
+ }
697
+ }
698
+
699
+ export function runProxy(upstreamCommand, options = {}) {
700
+ const traceRpc = Boolean(options.traceRpc);
701
+ const cfg = loadProxyConfig({
702
+ upstreamCommand,
703
+ configPath: options.configPath || null,
704
+ cliOverrides: {
705
+ stats: options.stats,
706
+ verbose: options.verbose,
707
+ sessionId: options.sessionId,
708
+ strictConfig: options.strictConfig,
709
+ resultCompression: options.resultCompression,
710
+ deltaResponses: options.deltaResponses,
711
+ lazyLoading: options.lazyLoading,
712
+ toolsHashSync: options.toolsHashSync,
713
+ caching: options.caching,
714
+ cacheTtl: options.cacheTtl,
715
+ deltaMinSavings: options.deltaMinSavings,
716
+ lazyMode: options.lazyMode,
717
+ toolsHashRefreshInterval: options.toolsHashRefreshInterval,
718
+ searchTopK: options.searchTopK,
719
+ resultCompressionMode: options.resultCompressionMode,
720
+ configPath: options.configPath,
721
+ },
722
+ });
723
+
724
+ if (options.stats) cfg.stats = true;
725
+
726
+ if (options.dumpEffectiveConfig) {
727
+ process.stderr.write(`${JSON.stringify(cfg, null, 2)}\n`);
728
+ }
729
+
730
+ const featureSummary = [
731
+ `definition=${cfg.definitionCompressionEnabled ? 'on' : 'off'}`,
732
+ `result=${cfg.resultCompressionEnabled ? 'on' : 'off'}`,
733
+ `delta=${cfg.deltaResponsesEnabled ? 'on' : 'off'}`,
734
+ `lazy=${cfg.lazyLoadingEnabled ? cfg.lazyMode : 'off'}`,
735
+ `tools_hash_sync=${cfg.toolsHashSyncEnabled ? 'on' : 'off'}`,
736
+ `cache=${cfg.cachingEnabled ? 'on' : 'off'}`,
737
+ ].join(',');
738
+ process.stderr.write(`[ultra-lean-mcp-proxy] runtime=npm features=${featureSummary}\n`);
739
+ if (traceRpc) {
740
+ process.stderr.write('[ultra-lean-mcp-proxy] trace-rpc enabled\n');
741
+ }
742
+
743
+ const upstream = spawn(upstreamCommand[0], upstreamCommand.slice(1), resolveSpawnOptions(upstreamCommand[0]));
744
+ const profileFingerprint = buildProfileFingerprint(cfg, upstreamCommand);
745
+
746
+ const pending = new Map();
747
+ const state = new ProxyState(cfg.cacheMaxEntries);
748
+ const tokenCounter = new TokenCounter();
749
+ const featureStates = {};
750
+ const deltaCounters = {};
751
+ const keyRegistry = {};
752
+ const keyRegistryCounter = {};
753
+ let toolsHashSyncNegotiated = false;
754
+
755
+ const metrics = {
756
+ toolsListRequests: 0,
757
+ toolsListSavedBytes: 0,
758
+ toolsHashSyncHits: 0,
759
+ toolsHashSyncMisses: 0,
760
+ toolsHashSyncNotModified: 0,
761
+ toolsHashSyncSavedBytes: 0,
762
+ toolsHashSyncSavedTokens: 0,
763
+ cacheHits: 0,
764
+ cacheMisses: 0,
765
+ resultCompressions: 0,
766
+ resultSavedBytes: 0,
767
+ deltaResponses: 0,
768
+ deltaSavedBytes: 0,
769
+ searchCalls: 0,
770
+ upstreamRequests: 0,
771
+ upstreamRequestBytes: 0,
772
+ upstreamRequestTokens: 0,
773
+ upstreamResponses: 0,
774
+ upstreamResponseBytes: 0,
775
+ upstreamResponseTokens: 0,
776
+ };
777
+
778
+ function sendToClient(msg) {
779
+ if (cfg.stats && msg && typeof msg === 'object') {
780
+ const result = msg.result;
781
+ if (result && typeof result === 'object' && !Array.isArray(result)) {
782
+ if (!result._ultra_lean_mcp_proxy || typeof result._ultra_lean_mcp_proxy !== 'object') {
783
+ result._ultra_lean_mcp_proxy = {};
784
+ }
785
+ result._ultra_lean_mcp_proxy.runtime_metrics = runtimeMetricsSnapshot(metrics);
786
+ }
787
+ }
788
+ process.stdout.write(`${JSON.stringify(msg)}\n`);
789
+ }
790
+
791
+ createLineReader(process.stdin, (line) => {
792
+ const msg = parseMessageLine(line);
793
+ if (!msg) {
794
+ if (traceRpc) {
795
+ process.stderr.write('[ultra-lean-mcp-proxy] rpc<- client non-json-line\n');
796
+ }
797
+ upstream.stdin.write(`${line}\n`);
798
+ return;
799
+ }
800
+
801
+ traceInbound(traceRpc, msg);
802
+
803
+ const method = msg.method;
804
+ const reqId = msg.id;
805
+ let shortCircuited = false;
806
+
807
+ if (typeof method === 'string' && reqId !== undefined) {
808
+ try {
809
+ if (method === 'initialize') {
810
+ pending.set(reqId, {
811
+ method,
812
+ clientToolsHashSyncSupported: clientSupportsToolsHashSync(msg.params),
813
+ });
814
+ } else if (method === 'tools/list') {
815
+ const conditional = extractToolsHashIfNoneMatch(msg.params, cfg.toolsHashSyncAlgorithm);
816
+ if (
817
+ cfg.toolsHashSyncEnabled
818
+ && toolsHashSyncNegotiated
819
+ && conditional.valid
820
+ && typeof conditional.value === 'string'
821
+ ) {
822
+ const scopeKey = toolsHashScopeKey(cfg, profileFingerprint);
823
+ const entry = state.toolsHashGet(scopeKey);
824
+ if (entry && entry.lastHash === conditional.value) {
825
+ const nextHit = (entry.conditionalHits || 0) + 1;
826
+ const forceRefresh = (nextHit % cfg.toolsHashSyncRefreshInterval) === 0;
827
+ if (!forceRefresh) {
828
+ state.toolsHashRecordHit(scopeKey);
829
+ metrics.toolsHashSyncHits += 1;
830
+ metrics.toolsHashSyncNotModified += 1;
831
+ sendToClient({
832
+ jsonrpc: msg.jsonrpc || '2.0',
833
+ id: reqId,
834
+ result: {
835
+ tools: [],
836
+ _ultra_lean_mcp_proxy: {
837
+ tools_hash_sync: {
838
+ not_modified: true,
839
+ tools_hash: conditional.value,
840
+ },
841
+ },
842
+ },
843
+ });
844
+ shortCircuited = true;
845
+ }
846
+ }
847
+ }
848
+ if (!shortCircuited) {
849
+ pending.set(reqId, {
850
+ method,
851
+ toolsHashIfNoneMatch: conditional.value,
852
+ toolsHashIfNoneMatchProvided: conditional.provided,
853
+ toolsHashIfNoneMatchValid: conditional.valid,
854
+ });
855
+ }
856
+ } else if (method === 'tools/call') {
857
+ const [toolName, argumentsValue] = extractToolCall(msg);
858
+
859
+ if (cfg.lazyLoadingEnabled && toolName === SEARCH_TOOL_NAME) {
860
+ let searchResult = buildSearchResult(state, cfg, argumentsValue);
861
+ searchResult = applyResultCompression(
862
+ searchResult,
863
+ toolName,
864
+ cfg,
865
+ metrics,
866
+ tokenCounter,
867
+ featureStates,
868
+ keyRegistry,
869
+ keyRegistryCounter
870
+ );
871
+ metrics.searchCalls += 1;
872
+ sendToClient({
873
+ jsonrpc: msg.jsonrpc || '2.0',
874
+ id: reqId,
875
+ result: searchResult,
876
+ });
877
+ shortCircuited = true;
878
+ }
879
+
880
+ if (!shortCircuited) {
881
+ let cacheKey = null;
882
+ if (toolCacheAllowed(cfg, toolName)) {
883
+ cacheKey = makeCacheKey(cfg.sessionId, cfg.serverName, toolName, argumentsValue);
884
+ const cached = state.cacheGet(cacheKey);
885
+ if (cached !== null) {
886
+ metrics.cacheHits += 1;
887
+ const delivered = applyDeltaResponse(
888
+ cached,
889
+ cacheKey,
890
+ toolName,
891
+ state,
892
+ cfg,
893
+ metrics,
894
+ deltaCounters,
895
+ tokenCounter
896
+ );
897
+ sendToClient({
898
+ jsonrpc: msg.jsonrpc || '2.0',
899
+ id: reqId,
900
+ result: delivered,
901
+ });
902
+ shortCircuited = true;
903
+ } else {
904
+ metrics.cacheMisses += 1;
905
+ }
906
+ }
907
+
908
+ if (!shortCircuited) {
909
+ pending.set(reqId, {
910
+ method,
911
+ toolName,
912
+ argumentsValue,
913
+ cacheKey,
914
+ });
915
+ }
916
+ }
917
+ } else {
918
+ pending.set(reqId, { method });
919
+ }
920
+ } catch {
921
+ // fail-open
922
+ }
923
+ }
924
+
925
+ if (shortCircuited) {
926
+ return;
927
+ }
928
+
929
+ upstream.stdin.write(`${JSON.stringify(msg)}\n`);
930
+ metrics.upstreamRequests += 1;
931
+ metrics.upstreamRequestBytes += jsonSize(msg);
932
+ metrics.upstreamRequestTokens += tokenCounter.count(msg);
933
+ });
934
+
935
+ createLineReader(upstream.stdout, (line) => {
936
+ const msg = parseMessageLine(line);
937
+ if (!msg) {
938
+ if (traceRpc) {
939
+ process.stderr.write('[ultra-lean-mcp-proxy] rpc<- upstream non-json-line\n');
940
+ }
941
+ process.stdout.write(`${line}\n`);
942
+ return;
943
+ }
944
+
945
+ metrics.upstreamResponses += 1;
946
+ metrics.upstreamResponseBytes += jsonSize(msg);
947
+ metrics.upstreamResponseTokens += tokenCounter.count(msg);
948
+
949
+ traceUpstream(traceRpc, msg, pending);
950
+
951
+ const reqId = msg.id;
952
+ if (reqId !== undefined && Object.prototype.hasOwnProperty.call(msg, 'result')) {
953
+ const pendingReq = pending.get(reqId);
954
+ pending.delete(reqId);
955
+
956
+ if (pendingReq && pendingReq.method === 'initialize') {
957
+ if (cfg.toolsHashSyncEnabled && pendingReq.clientToolsHashSyncSupported) {
958
+ toolsHashSyncNegotiated = true;
959
+ try {
960
+ msg.result = injectInitializeToolsHashCapability(msg.result, cfg.toolsHashSyncAlgorithm);
961
+ } catch {
962
+ // fail-open
963
+ }
964
+ } else {
965
+ toolsHashSyncNegotiated = false;
966
+ }
967
+ } else if (pendingReq && pendingReq.method === 'tools/list') {
968
+ try {
969
+ msg.result = handleToolsListResult(
970
+ msg.result,
971
+ state,
972
+ cfg,
973
+ metrics,
974
+ tokenCounter,
975
+ {
976
+ toolsHashSyncNegotiated,
977
+ profileFingerprint,
978
+ ifNoneMatch: pendingReq.toolsHashIfNoneMatch,
979
+ ifNoneMatchProvided: pendingReq.toolsHashIfNoneMatchProvided,
980
+ ifNoneMatchValid: pendingReq.toolsHashIfNoneMatchValid,
981
+ }
982
+ );
983
+ } catch {
984
+ // fail-open
985
+ }
986
+ } else if (pendingReq && pendingReq.method === 'tools/call') {
987
+ try {
988
+ const rawUpstreamResult = cloneJson(msg.result);
989
+ let result = msg.result;
990
+ result = applyResultCompression(
991
+ result,
992
+ pendingReq.toolName,
993
+ cfg,
994
+ metrics,
995
+ tokenCounter,
996
+ featureStates,
997
+ keyRegistry,
998
+ keyRegistryCounter
999
+ );
1000
+
1001
+ if (
1002
+ cfg.cachingEnabled
1003
+ && !cfg.cacheMutatingTools
1004
+ && pendingReq.toolName
1005
+ && isMutatingToolName(pendingReq.toolName)
1006
+ ) {
1007
+ const scopePrefix = `${cfg.sessionId}:${cfg.serverName}:`;
1008
+ state.cacheInvalidatePrefix(scopePrefix);
1009
+ state.historyInvalidatePrefix(`cache_raw:${scopePrefix}`);
1010
+ }
1011
+
1012
+ const cacheKey = pendingReq.cacheKey;
1013
+ if (cacheKey && toolCacheAllowed(cfg, pendingReq.toolName)) {
1014
+ const baseTtl = cacheTtlForTool(cfg, pendingReq.toolName);
1015
+ let ttl = baseTtl;
1016
+ if (cfg.cacheAdaptiveTtl && baseTtl > 0) {
1017
+ const rawKey = `cache_raw:${cacheKey}`;
1018
+ const previousRaw = state.historyGet(rawKey);
1019
+ if (previousRaw !== null) {
1020
+ const changed = JSON.stringify(previousRaw) !== JSON.stringify(rawUpstreamResult);
1021
+ if (changed) {
1022
+ ttl = Math.max(cfg.cacheTtlMinSeconds, Math.floor(baseTtl * 0.5));
1023
+ } else {
1024
+ ttl = Math.min(cfg.cacheTtlMaxSeconds, Math.floor(baseTtl * 1.5));
1025
+ }
1026
+ }
1027
+ ttl = Math.min(Math.max(ttl, cfg.cacheTtlMinSeconds), cfg.cacheTtlMaxSeconds);
1028
+ state.historySet(rawKey, rawUpstreamResult);
1029
+ }
1030
+ state.cacheSet(cacheKey, result, ttl);
1031
+ }
1032
+
1033
+ const historyKey = cacheKey || makeCacheKey(
1034
+ cfg.sessionId,
1035
+ cfg.serverName,
1036
+ pendingReq.toolName || '_unknown',
1037
+ pendingReq.argumentsValue || {}
1038
+ );
1039
+ result = applyDeltaResponse(
1040
+ result,
1041
+ historyKey,
1042
+ pendingReq.toolName,
1043
+ state,
1044
+ cfg,
1045
+ metrics,
1046
+ deltaCounters,
1047
+ tokenCounter
1048
+ );
1049
+ msg.result = result;
1050
+ } catch {
1051
+ // fail-open
1052
+ }
1053
+ }
1054
+ } else if (reqId !== undefined && Object.prototype.hasOwnProperty.call(msg, 'error')) {
1055
+ const pendingReq = pending.get(reqId);
1056
+ pending.delete(reqId);
1057
+ if (pendingReq && pendingReq.method === 'initialize') {
1058
+ toolsHashSyncNegotiated = false;
1059
+ }
1060
+ }
1061
+
1062
+ sendToClient(msg);
1063
+ });
1064
+
1065
+ upstream.stderr.on('data', (chunk) => {
1066
+ process.stderr.write(chunk);
1067
+ });
1068
+
1069
+ function shutdown(code) {
1070
+ if (cfg.stats) {
1071
+ process.stderr.write(
1072
+ `[ultra-lean-mcp-proxy] stats: tools/list=${metrics.toolsListRequests} saved=${metrics.toolsListSavedBytes}B `
1073
+ + `tools_hash_sync hit=${metrics.toolsHashSyncHits} miss=${metrics.toolsHashSyncMisses} `
1074
+ + `not_modified=${metrics.toolsHashSyncNotModified} saved=${metrics.toolsHashSyncSavedBytes}B/`
1075
+ + `${metrics.toolsHashSyncSavedTokens}tok cache hit=${metrics.cacheHits} miss=${metrics.cacheMisses} `
1076
+ + `result_compression=${metrics.resultCompressions} saved=${metrics.resultSavedBytes}B `
1077
+ + `delta=${metrics.deltaResponses} saved=${metrics.deltaSavedBytes}B `
1078
+ + `search_calls=${metrics.searchCalls} upstream req=${metrics.upstreamRequests}/`
1079
+ + `${metrics.upstreamRequestTokens}tok/${metrics.upstreamRequestBytes}B rsp=${metrics.upstreamResponses}/`
1080
+ + `${metrics.upstreamResponseTokens}tok/${metrics.upstreamResponseBytes}B\n`
1081
+ );
1082
+ }
1083
+ process.exit(code ?? 0);
1084
+ }
1085
+
1086
+ process.stdin.on('end', () => {
1087
+ try {
1088
+ upstream.stdin.end();
1089
+ } catch {
1090
+ // ignore
1091
+ }
1092
+ setTimeout(() => {
1093
+ try {
1094
+ upstream.kill('SIGTERM');
1095
+ } catch {
1096
+ // ignore
1097
+ }
1098
+ }, 2000);
1099
+ });
1100
+
1101
+ upstream.on('exit', (code) => {
1102
+ shutdown(code);
1103
+ });
1104
+
1105
+ upstream.on('error', (err) => {
1106
+ process.stderr.write(`[ultra-lean-mcp-proxy] upstream error: ${err.message}\n`);
1107
+ process.exit(1);
1108
+ });
1109
+
1110
+ for (const sig of ['SIGINT', 'SIGTERM']) {
1111
+ process.on(sig, () => {
1112
+ try {
1113
+ upstream.kill(sig);
1114
+ } catch {
1115
+ // ignore
1116
+ }
1117
+ setTimeout(() => process.exit(1), 3000);
1118
+ });
1119
+ }
1120
+
1121
+ return new Promise(() => {});
1122
+ }