@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
@@ -1,5 +1,5 @@
1
1
  import type { Database } from 'better-sqlite3';
2
- import { StorageBackend, SessionData } from './types.js'; // Ensure .js extension
2
+ import type { SessionStore, Session } from './types.js';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
5
  import { generateSessionId } from '../../shared/utils.js';
@@ -9,7 +9,7 @@ export interface SqliteStorageOptions {
9
9
  table?: string;
10
10
  }
11
11
 
12
- export class SqliteStorage implements StorageBackend {
12
+ export class SqliteStorage implements SessionStore {
13
13
  private db: Database | null = null;
14
14
  private table: string;
15
15
  private initialized = false;
@@ -37,11 +37,11 @@ export class SqliteStorage implements StorageBackend {
37
37
  this.db.exec(`
38
38
  CREATE TABLE IF NOT EXISTS ${this.table} (
39
39
  sessionId TEXT PRIMARY KEY,
40
- identity TEXT NOT NULL,
40
+ userId TEXT NOT NULL,
41
41
  data TEXT NOT NULL,
42
42
  expiresAt INTEGER
43
43
  );
44
- CREATE INDEX IF NOT EXISTS idx_${this.table}_identity ON ${this.table}(identity);
44
+ CREATE INDEX IF NOT EXISTS idx_${this.table}_userId ON ${this.table}(userId);
45
45
  `);
46
46
 
47
47
  this.initialized = true;
@@ -66,21 +66,21 @@ export class SqliteStorage implements StorageBackend {
66
66
  return generateSessionId();
67
67
  }
68
68
 
69
- async createSession(session: SessionData, ttl?: number): Promise<void> {
69
+ async create(session: Session, ttl?: number): Promise<void> {
70
70
  this.ensureInitialized();
71
- const { sessionId, identity } = session;
71
+ const { sessionId, userId } = session;
72
72
 
73
- if (!sessionId || !identity) {
74
- throw new Error('identity and sessionId required');
73
+ if (!sessionId || !userId) {
74
+ throw new Error('userId and sessionId required');
75
75
  }
76
76
 
77
77
  const expiresAt = ttl ? Date.now() + ttl * 1000 : null;
78
78
 
79
79
  try {
80
80
  const stmt = this.db!.prepare(
81
- `INSERT INTO ${this.table} (sessionId, identity, data, expiresAt) VALUES (?, ?, ?, ?)`
81
+ `INSERT INTO ${this.table} (sessionId, userId, data, expiresAt) VALUES (?, ?, ?, ?)`
82
82
  );
83
- stmt.run(sessionId, identity, JSON.stringify(session), expiresAt);
83
+ stmt.run(sessionId, userId, JSON.stringify(session), expiresAt);
84
84
  } catch (error: any) {
85
85
  if (error.code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {
86
86
  throw new Error(`Session ${sessionId} already exists`);
@@ -89,70 +89,70 @@ export class SqliteStorage implements StorageBackend {
89
89
  }
90
90
  }
91
91
 
92
- async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {
92
+ async update(userId: string, sessionId: string, data: Partial<Session>, ttl?: number): Promise<void> {
93
93
  this.ensureInitialized();
94
- if (!sessionId || !identity) {
95
- throw new Error('identity and sessionId required');
94
+ if (!sessionId || !userId) {
95
+ throw new Error('userId and sessionId required');
96
96
  }
97
97
 
98
- const currentSession = await this.getSession(identity, sessionId);
98
+ const currentSession = await this.get(userId, sessionId);
99
99
  if (!currentSession) {
100
- throw new Error(`Session ${sessionId} not found for identity ${identity}`);
100
+ throw new Error(`Session ${sessionId} not found for userId ${userId}`);
101
101
  }
102
102
 
103
103
  const updatedSession = { ...currentSession, ...data };
104
104
  const expiresAt = ttl ? Date.now() + ttl * 1000 : null;
105
105
 
106
106
  const stmt = this.db!.prepare(
107
- `UPDATE ${this.table} SET data = ?, expiresAt = ? WHERE sessionId = ? AND identity = ?`
107
+ `UPDATE ${this.table} SET data = ?, expiresAt = ? WHERE sessionId = ? AND userId = ?`
108
108
  );
109
109
 
110
- stmt.run(JSON.stringify(updatedSession), expiresAt, sessionId, identity);
110
+ stmt.run(JSON.stringify(updatedSession), expiresAt, sessionId, userId);
111
111
  }
112
112
 
113
- async getSession(identity: string, sessionId: string): Promise<SessionData | null> {
113
+ async get(userId: string, sessionId: string): Promise<Session | null> {
114
114
  this.ensureInitialized();
115
115
 
116
116
  const stmt = this.db!.prepare(
117
- `SELECT data FROM ${this.table} WHERE sessionId = ? AND identity = ?`
117
+ `SELECT data FROM ${this.table} WHERE sessionId = ? AND userId = ?`
118
118
  );
119
- const row = stmt.get(sessionId, identity) as { data: string } | undefined;
119
+ const row = stmt.get(sessionId, userId) as { data: string } | undefined;
120
120
 
121
121
  if (!row) return null;
122
- return JSON.parse(row.data) as SessionData;
122
+ return JSON.parse(row.data) as Session;
123
123
  }
124
124
 
125
- async getIdentitySessionsData(identity: string): Promise<SessionData[]> {
125
+ async list(userId: string): Promise<Session[]> {
126
126
  this.ensureInitialized();
127
127
 
128
128
  const stmt = this.db!.prepare(
129
- `SELECT data FROM ${this.table} WHERE identity = ?`
129
+ `SELECT data FROM ${this.table} WHERE userId = ?`
130
130
  );
131
- const rows = stmt.all(identity) as { data: string }[];
131
+ const rows = stmt.all(userId) as { data: string }[];
132
132
 
133
- return rows.map(row => JSON.parse(row.data) as SessionData);
133
+ return rows.map(row => JSON.parse(row.data) as Session);
134
134
  }
135
135
 
136
- async getIdentityMcpSessions(identity: string): Promise<string[]> {
136
+ async listIds(userId: string): Promise<string[]> {
137
137
  this.ensureInitialized();
138
138
 
139
139
  const stmt = this.db!.prepare(
140
- `SELECT sessionId FROM ${this.table} WHERE identity = ?`
140
+ `SELECT sessionId FROM ${this.table} WHERE userId = ?`
141
141
  );
142
- const rows = stmt.all(identity) as { sessionId: string }[];
142
+ const rows = stmt.all(userId) as { sessionId: string }[];
143
143
 
144
144
  return rows.map(row => row.sessionId);
145
145
  }
146
146
 
147
- async removeSession(identity: string, sessionId: string): Promise<void> {
147
+ async delete(userId: string, sessionId: string): Promise<void> {
148
148
  this.ensureInitialized();
149
149
  const stmt = this.db!.prepare(
150
- `DELETE FROM ${this.table} WHERE sessionId = ? AND identity = ?`
150
+ `DELETE FROM ${this.table} WHERE sessionId = ? AND userId = ?`
151
151
  );
152
- stmt.run(sessionId, identity);
152
+ stmt.run(sessionId, userId);
153
153
  }
154
154
 
155
- async getAllSessionIds(): Promise<string[]> {
155
+ async listAllIds(): Promise<string[]> {
156
156
  this.ensureInitialized();
157
157
  const stmt = this.db!.prepare(`SELECT sessionId FROM ${this.table}`);
158
158
  const rows = stmt.all() as { sessionId: string }[];
@@ -165,7 +165,7 @@ export class SqliteStorage implements StorageBackend {
165
165
  stmt.run();
166
166
  }
167
167
 
168
- async cleanupExpiredSessions(): Promise<void> {
168
+ async cleanupExpired(): Promise<void> {
169
169
  this.ensureInitialized();
170
170
  const now = Date.now();
171
171
  const stmt = this.db!.prepare(
@@ -1,10 +1,10 @@
1
1
  import type { SupabaseClient } from '@supabase/supabase-js';
2
- import { StorageBackend, SessionData } from './types.js';
2
+ import type { SessionStore, Session } from './types.js';
3
3
  import { SESSION_TTL_SECONDS } from '../../shared/constants.js';
4
4
  import { generateSessionId } from '../../shared/utils.js';
5
5
  import { encryptObject, decryptObject } from './crypto.js';
6
6
 
7
- export class SupabaseStorageBackend implements StorageBackend {
7
+ export class SupabaseStorageBackend implements SessionStore {
8
8
  private readonly DEFAULT_TTL = SESSION_TTL_SECONDS;
9
9
 
10
10
  constructor(private supabase: SupabaseClient) {}
@@ -34,7 +34,7 @@ export class SupabaseStorageBackend implements StorageBackend {
34
34
  return generateSessionId();
35
35
  }
36
36
 
37
- private mapRowToSessionData(row: any): SessionData {
37
+ private mapRowToSessionData(row: any): Session {
38
38
  return {
39
39
  sessionId: row.session_id,
40
40
  serverId: row.server_id,
@@ -43,7 +43,7 @@ export class SupabaseStorageBackend implements StorageBackend {
43
43
  transportType: row.transport_type,
44
44
  callbackUrl: row.callback_url,
45
45
  createdAt: new Date(row.created_at).getTime(),
46
- identity: row.identity,
46
+ userId: row.user_id,
47
47
  headers: decryptObject(row.headers),
48
48
  active: row.active,
49
49
  clientInformation: row.client_information,
@@ -53,9 +53,9 @@ export class SupabaseStorageBackend implements StorageBackend {
53
53
  };
54
54
  }
55
55
 
56
- async createSession(session: SessionData, ttl?: number): Promise<void> {
57
- const { sessionId, identity } = session;
58
- if (!sessionId || !identity) throw new Error('identity and sessionId required');
56
+ async create(session: Session, ttl?: number): Promise<void> {
57
+ const { sessionId, userId } = session;
58
+ if (!sessionId || !userId) throw new Error('userId and sessionId required');
59
59
 
60
60
  const effectiveTtl = ttl ?? this.DEFAULT_TTL;
61
61
  const expiresAt = new Date(Date.now() + effectiveTtl * 1000).toISOString();
@@ -64,14 +64,13 @@ export class SupabaseStorageBackend implements StorageBackend {
64
64
  .from('mcp_sessions')
65
65
  .insert({
66
66
  session_id: sessionId,
67
- user_id: identity, // Maps user_id to identity to support RLS using auth.uid()
67
+ user_id: userId, // Maps user_id to userId to support RLS using auth.uid()
68
68
  server_id: session.serverId,
69
69
  server_name: session.serverName,
70
70
  server_url: session.serverUrl,
71
71
  transport_type: session.transportType,
72
72
  callback_url: session.callbackUrl,
73
73
  created_at: new Date(session.createdAt || Date.now()).toISOString(),
74
- identity: identity,
75
74
  headers: encryptObject(session.headers),
76
75
  active: session.active ?? false,
77
76
  client_information: session.clientInformation,
@@ -90,7 +89,7 @@ export class SupabaseStorageBackend implements StorageBackend {
90
89
  }
91
90
  }
92
91
 
93
- async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {
92
+ async update(userId: string, sessionId: string, data: Partial<Session>, ttl?: number): Promise<void> {
94
93
  const effectiveTtl = ttl ?? this.DEFAULT_TTL;
95
94
  const expiresAt = new Date(Date.now() + effectiveTtl * 1000).toISOString();
96
95
 
@@ -115,7 +114,7 @@ export class SupabaseStorageBackend implements StorageBackend {
115
114
  const { data: updatedRows, error } = await this.supabase
116
115
  .from('mcp_sessions')
117
116
  .update(updateData)
118
- .eq('identity', identity)
117
+ .eq('user_id', userId)
119
118
  .eq('session_id', sessionId)
120
119
  .select('id');
121
120
 
@@ -124,15 +123,15 @@ export class SupabaseStorageBackend implements StorageBackend {
124
123
  }
125
124
 
126
125
  if (!updatedRows || updatedRows.length === 0) {
127
- throw new Error(`Session ${sessionId} not found for identity ${identity}`);
126
+ throw new Error(`Session ${sessionId} not found for userId ${userId}`);
128
127
  }
129
128
  }
130
129
 
131
- async getSession(identity: string, sessionId: string): Promise<SessionData | null> {
130
+ async get(userId: string, sessionId: string): Promise<Session | null> {
132
131
  const { data, error } = await this.supabase
133
132
  .from('mcp_sessions')
134
133
  .select('*')
135
- .eq('identity', identity)
134
+ .eq('user_id', userId)
136
135
  .eq('session_id', sessionId)
137
136
  .maybeSingle();
138
137
 
@@ -146,25 +145,25 @@ export class SupabaseStorageBackend implements StorageBackend {
146
145
  return this.mapRowToSessionData(data);
147
146
  }
148
147
 
149
- async getIdentitySessionsData(identity: string): Promise<SessionData[]> {
148
+ async list(userId: string): Promise<Session[]> {
150
149
  const { data, error } = await this.supabase
151
150
  .from('mcp_sessions')
152
151
  .select('*')
153
- .eq('identity', identity);
152
+ .eq('user_id', userId);
154
153
 
155
154
  if (error) {
156
- console.error(`[SupabaseStorage] Failed to get session data for ${identity}:`, error);
155
+ console.error(`[SupabaseStorage] Failed to get session data for ${userId}:`, error);
157
156
  return [];
158
157
  }
159
158
 
160
159
  return data.map(row => this.mapRowToSessionData(row));
161
160
  }
162
161
 
163
- async removeSession(identity: string, sessionId: string): Promise<void> {
162
+ async delete(userId: string, sessionId: string): Promise<void> {
164
163
  const { error } = await this.supabase
165
164
  .from('mcp_sessions')
166
165
  .delete()
167
- .eq('identity', identity)
166
+ .eq('user_id', userId)
168
167
  .eq('session_id', sessionId);
169
168
 
170
169
  if (error) {
@@ -172,21 +171,21 @@ export class SupabaseStorageBackend implements StorageBackend {
172
171
  }
173
172
  }
174
173
 
175
- async getIdentityMcpSessions(identity: string): Promise<string[]> {
174
+ async listIds(userId: string): Promise<string[]> {
176
175
  const { data, error } = await this.supabase
177
176
  .from('mcp_sessions')
178
177
  .select('session_id')
179
- .eq('identity', identity);
178
+ .eq('user_id', userId);
180
179
 
181
180
  if (error) {
182
- console.error(`[SupabaseStorage] Failed to get sessions for ${identity}:`, error);
181
+ console.error(`[SupabaseStorage] Failed to get sessions for ${userId}:`, error);
183
182
  return [];
184
183
  }
185
184
 
186
185
  return data.map(row => row.session_id);
187
186
  }
188
187
 
189
- async getAllSessionIds(): Promise<string[]> {
188
+ async listAllIds(): Promise<string[]> {
190
189
  const { data, error } = await this.supabase
191
190
  .from('mcp_sessions')
192
191
  .select('session_id');
@@ -211,7 +210,7 @@ export class SupabaseStorageBackend implements StorageBackend {
211
210
  }
212
211
  }
213
212
 
214
- async cleanupExpiredSessions(): Promise<void> {
213
+ async cleanupExpired(): Promise<void> {
215
214
  const { error } = await this.supabase
216
215
  .from('mcp_sessions')
217
216
  .delete()
@@ -5,15 +5,15 @@ import type {
5
5
  OAuthClientInformationMixed,
6
6
  } from '@modelcontextprotocol/sdk/shared/auth.js';
7
7
 
8
- export interface SessionData {
8
+ export interface Session {
9
9
  sessionId: string;
10
10
  serverId?: string; // Database server ID for mapping
11
11
  serverName?: string;
12
12
  serverUrl: string;
13
- transportType: 'sse' | 'streamable_http';
13
+ transportType: 'sse' | 'streamable-http';
14
14
  callbackUrl: string;
15
15
  createdAt: number;
16
- identity: string;
16
+ userId: string;
17
17
  headers?: Record<string, string>;
18
18
  /**
19
19
  * Session status marker used for TTL transitions:
@@ -36,15 +36,15 @@ export interface SetClientOptions {
36
36
  client?: MCPClient;
37
37
  serverUrl?: string;
38
38
  callbackUrl?: string;
39
- transportType?: 'sse' | 'streamable_http';
40
- identity?: string;
39
+ transportType?: 'sse' | 'streamable-http';
40
+ userId?: string;
41
41
  headers?: Record<string, string>;
42
42
  }
43
43
 
44
44
  /**
45
- * Interface for MCP Session Storage Backends
45
+ * Interface for MCP session stores.
46
46
  */
47
- export interface StorageBackend {
47
+ export interface SessionStore {
48
48
  /**
49
49
  * Optional initialization (e.g., database connection)
50
50
  */
@@ -55,49 +55,46 @@ export interface StorageBackend {
55
55
  */
56
56
  generateSessionId(): string;
57
57
 
58
- /**
59
- * Stores or updates a session
60
- */
61
58
  /**
62
59
  * Creates a new session. Throws if session already exists.
63
60
  * @param session - Session data to create
64
61
  * @param ttl - Optional TTL in seconds (defaults to backend's default)
65
62
  */
66
- createSession(session: SessionData, ttl?: number): Promise<void>;
63
+ create(session: Session, ttl?: number): Promise<void>;
67
64
 
68
65
  /**
69
66
  * Updates an existing session with partial data. Throws if session does not exist.
70
- * @param identity - User identity
67
+ * @param userId - User identifier
71
68
  * @param sessionId - Session identifier
72
69
  * @param data - Partial session data to update
73
70
  * @param ttl - Optional TTL in seconds (defaults to backend's default)
74
71
  */
75
- updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void>;
72
+ update(userId: string, sessionId: string, data: Partial<Session>, ttl?: number): Promise<void>;
76
73
 
77
74
  /**
78
75
  * Retrieves a session
79
76
  */
80
- getSession(identity: string, sessionId: string): Promise<SessionData | null>;
77
+ get(userId: string, sessionId: string): Promise<Session | null>;
81
78
 
82
79
  /**
83
- * Gets full session data for all of an identity's sessions
80
+ * Gets full session data for all sessions owned by a user
84
81
  */
85
- getIdentitySessionsData(identity: string): Promise<SessionData[]>;
82
+ list(userId: string): Promise<Session[]>;
86
83
 
87
84
  /**
88
85
  * Removes a session
89
86
  */
90
- removeSession(identity: string, sessionId: string): Promise<void>;
87
+ delete(userId: string, sessionId: string): Promise<void>;
91
88
 
92
89
  /**
93
- * Gets all sessions IDs of an identity
90
+ * Gets all session IDs owned by a user
94
91
  */
95
- getIdentityMcpSessions(identity: string): Promise<string[]>;
92
+ listIds(userId: string): Promise<string[]>;
96
93
 
97
94
  /**
98
95
  * Gets all session IDs across all users (Admin)
99
96
  */
100
- getAllSessionIds(): Promise<string[]>;
97
+ listAllIds(): Promise<string[]>;
101
98
 
102
99
  /**
103
100
  * Clears all sessions (Admin)
@@ -107,7 +104,7 @@ export interface StorageBackend {
107
104
  /**
108
105
  * Clean up expired sessions
109
106
  */
110
- cleanupExpiredSessions(): Promise<void>;
107
+ cleanupExpired(): Promise<void>;
111
108
 
112
109
  /**
113
110
  * Disconnect from storage backend
@@ -123,7 +123,7 @@ export class ToolExecutionError extends McpError {
123
123
  */
124
124
  export const RpcErrorCodes = {
125
125
  EXECUTION_ERROR: 'EXECUTION_ERROR',
126
- MISSING_IDENTITY: 'MISSING_IDENTITY',
126
+ MISSING_USER_ID: 'MISSING_USER_ID',
127
127
  UNAUTHORIZED: 'UNAUTHORIZED',
128
128
  NO_CONNECTION: 'NO_CONNECTION',
129
129
  UNKNOWN_METHOD: 'UNKNOWN_METHOD',
@@ -52,7 +52,7 @@ export type {
52
52
  SessionListResult,
53
53
  ConnectResult,
54
54
  DisconnectResult,
55
- RestoreSessionResult,
55
+ GetSessionResult,
56
56
  FinishAuthResult,
57
57
  ListToolsRpcResult,
58
58
  ListPromptsResult,
@@ -98,7 +98,6 @@ export {
98
98
  export {
99
99
  SchemaCompressor,
100
100
  type CompactTool,
101
- type CompressionStats,
102
101
  } from './schema-compressor.js';
103
102
 
104
103
  export {
@@ -337,7 +337,7 @@ export async function executeMetaTool(
337
337
 
338
338
  if (found.length > 0) {
339
339
  lines.push(...found.map((t, i) =>
340
- `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})\n ${t.description}`
340
+ `${i + 1}. **${t.name}** (serverName: ${t.serverName}, serverId: ${t.serverId})\n ${t.description}`
341
341
  ));
342
342
  }
343
343
 
@@ -380,7 +380,7 @@ export async function executeMetaTool(
380
380
  : servers
381
381
  .map(
382
382
  (server, i) =>
383
- `${i + 1}. **${server.serverName}** (serverId: ${server.serverId}, sessionId: ${server.sessionId})\n` +
383
+ `${i + 1}. **${server.serverName}** (serverId: ${server.serverId})\n` +
384
384
  ` Tool count: ${server.toolCount}`
385
385
  )
386
386
  .join('\n');
@@ -518,14 +518,12 @@ function formatToolSummaries(
518
518
  description: string;
519
519
  serverName: string;
520
520
  serverId: string;
521
- estimatedTokens: number;
522
521
  }>
523
522
  ): string[] {
524
523
  return tools.map(
525
524
  (t, i) =>
526
- `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})\n` +
527
- ` ${t.description}\n` +
528
- ` Estimated tokens: ${t.estimatedTokens}`
525
+ `${i + 1}. **${t.name}** (serverName: ${t.serverName}, serverId: ${t.serverId})\n` +
526
+ ` ${t.description}`
529
527
  );
530
528
  }
531
529
 
@@ -1,14 +1,13 @@
1
1
  /**
2
- * SchemaCompressor — Utilities for reducing tool schema token overhead.
2
+ * SchemaCompressor — Utilities for compact tool representations.
3
3
  *
4
4
  * Provides compact representations of tools (name + description only,
5
- * no inputSchema) and token savings estimation.
5
+ * no inputSchema).
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
9
 
10
10
  import type { Tool } from '@modelcontextprotocol/sdk/types.js';
11
- import { ToolIndex } from './tool-index.js';
12
11
 
13
12
  // ---------------------------------------------------------------------------
14
13
  // Types
@@ -28,17 +27,6 @@ export interface CompactTool {
28
27
  parameterHint?: string;
29
28
  }
30
29
 
31
- export interface CompressionStats {
32
- /** Estimated tokens for the *full* tool list. */
33
- fullTokens: number;
34
- /** Estimated tokens for the *compact* tool list. */
35
- compactTokens: number;
36
- /** Absolute token savings. */
37
- savedTokens: number;
38
- /** Percentage savings as a human-readable string, e.g. "82.3%". */
39
- savingsPercent: string;
40
- }
41
-
42
30
  // ---------------------------------------------------------------------------
43
31
  // SchemaCompressor
44
32
  // ---------------------------------------------------------------------------
@@ -93,32 +81,4 @@ export class SchemaCompressor {
93
81
  const limited = options?.maxTools ? tools.slice(0, options.maxTools) : tools;
94
82
  return limited.map((t) => SchemaCompressor.toCompact(t));
95
83
  }
96
-
97
- /**
98
- * Estimate token savings from using compact vs full tool schemas.
99
- */
100
- static estimateSavings(tools: Tool[]): CompressionStats {
101
- let fullTokens = 0;
102
- let compactTokens = 0;
103
-
104
- for (const tool of tools) {
105
- fullTokens += ToolIndex.estimateTokens(tool);
106
-
107
- // Compact form: name + description + parameterHint
108
- const compact = SchemaCompressor.toCompact(tool);
109
- const text = [compact.name, compact.description ?? '', compact.parameterHint ?? ''].join(' ');
110
- // Simple estimation for compact: ~4 chars per token for plain text
111
- compactTokens += Math.ceil(text.length / 4);
112
- }
113
-
114
- const saved = fullTokens - compactTokens;
115
- const pct = fullTokens > 0 ? ((saved / fullTokens) * 100).toFixed(1) : '0.0';
116
-
117
- return {
118
- fullTokens,
119
- compactTokens,
120
- savedTokens: saved,
121
- savingsPercent: `${pct}%`,
122
- };
123
- }
124
84
  }