@mcp-ts/sdk 1.6.2 → 2.0.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.
Files changed (113) hide show
  1. package/README.md +12 -6
  2. package/dist/adapters/agui-adapter.d.mts +3 -3
  3. package/dist/adapters/agui-adapter.d.ts +3 -3
  4. package/dist/adapters/agui-adapter.js +4 -5
  5. package/dist/adapters/agui-adapter.js.map +1 -1
  6. package/dist/adapters/agui-adapter.mjs +4 -5
  7. package/dist/adapters/agui-adapter.mjs.map +1 -1
  8. package/dist/adapters/agui-middleware.d.mts +3 -3
  9. package/dist/adapters/agui-middleware.d.ts +3 -3
  10. package/dist/adapters/ai-adapter.d.mts +9 -3
  11. package/dist/adapters/ai-adapter.d.ts +9 -3
  12. package/dist/adapters/ai-adapter.js +20 -6
  13. package/dist/adapters/ai-adapter.js.map +1 -1
  14. package/dist/adapters/ai-adapter.mjs +20 -6
  15. package/dist/adapters/ai-adapter.mjs.map +1 -1
  16. package/dist/adapters/langchain-adapter.d.mts +3 -3
  17. package/dist/adapters/langchain-adapter.d.ts +3 -3
  18. package/dist/adapters/langchain-adapter.js +9 -6
  19. package/dist/adapters/langchain-adapter.js.map +1 -1
  20. package/dist/adapters/langchain-adapter.mjs +9 -6
  21. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  22. package/dist/adapters/mastra-adapter.d.mts +1 -1
  23. package/dist/adapters/mastra-adapter.d.ts +1 -1
  24. package/dist/adapters/mastra-adapter.js +5 -1
  25. package/dist/adapters/mastra-adapter.js.map +1 -1
  26. package/dist/adapters/mastra-adapter.mjs +5 -1
  27. package/dist/adapters/mastra-adapter.mjs.map +1 -1
  28. package/dist/bin/mcp-ts.js +7 -1
  29. package/dist/bin/mcp-ts.js.map +1 -1
  30. package/dist/bin/mcp-ts.mjs +7 -1
  31. package/dist/bin/mcp-ts.mjs.map +1 -1
  32. package/dist/client/index.d.mts +2 -2
  33. package/dist/client/index.d.ts +2 -2
  34. package/dist/client/index.js +9 -13
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/client/index.mjs +9 -13
  37. package/dist/client/index.mjs.map +1 -1
  38. package/dist/client/react.d.mts +7 -7
  39. package/dist/client/react.d.ts +7 -7
  40. package/dist/client/react.js +15 -19
  41. package/dist/client/react.js.map +1 -1
  42. package/dist/client/react.mjs +15 -19
  43. package/dist/client/react.mjs.map +1 -1
  44. package/dist/client/vue.d.mts +7 -7
  45. package/dist/client/vue.d.ts +7 -7
  46. package/dist/client/vue.js +14 -18
  47. package/dist/client/vue.js.map +1 -1
  48. package/dist/client/vue.mjs +14 -18
  49. package/dist/client/vue.mjs.map +1 -1
  50. package/dist/{index-DhA-OEAe.d.ts → index-C9gvpxy5.d.ts} +5 -5
  51. package/dist/{index-bFL4ZF2N.d.mts → index-eaH14_5u.d.mts} +5 -5
  52. package/dist/index.d.mts +6 -6
  53. package/dist/index.d.ts +6 -6
  54. package/dist/index.js +616 -370
  55. package/dist/index.js.map +1 -1
  56. package/dist/index.mjs +615 -370
  57. package/dist/index.mjs.map +1 -1
  58. package/dist/{multi-session-client-CHE8QpVE.d.ts → multi-session-client-BYtguGJm.d.ts} +22 -22
  59. package/dist/{multi-session-client-CQsRbxYI.d.mts → multi-session-client-DYNe6az3.d.mts} +22 -22
  60. package/dist/server/index.d.mts +31 -34
  61. package/dist/server/index.d.ts +31 -34
  62. package/dist/server/index.js +531 -256
  63. package/dist/server/index.js.map +1 -1
  64. package/dist/server/index.mjs +530 -256
  65. package/dist/server/index.mjs.map +1 -1
  66. package/dist/shared/index.d.mts +5 -5
  67. package/dist/shared/index.d.ts +5 -5
  68. package/dist/shared/index.js +76 -101
  69. package/dist/shared/index.js.map +1 -1
  70. package/dist/shared/index.mjs +76 -101
  71. package/dist/shared/index.mjs.map +1 -1
  72. package/dist/{tool-router-Dh2804tM.d.ts → tool-router-Ddtybmr0.d.ts} +71 -73
  73. package/dist/{tool-router-BVaV1udm.d.mts → tool-router-Dnd6IOKC.d.mts} +71 -73
  74. package/dist/{types-rIuN1CQi.d.mts → types-BCAG20P6.d.mts} +4 -4
  75. package/dist/{types-rIuN1CQi.d.ts → types-BCAG20P6.d.ts} +4 -4
  76. package/dist/{utils-0qmYrqoa.d.mts → utils-DELRKQPU.d.mts} +1 -1
  77. package/dist/{utils-0qmYrqoa.d.ts → utils-DELRKQPU.d.ts} +1 -1
  78. package/migrations/neon/20260513010000_install_mcp_sessions.sql +69 -0
  79. package/migrations/neon/20260513020000_add_session_cleanup_cron.sql +35 -0
  80. package/{supabase/migrations → migrations/supabase}/20260330195700_install_mcp_sessions.sql +7 -9
  81. package/package.json +14 -5
  82. package/src/adapters/ai-adapter.ts +30 -1
  83. package/src/adapters/langchain-adapter.ts +6 -2
  84. package/src/adapters/mastra-adapter.ts +6 -2
  85. package/src/bin/mcp-ts.ts +8 -1
  86. package/src/client/core/app-host.ts +1 -1
  87. package/src/client/core/sse-client.ts +12 -14
  88. package/src/client/core/types.ts +1 -1
  89. package/src/client/react/use-mcp-apps.tsx +1 -1
  90. package/src/client/react/use-mcp.ts +11 -11
  91. package/src/client/vue/use-mcp.ts +10 -10
  92. package/src/server/handlers/nextjs-handler.ts +18 -15
  93. package/src/server/handlers/sse-handler.ts +29 -29
  94. package/src/server/index.ts +1 -1
  95. package/src/server/mcp/multi-session-client.ts +17 -17
  96. package/src/server/mcp/oauth-client.ts +37 -37
  97. package/src/server/mcp/storage-oauth-provider.ts +17 -17
  98. package/src/server/storage/file-backend.ts +25 -25
  99. package/src/server/storage/index.ts +67 -10
  100. package/src/server/storage/memory-backend.ts +34 -34
  101. package/src/server/storage/neon-backend.ts +281 -0
  102. package/src/server/storage/redis-backend.ts +64 -64
  103. package/src/server/storage/sqlite-backend.ts +33 -33
  104. package/src/server/storage/supabase-backend.ts +23 -24
  105. package/src/server/storage/types.ts +18 -21
  106. package/src/shared/errors.ts +1 -1
  107. package/src/shared/index.ts +1 -2
  108. package/src/shared/meta-tools.ts +4 -6
  109. package/src/shared/schema-compressor.ts +2 -42
  110. package/src/shared/tool-index.ts +89 -84
  111. package/src/shared/tool-router.ts +0 -24
  112. package/src/shared/types.ts +4 -4
  113. /package/{supabase/migrations → migrations/supabase}/20260421010000_add_session_cleanup_cron.sql +0 -0
@@ -28,8 +28,6 @@ export interface ToolSummary {
28
28
  serverId: string;
29
29
  /** Session the tool belongs to */
30
30
  sessionId: string;
31
- /** Estimated token cost of the full inputSchema */
32
- estimatedTokens: number;
33
31
  }
34
32
 
35
33
  /** Server-level summary derived from indexed tools. */
@@ -106,41 +104,6 @@ export interface ToolIndexOptions {
106
104
  keywordWeight?: number;
107
105
  }
108
106
 
109
- // ---------------------------------------------------------------------------
110
- // Token Estimation
111
- // ---------------------------------------------------------------------------
112
-
113
- /**
114
- * Character-class weights for accurate-ish token estimation without a real
115
- * tokenizer. Empirically calibrated against cl100k_base on typical JSON
116
- * Schema payloads.
117
- *
118
- * | Char class | Approx chars per token |
119
- * |--------------------|------------------------|
120
- * | Whitespace / punct | 1–2 |
121
- * | English words | ~4 |
122
- * | JSON keys/values | ~3.5 |
123
- *
124
- * We walk the string once and accumulate a weighted character count, then
125
- * divide by a calibrated divisor.
126
- */
127
- const CALIBRATION_DIVISOR = 3.6;
128
-
129
- function classifyChar(ch: string): number {
130
- const code = ch.charCodeAt(0);
131
- // whitespace / common JSON structural chars → high token density
132
- if (code <= 0x20 || ch === '{' || ch === '}' || ch === '[' || ch === ']' || ch === ':' || ch === ',') return 1.0;
133
- // digits and symbols
134
- if (code >= 0x21 && code <= 0x2f) return 1.5;
135
- if (code >= 0x30 && code <= 0x39) return 2.0;
136
- // uppercase (often JSON keys)
137
- if (code >= 0x41 && code <= 0x5a) return 3.5;
138
- // lowercase (natural language in descriptions)
139
- if (code >= 0x61 && code <= 0x7a) return 4.0;
140
- // everything else (unicode, emojis, etc.)
141
- return 2.5;
142
- }
143
-
144
107
  // ---------------------------------------------------------------------------
145
108
  // ToolIndex
146
109
  // ---------------------------------------------------------------------------
@@ -170,9 +133,6 @@ export class ToolIndex {
170
133
  /** BM25: average document length across the entire index. */
171
134
  private avgDocLength = 0;
172
135
 
173
- /** Cached total estimated token cost across all indexed tools. */
174
- private totalTokenCost = 0;
175
-
176
136
  private options: Required<ToolIndexOptions>;
177
137
 
178
138
  constructor(options: ToolIndexOptions = {}) {
@@ -199,7 +159,6 @@ export class ToolIndex {
199
159
  this.embeddings.clear();
200
160
  this.docLengths.clear();
201
161
  this.avgDocLength = 0;
202
- this.totalTokenCost = 0;
203
162
 
204
163
  // 1. Populate tool map + search text
205
164
  const allTokenSets: Map<string, Set<string>> = new Map();
@@ -212,21 +171,19 @@ export class ToolIndex {
212
171
  this.tools.set(tool.name, []);
213
172
  }
214
173
  this.tools.get(tool.name)!.push(tool);
215
- const estimatedTokens = ToolIndex.estimateTokens(tool);
216
174
  this.toolSummaries.set(docKey, {
217
175
  name: tool.name,
218
176
  description: tool.description ?? '',
219
177
  serverName: tool.serverName,
220
178
  serverId: tool.serverId,
221
179
  sessionId: tool.sessionId,
222
- estimatedTokens,
223
180
  });
224
- this.totalTokenCost += estimatedTokens;
225
181
 
226
- const text = this.buildSearchableText(tool).toLowerCase();
182
+ const rawText = this.buildSearchableText(tool);
183
+ const text = rawText.toLowerCase();
227
184
  this.searchTexts.set(docKey, text);
228
185
 
229
- const tokens = this.tokenize(text);
186
+ const tokens = this.tokenize(rawText);
230
187
  const tf = new Map<string, number>();
231
188
  const uniqueTokens = new Set<string>();
232
189
 
@@ -578,60 +535,107 @@ export class ToolIndex {
578
535
  return count;
579
536
  }
580
537
 
581
- /** Total estimated token cost of all indexed tool schemas. */
582
- getTotalTokenCost(): number {
583
- return this.totalTokenCost;
584
- }
585
-
586
538
  // -----------------------------------------------------------------------
587
- // Static Helpers
539
+ // Internals
588
540
  // -----------------------------------------------------------------------
589
541
 
590
- /**
591
- * Estimate token count of a tool's full schema (name + description + inputSchema).
592
- *
593
- * Uses character-class weighted counting calibrated against cl100k_base.
594
- * Accuracy is typically within ±10% for JSON Schema payloads.
595
- */
596
- static estimateTokens(tool: Tool): number {
542
+ /** Build a single searchable string from tool metadata. */
543
+ private buildSearchableText(tool: Tool): string {
597
544
  const parts: string[] = [tool.name];
598
545
  if (tool.description) parts.push(tool.description);
599
- if (tool.inputSchema) parts.push(JSON.stringify(tool.inputSchema));
600
546
 
601
- const text = parts.join(' ');
602
- let weightedLen = 0;
603
-
604
- for (let i = 0; i < text.length; i++) {
605
- weightedLen += 1 / classifyChar(text[i]);
547
+ if (tool.inputSchema && typeof tool.inputSchema === 'object') {
548
+ this.collectSchemaSearchText(tool.inputSchema, parts);
606
549
  }
607
550
 
608
- return Math.ceil(weightedLen / (1 / CALIBRATION_DIVISOR));
551
+ return parts.join(' ');
609
552
  }
610
553
 
611
- // -----------------------------------------------------------------------
612
- // Internals
613
- // -----------------------------------------------------------------------
554
+ /** Recursively collect JSON Schema argument names and descriptions. */
555
+ private collectSchemaSearchText(
556
+ schema: unknown,
557
+ parts: string[],
558
+ seen = new WeakSet<object>()
559
+ ): void {
560
+ if (!schema || typeof schema !== 'object') return;
561
+ if (seen.has(schema)) return;
562
+ seen.add(schema);
563
+
564
+ if (Array.isArray(schema)) {
565
+ for (const item of schema) {
566
+ this.collectSchemaSearchText(item, parts, seen);
567
+ }
568
+ return;
569
+ }
614
570
 
615
- /** Build a single searchable string from tool metadata. */
616
- private buildSearchableText(tool: Tool): string {
617
- const parts: string[] = [tool.name];
618
- if (tool.description) parts.push(tool.description);
571
+ const schemaObject = schema as Record<string, unknown>;
572
+ this.pushStringValue(schemaObject.description, parts);
573
+ this.pushStringValue(schemaObject.title, parts);
619
574
 
620
- // Include property names and descriptions from schema
621
- if (tool.inputSchema && typeof tool.inputSchema === 'object') {
622
- const schema = tool.inputSchema as Record<string, unknown>;
623
- const props = schema.properties as Record<string, { description?: string }> | undefined;
624
- if (props) {
625
- for (const [key, val] of Object.entries(props)) {
626
- parts.push(key);
627
- if (val && typeof val === 'object' && val.description) {
628
- parts.push(val.description);
629
- }
575
+ const properties = schemaObject.properties;
576
+ if (properties && typeof properties === 'object' && !Array.isArray(properties)) {
577
+ for (const [propertyName, propertySchema] of Object.entries(properties)) {
578
+ parts.push(propertyName);
579
+ this.collectSchemaSearchText(propertySchema, parts, seen);
580
+ }
581
+ }
582
+
583
+ const patternProperties = schemaObject.patternProperties;
584
+ if (
585
+ patternProperties &&
586
+ typeof patternProperties === 'object' &&
587
+ !Array.isArray(patternProperties)
588
+ ) {
589
+ for (const [propertyPattern, propertySchema] of Object.entries(patternProperties)) {
590
+ parts.push(propertyPattern);
591
+ this.collectSchemaSearchText(propertySchema, parts, seen);
592
+ }
593
+ }
594
+
595
+ const dependentSchemas = schemaObject.dependentSchemas;
596
+ if (
597
+ dependentSchemas &&
598
+ typeof dependentSchemas === 'object' &&
599
+ !Array.isArray(dependentSchemas)
600
+ ) {
601
+ for (const [propertyName, dependentSchema] of Object.entries(dependentSchemas)) {
602
+ parts.push(propertyName);
603
+ this.collectSchemaSearchText(dependentSchema, parts, seen);
604
+ }
605
+ }
606
+
607
+ for (const key of [
608
+ 'items',
609
+ 'additionalProperties',
610
+ 'contains',
611
+ 'propertyNames',
612
+ 'if',
613
+ 'then',
614
+ 'else',
615
+ 'not',
616
+ ]) {
617
+ this.collectSchemaSearchText(schemaObject[key], parts, seen);
618
+ }
619
+
620
+ for (const key of ['allOf', 'anyOf', 'oneOf', 'prefixItems']) {
621
+ this.collectSchemaSearchText(schemaObject[key], parts, seen);
622
+ }
623
+
624
+ for (const key of ['$defs', 'definitions']) {
625
+ const definitions = schemaObject[key];
626
+ if (definitions && typeof definitions === 'object' && !Array.isArray(definitions)) {
627
+ for (const [definitionName, definitionSchema] of Object.entries(definitions)) {
628
+ parts.push(definitionName);
629
+ this.collectSchemaSearchText(definitionSchema, parts, seen);
630
630
  }
631
631
  }
632
632
  }
633
+ }
633
634
 
634
- return parts.join(' ');
635
+ private pushStringValue(value: unknown, parts: string[]): void {
636
+ if (typeof value === 'string' && value.trim()) {
637
+ parts.push(value);
638
+ }
635
639
  }
636
640
 
637
641
  private getDocumentKey(tool: IndexedTool): string {
@@ -662,6 +666,7 @@ export class ToolIndex {
662
666
  .replace(/([a-z])([A-Z])/g, '$1 $2')
663
667
  // Split snake_case / kebab-case
664
668
  .replace(/[_-]/g, ' ')
669
+ .toLowerCase()
665
670
  // Remove non-alphanumeric (except spaces)
666
671
  .replace(/[^a-z0-9\s]/g, '')
667
672
  // Split on whitespace
@@ -290,30 +290,6 @@ export class ToolRouter {
290
290
  return [...this.activeGroups];
291
291
  }
292
292
 
293
- // -----------------------------------------------------------------------
294
- // Stats & Introspection
295
- // -----------------------------------------------------------------------
296
-
297
- /** Total token cost of all tools if loaded without filtering. */
298
- getTotalTokenCost(): number {
299
- return this.index.getTotalTokenCost();
300
- }
301
-
302
- /** Estimate token cost of the currently filtered tool set. */
303
- async getFilteredTokenCost(): Promise<number> {
304
- const tools = await this.getFilteredTools();
305
- let total = 0;
306
- for (const tool of tools) {
307
- total += ToolIndex.estimateTokens(tool);
308
- }
309
- return total;
310
- }
311
-
312
- /** Get compression stats showing savings from current strategy. */
313
- getCompressionStats() {
314
- return SchemaCompressor.estimateSavings(this.allTools);
315
- }
316
-
317
293
  /** Number of total indexed tools. */
318
294
  get totalToolCount(): number {
319
295
  return this.allTools.length;
@@ -166,7 +166,7 @@ export type ToolInfo = {
166
166
  };
167
167
 
168
168
  // Transport type
169
- export type TransportType = 'sse' | 'streamable_http';
169
+ export type TransportType = 'sse' | 'streamable-http';
170
170
 
171
171
  // SSE/RPC types
172
172
  export type McpRpcMethod =
@@ -174,8 +174,8 @@ export type McpRpcMethod =
174
174
  | 'disconnect'
175
175
  | 'listTools'
176
176
  | 'callTool'
177
- | 'getSessions'
178
- | 'restoreSession'
177
+ | 'listSessions'
178
+ | 'getSession'
179
179
  | 'finishAuth'
180
180
  | 'listPrompts'
181
181
  | 'getPrompt'
@@ -275,7 +275,7 @@ export interface DisconnectResult {
275
275
  success: boolean;
276
276
  }
277
277
 
278
- export interface RestoreSessionResult {
278
+ export interface GetSessionResult {
279
279
  success: boolean;
280
280
  toolCount: number;
281
281
  }