@mcp-ts/sdk 1.3.6 → 1.3.9

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 (103) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +398 -404
  3. package/dist/adapters/agui-adapter.d.mts +1 -1
  4. package/dist/adapters/agui-adapter.d.ts +1 -1
  5. package/dist/adapters/agui-adapter.js +2 -2
  6. package/dist/adapters/agui-adapter.js.map +1 -1
  7. package/dist/adapters/agui-adapter.mjs +2 -2
  8. package/dist/adapters/agui-adapter.mjs.map +1 -1
  9. package/dist/adapters/agui-middleware.d.mts +1 -1
  10. package/dist/adapters/agui-middleware.d.ts +1 -1
  11. package/dist/adapters/agui-middleware.js.map +1 -1
  12. package/dist/adapters/agui-middleware.mjs.map +1 -1
  13. package/dist/adapters/ai-adapter.d.mts +1 -1
  14. package/dist/adapters/ai-adapter.d.ts +1 -1
  15. package/dist/adapters/ai-adapter.js +1 -1
  16. package/dist/adapters/ai-adapter.js.map +1 -1
  17. package/dist/adapters/ai-adapter.mjs +1 -1
  18. package/dist/adapters/ai-adapter.mjs.map +1 -1
  19. package/dist/adapters/langchain-adapter.d.mts +1 -1
  20. package/dist/adapters/langchain-adapter.d.ts +1 -1
  21. package/dist/adapters/langchain-adapter.js +1 -1
  22. package/dist/adapters/langchain-adapter.js.map +1 -1
  23. package/dist/adapters/langchain-adapter.mjs +1 -1
  24. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  25. package/dist/adapters/mastra-adapter.d.mts +1 -1
  26. package/dist/adapters/mastra-adapter.d.ts +1 -1
  27. package/dist/adapters/mastra-adapter.js +1 -1
  28. package/dist/adapters/mastra-adapter.js.map +1 -1
  29. package/dist/adapters/mastra-adapter.mjs +1 -1
  30. package/dist/adapters/mastra-adapter.mjs.map +1 -1
  31. package/dist/bin/mcp-ts.js +0 -0
  32. package/dist/bin/mcp-ts.js.map +1 -1
  33. package/dist/bin/mcp-ts.mjs +0 -0
  34. package/dist/bin/mcp-ts.mjs.map +1 -1
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/client/index.mjs.map +1 -1
  37. package/dist/client/react.d.mts +2 -2
  38. package/dist/client/react.d.ts +2 -2
  39. package/dist/client/react.js +25 -2
  40. package/dist/client/react.js.map +1 -1
  41. package/dist/client/react.mjs +26 -3
  42. package/dist/client/react.mjs.map +1 -1
  43. package/dist/client/vue.js.map +1 -1
  44. package/dist/client/vue.mjs.map +1 -1
  45. package/dist/index.d.mts +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +134 -71
  48. package/dist/index.js.map +1 -1
  49. package/dist/index.mjs +134 -71
  50. package/dist/index.mjs.map +1 -1
  51. package/dist/{multi-session-client-BYLarghq.d.ts → multi-session-client-CHE8QpVE.d.ts} +75 -5
  52. package/dist/{multi-session-client-CzhMkE0k.d.mts → multi-session-client-CQsRbxYI.d.mts} +75 -5
  53. package/dist/server/index.d.mts +1 -1
  54. package/dist/server/index.d.ts +1 -1
  55. package/dist/server/index.js +134 -71
  56. package/dist/server/index.js.map +1 -1
  57. package/dist/server/index.mjs +134 -71
  58. package/dist/server/index.mjs.map +1 -1
  59. package/dist/shared/index.js +10 -2
  60. package/dist/shared/index.js.map +1 -1
  61. package/dist/shared/index.mjs +10 -2
  62. package/dist/shared/index.mjs.map +1 -1
  63. package/package.json +185 -185
  64. package/src/adapters/agui-adapter.ts +222 -222
  65. package/src/adapters/agui-middleware.ts +382 -382
  66. package/src/adapters/ai-adapter.ts +115 -115
  67. package/src/adapters/langchain-adapter.ts +127 -127
  68. package/src/adapters/mastra-adapter.ts +126 -126
  69. package/src/bin/mcp-ts.ts +102 -102
  70. package/src/client/core/app-host.ts +417 -417
  71. package/src/client/core/sse-client.ts +371 -371
  72. package/src/client/core/types.ts +31 -31
  73. package/src/client/index.ts +27 -27
  74. package/src/client/react/index.ts +16 -16
  75. package/src/client/react/use-app-host.ts +73 -73
  76. package/src/client/react/use-mcp-apps.tsx +247 -214
  77. package/src/client/react/use-mcp.ts +641 -641
  78. package/src/client/vue/index.ts +10 -10
  79. package/src/client/vue/use-mcp.ts +617 -617
  80. package/src/index.ts +11 -11
  81. package/src/server/handlers/nextjs-handler.ts +204 -204
  82. package/src/server/handlers/sse-handler.ts +631 -631
  83. package/src/server/index.ts +57 -57
  84. package/src/server/mcp/multi-session-client.ts +228 -132
  85. package/src/server/mcp/oauth-client.ts +1188 -1188
  86. package/src/server/mcp/storage-oauth-provider.ts +272 -272
  87. package/src/server/storage/file-backend.ts +157 -170
  88. package/src/server/storage/index.ts +176 -175
  89. package/src/server/storage/memory-backend.ts +123 -136
  90. package/src/server/storage/redis-backend.ts +276 -289
  91. package/src/server/storage/redis.ts +160 -160
  92. package/src/server/storage/sqlite-backend.ts +182 -186
  93. package/src/server/storage/supabase-backend.ts +228 -227
  94. package/src/server/storage/types.ts +116 -116
  95. package/src/shared/constants.ts +29 -29
  96. package/src/shared/errors.ts +133 -133
  97. package/src/shared/event-routing.ts +28 -28
  98. package/src/shared/events.ts +180 -180
  99. package/src/shared/index.ts +75 -75
  100. package/src/shared/tool-utils.ts +61 -61
  101. package/src/shared/types.ts +282 -282
  102. package/src/shared/utils.ts +38 -16
  103. package/supabase/migrations/20260330195700_install_mcp_sessions.sql +84 -84
@@ -1,170 +1,157 @@
1
-
2
- import { promises as fs } from 'fs';
3
- import * as path from 'path';
4
- import { customAlphabet } from 'nanoid';
5
- import { StorageBackend, SessionData, SetClientOptions } from './types';
6
-
7
- // first char: letters only (required by OpenAI)
8
- const firstChar = customAlphabet(
9
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
10
- 1
11
- );
12
-
13
- // remaining chars: alphanumeric
14
- const rest = customAlphabet(
15
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
16
- 11
17
- );
18
-
19
- /**
20
- * File system implementation of StorageBackend
21
- * Persists sessions to a JSON file
22
- */
23
- export class FileStorageBackend implements StorageBackend {
24
- private filePath: string;
25
- private memoryCache: Map<string, SessionData> | null = null;
26
- private initialized = false;
27
-
28
- /**
29
- * @param options.path Path to the JSON file storage (default: ./sessions.json)
30
- */
31
- constructor(options: { path?: string } = {}) {
32
- this.filePath = options.path || './sessions.json';
33
- }
34
-
35
- /**
36
- * Initialize storage: ensure file exists and load into memory cache
37
- */
38
- async init(): Promise<void> {
39
- if (this.initialized) return;
40
-
41
- try {
42
- // Ensure directory exists
43
- const dir = path.dirname(this.filePath);
44
- await fs.mkdir(dir, { recursive: true });
45
-
46
- // Try to read file
47
- const data = await fs.readFile(this.filePath, 'utf-8');
48
- const json = JSON.parse(data);
49
-
50
- this.memoryCache = new Map();
51
- if (Array.isArray(json)) {
52
- json.forEach((s: SessionData) => {
53
- this.memoryCache!.set(this.getSessionKey(s.identity || 'unknown', s.sessionId), s);
54
- });
55
- }
56
- } catch (error: any) {
57
- if (error.code === 'ENOENT') {
58
- // File does not exist, initialize empty
59
- this.memoryCache = new Map();
60
- await this.flush();
61
- } else {
62
- console.error('[FileStorage] Failed to load sessions:', error);
63
- throw error;
64
- }
65
- }
66
-
67
- this.initialized = true;
68
- console.log(`[mcp-ts][Storage] File: storage directory at ${path.dirname(this.filePath)} verified.`);
69
- }
70
-
71
- private async ensureInitialized() {
72
- if (!this.initialized) await this.init();
73
- }
74
-
75
- private async flush(): Promise<void> {
76
- if (!this.memoryCache) return;
77
- const sessions = Array.from(this.memoryCache.values());
78
- await fs.writeFile(this.filePath, JSON.stringify(sessions, null, 2), 'utf-8');
79
- }
80
-
81
- private getSessionKey(identity: string, sessionId: string): string {
82
- return `${identity}:${sessionId}`;
83
- }
84
-
85
- generateSessionId(): string {
86
- return firstChar() + rest();
87
- }
88
-
89
- async createSession(session: SessionData, ttl?: number): Promise<void> {
90
- await this.ensureInitialized();
91
- const { sessionId, identity } = session;
92
- if (!sessionId || !identity) throw new Error('identity and sessionId required');
93
-
94
- const sessionKey = this.getSessionKey(identity, sessionId);
95
- if (this.memoryCache!.has(sessionKey)) {
96
- throw new Error(`Session ${sessionId} already exists`);
97
- }
98
-
99
- this.memoryCache!.set(sessionKey, session);
100
- await this.flush();
101
- // Note: TTL is ignored in file backend - sessions don't auto-expire
102
- }
103
-
104
- async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {
105
- await this.ensureInitialized();
106
- if (!identity || !sessionId) throw new Error('identity and sessionId required');
107
-
108
- const sessionKey = this.getSessionKey(identity, sessionId);
109
- const current = this.memoryCache!.get(sessionKey);
110
-
111
- if (!current) {
112
- throw new Error(`Session ${sessionId} not found`);
113
- }
114
-
115
- const updated = {
116
- ...current,
117
- ...data
118
- };
119
-
120
- this.memoryCache!.set(sessionKey, updated);
121
- await this.flush();
122
- // Note: TTL is ignored in file backend - sessions don't auto-expire
123
- }
124
-
125
- async getSession(identity: string, sessionId: string): Promise<SessionData | null> {
126
- await this.ensureInitialized();
127
- const sessionKey = this.getSessionKey(identity, sessionId);
128
- return this.memoryCache!.get(sessionKey) || null;
129
- }
130
-
131
- async getIdentitySessionsData(identity: string): Promise<SessionData[]> {
132
- await this.ensureInitialized();
133
- return Array.from(this.memoryCache!.values()).filter(s => s.identity === identity);
134
- }
135
-
136
- async getIdentityMcpSessions(identity: string): Promise<string[]> {
137
- await this.ensureInitialized();
138
- return Array.from(this.memoryCache!.values())
139
- .filter(s => s.identity === identity)
140
- .map(s => s.sessionId);
141
- }
142
-
143
- async removeSession(identity: string, sessionId: string): Promise<void> {
144
- await this.ensureInitialized();
145
- const sessionKey = this.getSessionKey(identity, sessionId);
146
- if (this.memoryCache!.delete(sessionKey)) {
147
- await this.flush();
148
- }
149
- }
150
-
151
- async getAllSessionIds(): Promise<string[]> {
152
- await this.ensureInitialized();
153
- return Array.from(this.memoryCache!.values()).map(s => s.sessionId);
154
- }
155
-
156
- async clearAll(): Promise<void> {
157
- await this.ensureInitialized();
158
- this.memoryCache!.clear();
159
- await this.flush();
160
- }
161
-
162
- async cleanupExpiredSessions(): Promise<void> {
163
- // Could implement TTL check here using createdAt
164
- await this.ensureInitialized();
165
- }
166
-
167
- async disconnect(): Promise<void> {
168
- // No explicit disconnect needed for file
169
- }
170
- }
1
+ import { promises as fs } from 'fs';
2
+ import * as path from 'path';
3
+ import { StorageBackend, SessionData, SetClientOptions } from './types.js';
4
+ import { generateSessionId } from '../../shared/utils.js';
5
+
6
+ /**
7
+ * File system implementation of StorageBackend
8
+ * Persists sessions to a JSON file
9
+ */
10
+ export class FileStorageBackend implements StorageBackend {
11
+ private filePath: string;
12
+ private memoryCache: Map<string, SessionData> | null = null;
13
+ private initialized = false;
14
+
15
+ /**
16
+ * @param options.path Path to the JSON file storage (default: ./sessions.json)
17
+ */
18
+ constructor(options: { path?: string } = {}) {
19
+ this.filePath = options.path || './sessions.json';
20
+ }
21
+
22
+ /**
23
+ * Initialize storage: ensure file exists and load into memory cache
24
+ */
25
+ async init(): Promise<void> {
26
+ if (this.initialized) return;
27
+
28
+ try {
29
+ // Ensure directory exists
30
+ const dir = path.dirname(this.filePath);
31
+ await fs.mkdir(dir, { recursive: true });
32
+
33
+ // Try to read file
34
+ const data = await fs.readFile(this.filePath, 'utf-8');
35
+ const json = JSON.parse(data);
36
+
37
+ this.memoryCache = new Map();
38
+ if (Array.isArray(json)) {
39
+ json.forEach((s: SessionData) => {
40
+ this.memoryCache!.set(this.getSessionKey(s.identity || 'unknown', s.sessionId), s);
41
+ });
42
+ }
43
+ } catch (error: any) {
44
+ if (error.code === 'ENOENT') {
45
+ // File does not exist, initialize empty
46
+ this.memoryCache = new Map();
47
+ await this.flush();
48
+ } else {
49
+ console.error('[FileStorage] Failed to load sessions:', error);
50
+ throw error;
51
+ }
52
+ }
53
+
54
+ this.initialized = true;
55
+ console.log(`[mcp-ts][Storage] File: ✓ storage directory at ${path.dirname(this.filePath)} verified.`);
56
+ }
57
+
58
+ private async ensureInitialized() {
59
+ if (!this.initialized) await this.init();
60
+ }
61
+
62
+ private async flush(): Promise<void> {
63
+ if (!this.memoryCache) return;
64
+ const sessions = Array.from(this.memoryCache.values());
65
+ await fs.writeFile(this.filePath, JSON.stringify(sessions, null, 2), 'utf-8');
66
+ }
67
+
68
+ private getSessionKey(identity: string, sessionId: string): string {
69
+ return `${identity}:${sessionId}`;
70
+ }
71
+
72
+ generateSessionId(): string {
73
+ return generateSessionId();
74
+ }
75
+
76
+ async createSession(session: SessionData, ttl?: number): Promise<void> {
77
+ await this.ensureInitialized();
78
+ const { sessionId, identity } = session;
79
+ if (!sessionId || !identity) throw new Error('identity and sessionId required');
80
+
81
+ const sessionKey = this.getSessionKey(identity, sessionId);
82
+ if (this.memoryCache!.has(sessionKey)) {
83
+ throw new Error(`Session ${sessionId} already exists`);
84
+ }
85
+
86
+ this.memoryCache!.set(sessionKey, session);
87
+ await this.flush();
88
+ // Note: TTL is ignored in file backend - sessions don't auto-expire
89
+ }
90
+
91
+ async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {
92
+ await this.ensureInitialized();
93
+ if (!identity || !sessionId) throw new Error('identity and sessionId required');
94
+
95
+ const sessionKey = this.getSessionKey(identity, sessionId);
96
+ const current = this.memoryCache!.get(sessionKey);
97
+
98
+ if (!current) {
99
+ throw new Error(`Session ${sessionId} not found`);
100
+ }
101
+
102
+ const updated = {
103
+ ...current,
104
+ ...data
105
+ };
106
+
107
+ this.memoryCache!.set(sessionKey, updated);
108
+ await this.flush();
109
+ // Note: TTL is ignored in file backend - sessions don't auto-expire
110
+ }
111
+
112
+ async getSession(identity: string, sessionId: string): Promise<SessionData | null> {
113
+ await this.ensureInitialized();
114
+ const sessionKey = this.getSessionKey(identity, sessionId);
115
+ return this.memoryCache!.get(sessionKey) || null;
116
+ }
117
+
118
+ async getIdentitySessionsData(identity: string): Promise<SessionData[]> {
119
+ await this.ensureInitialized();
120
+ return Array.from(this.memoryCache!.values()).filter(s => s.identity === identity);
121
+ }
122
+
123
+ async getIdentityMcpSessions(identity: string): Promise<string[]> {
124
+ await this.ensureInitialized();
125
+ return Array.from(this.memoryCache!.values())
126
+ .filter(s => s.identity === identity)
127
+ .map(s => s.sessionId);
128
+ }
129
+
130
+ async removeSession(identity: string, sessionId: string): Promise<void> {
131
+ await this.ensureInitialized();
132
+ const sessionKey = this.getSessionKey(identity, sessionId);
133
+ if (this.memoryCache!.delete(sessionKey)) {
134
+ await this.flush();
135
+ }
136
+ }
137
+
138
+ async getAllSessionIds(): Promise<string[]> {
139
+ await this.ensureInitialized();
140
+ return Array.from(this.memoryCache!.values()).map(s => s.sessionId);
141
+ }
142
+
143
+ async clearAll(): Promise<void> {
144
+ await this.ensureInitialized();
145
+ this.memoryCache!.clear();
146
+ await this.flush();
147
+ }
148
+
149
+ async cleanupExpiredSessions(): Promise<void> {
150
+ // Could implement TTL check here using createdAt
151
+ await this.ensureInitialized();
152
+ }
153
+
154
+ async disconnect(): Promise<void> {
155
+ // No explicit disconnect needed for file
156
+ }
157
+ }