@mcp-ts/sdk 1.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.
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/dist/adapters/agui-adapter.d.mts +119 -0
- package/dist/adapters/agui-adapter.d.ts +119 -0
- package/dist/adapters/agui-adapter.js +109 -0
- package/dist/adapters/agui-adapter.js.map +1 -0
- package/dist/adapters/agui-adapter.mjs +107 -0
- package/dist/adapters/agui-adapter.mjs.map +1 -0
- package/dist/adapters/agui-middleware.d.mts +171 -0
- package/dist/adapters/agui-middleware.d.ts +171 -0
- package/dist/adapters/agui-middleware.js +429 -0
- package/dist/adapters/agui-middleware.js.map +1 -0
- package/dist/adapters/agui-middleware.mjs +417 -0
- package/dist/adapters/agui-middleware.mjs.map +1 -0
- package/dist/adapters/ai-adapter.d.mts +38 -0
- package/dist/adapters/ai-adapter.d.ts +38 -0
- package/dist/adapters/ai-adapter.js +82 -0
- package/dist/adapters/ai-adapter.js.map +1 -0
- package/dist/adapters/ai-adapter.mjs +80 -0
- package/dist/adapters/ai-adapter.mjs.map +1 -0
- package/dist/adapters/langchain-adapter.d.mts +46 -0
- package/dist/adapters/langchain-adapter.d.ts +46 -0
- package/dist/adapters/langchain-adapter.js +102 -0
- package/dist/adapters/langchain-adapter.js.map +1 -0
- package/dist/adapters/langchain-adapter.mjs +100 -0
- package/dist/adapters/langchain-adapter.mjs.map +1 -0
- package/dist/adapters/mastra-adapter.d.mts +49 -0
- package/dist/adapters/mastra-adapter.d.ts +49 -0
- package/dist/adapters/mastra-adapter.js +95 -0
- package/dist/adapters/mastra-adapter.js.map +1 -0
- package/dist/adapters/mastra-adapter.mjs +93 -0
- package/dist/adapters/mastra-adapter.mjs.map +1 -0
- package/dist/client/index.d.mts +119 -0
- package/dist/client/index.d.ts +119 -0
- package/dist/client/index.js +225 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +223 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/client/react.d.mts +151 -0
- package/dist/client/react.d.ts +151 -0
- package/dist/client/react.js +492 -0
- package/dist/client/react.js.map +1 -0
- package/dist/client/react.mjs +489 -0
- package/dist/client/react.mjs.map +1 -0
- package/dist/client/vue.d.mts +157 -0
- package/dist/client/vue.d.ts +157 -0
- package/dist/client/vue.js +474 -0
- package/dist/client/vue.js.map +1 -0
- package/dist/client/vue.mjs +471 -0
- package/dist/client/vue.mjs.map +1 -0
- package/dist/events-BP6WyRNh.d.mts +110 -0
- package/dist/events-BP6WyRNh.d.ts +110 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +2784 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2723 -0
- package/dist/index.mjs.map +1 -0
- package/dist/multi-session-client-BOFgPypS.d.ts +389 -0
- package/dist/multi-session-client-DMF3ED2O.d.mts +389 -0
- package/dist/server/index.d.mts +269 -0
- package/dist/server/index.d.ts +269 -0
- package/dist/server/index.js +2444 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +2414 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/shared/index.d.mts +24 -0
- package/dist/shared/index.d.ts +24 -0
- package/dist/shared/index.js +223 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/index.mjs +190 -0
- package/dist/shared/index.mjs.map +1 -0
- package/dist/types-SbDlA2VX.d.mts +153 -0
- package/dist/types-SbDlA2VX.d.ts +153 -0
- package/dist/utils-0qmYrqoa.d.mts +92 -0
- package/dist/utils-0qmYrqoa.d.ts +92 -0
- package/package.json +165 -0
- package/src/adapters/agui-adapter.ts +210 -0
- package/src/adapters/agui-middleware.ts +512 -0
- package/src/adapters/ai-adapter.ts +115 -0
- package/src/adapters/langchain-adapter.ts +127 -0
- package/src/adapters/mastra-adapter.ts +126 -0
- package/src/client/core/sse-client.ts +340 -0
- package/src/client/index.ts +26 -0
- package/src/client/react/index.ts +10 -0
- package/src/client/react/useMcp.ts +558 -0
- package/src/client/vue/index.ts +10 -0
- package/src/client/vue/useMcp.ts +542 -0
- package/src/index.ts +11 -0
- package/src/server/handlers/nextjs-handler.ts +216 -0
- package/src/server/handlers/sse-handler.ts +699 -0
- package/src/server/index.ts +57 -0
- package/src/server/mcp/multi-session-client.ts +132 -0
- package/src/server/mcp/oauth-client.ts +1168 -0
- package/src/server/mcp/storage-oauth-provider.ts +239 -0
- package/src/server/storage/file-backend.ts +169 -0
- package/src/server/storage/index.ts +115 -0
- package/src/server/storage/memory-backend.ts +132 -0
- package/src/server/storage/redis-backend.ts +210 -0
- package/src/server/storage/redis.ts +160 -0
- package/src/server/storage/types.ts +109 -0
- package/src/shared/constants.ts +29 -0
- package/src/shared/errors.ts +133 -0
- package/src/shared/events.ts +166 -0
- package/src/shared/index.ts +70 -0
- package/src/shared/types.ts +274 -0
- package/src/shared/utils.ts +16 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
|
+
|
|
7
|
+
// src/shared/events.ts
|
|
8
|
+
var Emitter = class {
|
|
9
|
+
constructor() {
|
|
10
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Subscribe to events
|
|
14
|
+
* @param listener - Callback function to handle events
|
|
15
|
+
* @returns Disposable to unsubscribe
|
|
16
|
+
*/
|
|
17
|
+
get event() {
|
|
18
|
+
return (listener) => {
|
|
19
|
+
this.listeners.add(listener);
|
|
20
|
+
return {
|
|
21
|
+
dispose: () => {
|
|
22
|
+
this.listeners.delete(listener);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fire an event to all listeners
|
|
29
|
+
* @param event - Event data to emit
|
|
30
|
+
*/
|
|
31
|
+
fire(event) {
|
|
32
|
+
for (const listener of this.listeners) {
|
|
33
|
+
try {
|
|
34
|
+
listener(event);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error("[Emitter] Error in event listener:", error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Clear all listeners
|
|
42
|
+
*/
|
|
43
|
+
dispose() {
|
|
44
|
+
this.listeners.clear();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get number of active listeners
|
|
48
|
+
*/
|
|
49
|
+
get listenerCount() {
|
|
50
|
+
return this.listeners.size;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var DisposableStore = class {
|
|
54
|
+
constructor() {
|
|
55
|
+
__publicField(this, "disposables", /* @__PURE__ */ new Set());
|
|
56
|
+
}
|
|
57
|
+
add(disposable) {
|
|
58
|
+
this.disposables.add(disposable);
|
|
59
|
+
}
|
|
60
|
+
dispose() {
|
|
61
|
+
for (const disposable of this.disposables) {
|
|
62
|
+
disposable.dispose();
|
|
63
|
+
}
|
|
64
|
+
this.disposables.clear();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/shared/constants.ts
|
|
69
|
+
var SESSION_TTL_SECONDS = 43200;
|
|
70
|
+
var STATE_EXPIRATION_MS = 10 * 60 * 1e3;
|
|
71
|
+
var DEFAULT_HEARTBEAT_INTERVAL_MS = 3e4;
|
|
72
|
+
var REDIS_KEY_PREFIX = "mcp:session:";
|
|
73
|
+
var TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1e3;
|
|
74
|
+
var DEFAULT_CLIENT_NAME = "MCP Assistant";
|
|
75
|
+
var DEFAULT_CLIENT_URI = "https://mcp-assistant.in";
|
|
76
|
+
var DEFAULT_LOGO_URI = "https://mcp-assistant.in/logo.png";
|
|
77
|
+
var DEFAULT_POLICY_URI = "https://mcp-assistant.in/privacy";
|
|
78
|
+
var SOFTWARE_ID = "@mcp-ts";
|
|
79
|
+
var SOFTWARE_VERSION = "1.0.0-beta.5";
|
|
80
|
+
var MCP_CLIENT_NAME = "mcp-ts-oauth-client";
|
|
81
|
+
var MCP_CLIENT_VERSION = "2.0";
|
|
82
|
+
|
|
83
|
+
// src/shared/errors.ts
|
|
84
|
+
var McpError = class extends Error {
|
|
85
|
+
constructor(code, message, cause) {
|
|
86
|
+
super(message);
|
|
87
|
+
this.code = code;
|
|
88
|
+
this.cause = cause;
|
|
89
|
+
this.name = "McpError";
|
|
90
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
91
|
+
}
|
|
92
|
+
toJSON() {
|
|
93
|
+
return {
|
|
94
|
+
name: this.name,
|
|
95
|
+
code: this.code,
|
|
96
|
+
message: this.message,
|
|
97
|
+
...this.cause ? { cause: this.cause.message } : {}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var UnauthorizedError = class extends McpError {
|
|
102
|
+
constructor(message = "OAuth authorization required", cause) {
|
|
103
|
+
super("UNAUTHORIZED", message, cause);
|
|
104
|
+
this.name = "UnauthorizedError";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var ConnectionError = class extends McpError {
|
|
108
|
+
constructor(message, cause) {
|
|
109
|
+
super("CONNECTION_ERROR", message, cause);
|
|
110
|
+
this.name = "ConnectionError";
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
var SessionNotFoundError = class extends McpError {
|
|
114
|
+
constructor(sessionId, cause) {
|
|
115
|
+
super("SESSION_NOT_FOUND", `Session not found: ${sessionId}`, cause);
|
|
116
|
+
this.name = "SessionNotFoundError";
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
var SessionValidationError = class extends McpError {
|
|
120
|
+
constructor(message, cause) {
|
|
121
|
+
super("SESSION_VALIDATION_ERROR", message, cause);
|
|
122
|
+
this.name = "SessionValidationError";
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
var AuthenticationError = class extends McpError {
|
|
126
|
+
constructor(message, cause) {
|
|
127
|
+
super("AUTH_ERROR", message, cause);
|
|
128
|
+
this.name = "AuthenticationError";
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var InvalidStateError = class extends McpError {
|
|
132
|
+
constructor(message = "Invalid OAuth state", cause) {
|
|
133
|
+
super("INVALID_STATE", message, cause);
|
|
134
|
+
this.name = "InvalidStateError";
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var NotConnectedError = class extends McpError {
|
|
138
|
+
constructor(message = "Not connected to server", cause) {
|
|
139
|
+
super("NOT_CONNECTED", message, cause);
|
|
140
|
+
this.name = "NotConnectedError";
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var ConfigurationError = class extends McpError {
|
|
144
|
+
constructor(message, cause) {
|
|
145
|
+
super("CONFIGURATION_ERROR", message, cause);
|
|
146
|
+
this.name = "ConfigurationError";
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
var ToolExecutionError = class extends McpError {
|
|
150
|
+
constructor(toolName, message, cause) {
|
|
151
|
+
super("TOOL_EXECUTION_ERROR", `Tool '${toolName}' failed: ${message}`, cause);
|
|
152
|
+
this.name = "ToolExecutionError";
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
var RpcErrorCodes = {
|
|
156
|
+
EXECUTION_ERROR: "EXECUTION_ERROR",
|
|
157
|
+
MISSING_IDENTITY: "MISSING_IDENTITY",
|
|
158
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
159
|
+
NO_CONNECTION: "NO_CONNECTION",
|
|
160
|
+
UNKNOWN_METHOD: "UNKNOWN_METHOD",
|
|
161
|
+
INVALID_PARAMS: "INVALID_PARAMS"
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// src/shared/types.ts
|
|
165
|
+
function isConnectSuccess(response) {
|
|
166
|
+
return "success" in response && response.success === true;
|
|
167
|
+
}
|
|
168
|
+
function isConnectAuthRequired(response) {
|
|
169
|
+
return "requiresAuth" in response && response.requiresAuth === true;
|
|
170
|
+
}
|
|
171
|
+
function isConnectError(response) {
|
|
172
|
+
return "error" in response;
|
|
173
|
+
}
|
|
174
|
+
function isListToolsSuccess(response) {
|
|
175
|
+
return "tools" in response;
|
|
176
|
+
}
|
|
177
|
+
function isCallToolSuccess(response) {
|
|
178
|
+
return "content" in response;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/shared/utils.ts
|
|
182
|
+
function sanitizeServerLabel(name) {
|
|
183
|
+
let sanitized = name.replace(/[^a-zA-Z0-9-_]/g, "_").replace(/_{2,}/g, "_").toLowerCase();
|
|
184
|
+
if (!/^[a-zA-Z]/.test(sanitized)) {
|
|
185
|
+
sanitized = "s_" + sanitized;
|
|
186
|
+
}
|
|
187
|
+
return sanitized;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
exports.AuthenticationError = AuthenticationError;
|
|
191
|
+
exports.ConfigurationError = ConfigurationError;
|
|
192
|
+
exports.ConnectionError = ConnectionError;
|
|
193
|
+
exports.DEFAULT_CLIENT_NAME = DEFAULT_CLIENT_NAME;
|
|
194
|
+
exports.DEFAULT_CLIENT_URI = DEFAULT_CLIENT_URI;
|
|
195
|
+
exports.DEFAULT_HEARTBEAT_INTERVAL_MS = DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
196
|
+
exports.DEFAULT_LOGO_URI = DEFAULT_LOGO_URI;
|
|
197
|
+
exports.DEFAULT_POLICY_URI = DEFAULT_POLICY_URI;
|
|
198
|
+
exports.DisposableStore = DisposableStore;
|
|
199
|
+
exports.Emitter = Emitter;
|
|
200
|
+
exports.InvalidStateError = InvalidStateError;
|
|
201
|
+
exports.MCP_CLIENT_NAME = MCP_CLIENT_NAME;
|
|
202
|
+
exports.MCP_CLIENT_VERSION = MCP_CLIENT_VERSION;
|
|
203
|
+
exports.McpError = McpError;
|
|
204
|
+
exports.NotConnectedError = NotConnectedError;
|
|
205
|
+
exports.REDIS_KEY_PREFIX = REDIS_KEY_PREFIX;
|
|
206
|
+
exports.RpcErrorCodes = RpcErrorCodes;
|
|
207
|
+
exports.SESSION_TTL_SECONDS = SESSION_TTL_SECONDS;
|
|
208
|
+
exports.SOFTWARE_ID = SOFTWARE_ID;
|
|
209
|
+
exports.SOFTWARE_VERSION = SOFTWARE_VERSION;
|
|
210
|
+
exports.STATE_EXPIRATION_MS = STATE_EXPIRATION_MS;
|
|
211
|
+
exports.SessionNotFoundError = SessionNotFoundError;
|
|
212
|
+
exports.SessionValidationError = SessionValidationError;
|
|
213
|
+
exports.TOKEN_EXPIRY_BUFFER_MS = TOKEN_EXPIRY_BUFFER_MS;
|
|
214
|
+
exports.ToolExecutionError = ToolExecutionError;
|
|
215
|
+
exports.UnauthorizedError = UnauthorizedError;
|
|
216
|
+
exports.isCallToolSuccess = isCallToolSuccess;
|
|
217
|
+
exports.isConnectAuthRequired = isConnectAuthRequired;
|
|
218
|
+
exports.isConnectError = isConnectError;
|
|
219
|
+
exports.isConnectSuccess = isConnectSuccess;
|
|
220
|
+
exports.isListToolsSuccess = isListToolsSuccess;
|
|
221
|
+
exports.sanitizeServerLabel = sanitizeServerLabel;
|
|
222
|
+
//# sourceMappingURL=index.js.map
|
|
223
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shared/events.ts","../../src/shared/constants.ts","../../src/shared/errors.ts","../../src/shared/types.ts","../../src/shared/utils.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId: string;\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\n"]}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
// src/shared/events.ts
|
|
6
|
+
var Emitter = class {
|
|
7
|
+
constructor() {
|
|
8
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Subscribe to events
|
|
12
|
+
* @param listener - Callback function to handle events
|
|
13
|
+
* @returns Disposable to unsubscribe
|
|
14
|
+
*/
|
|
15
|
+
get event() {
|
|
16
|
+
return (listener) => {
|
|
17
|
+
this.listeners.add(listener);
|
|
18
|
+
return {
|
|
19
|
+
dispose: () => {
|
|
20
|
+
this.listeners.delete(listener);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Fire an event to all listeners
|
|
27
|
+
* @param event - Event data to emit
|
|
28
|
+
*/
|
|
29
|
+
fire(event) {
|
|
30
|
+
for (const listener of this.listeners) {
|
|
31
|
+
try {
|
|
32
|
+
listener(event);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("[Emitter] Error in event listener:", error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Clear all listeners
|
|
40
|
+
*/
|
|
41
|
+
dispose() {
|
|
42
|
+
this.listeners.clear();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get number of active listeners
|
|
46
|
+
*/
|
|
47
|
+
get listenerCount() {
|
|
48
|
+
return this.listeners.size;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var DisposableStore = class {
|
|
52
|
+
constructor() {
|
|
53
|
+
__publicField(this, "disposables", /* @__PURE__ */ new Set());
|
|
54
|
+
}
|
|
55
|
+
add(disposable) {
|
|
56
|
+
this.disposables.add(disposable);
|
|
57
|
+
}
|
|
58
|
+
dispose() {
|
|
59
|
+
for (const disposable of this.disposables) {
|
|
60
|
+
disposable.dispose();
|
|
61
|
+
}
|
|
62
|
+
this.disposables.clear();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/shared/constants.ts
|
|
67
|
+
var SESSION_TTL_SECONDS = 43200;
|
|
68
|
+
var STATE_EXPIRATION_MS = 10 * 60 * 1e3;
|
|
69
|
+
var DEFAULT_HEARTBEAT_INTERVAL_MS = 3e4;
|
|
70
|
+
var REDIS_KEY_PREFIX = "mcp:session:";
|
|
71
|
+
var TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1e3;
|
|
72
|
+
var DEFAULT_CLIENT_NAME = "MCP Assistant";
|
|
73
|
+
var DEFAULT_CLIENT_URI = "https://mcp-assistant.in";
|
|
74
|
+
var DEFAULT_LOGO_URI = "https://mcp-assistant.in/logo.png";
|
|
75
|
+
var DEFAULT_POLICY_URI = "https://mcp-assistant.in/privacy";
|
|
76
|
+
var SOFTWARE_ID = "@mcp-ts";
|
|
77
|
+
var SOFTWARE_VERSION = "1.0.0-beta.5";
|
|
78
|
+
var MCP_CLIENT_NAME = "mcp-ts-oauth-client";
|
|
79
|
+
var MCP_CLIENT_VERSION = "2.0";
|
|
80
|
+
|
|
81
|
+
// src/shared/errors.ts
|
|
82
|
+
var McpError = class extends Error {
|
|
83
|
+
constructor(code, message, cause) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.code = code;
|
|
86
|
+
this.cause = cause;
|
|
87
|
+
this.name = "McpError";
|
|
88
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
89
|
+
}
|
|
90
|
+
toJSON() {
|
|
91
|
+
return {
|
|
92
|
+
name: this.name,
|
|
93
|
+
code: this.code,
|
|
94
|
+
message: this.message,
|
|
95
|
+
...this.cause ? { cause: this.cause.message } : {}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var UnauthorizedError = class extends McpError {
|
|
100
|
+
constructor(message = "OAuth authorization required", cause) {
|
|
101
|
+
super("UNAUTHORIZED", message, cause);
|
|
102
|
+
this.name = "UnauthorizedError";
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var ConnectionError = class extends McpError {
|
|
106
|
+
constructor(message, cause) {
|
|
107
|
+
super("CONNECTION_ERROR", message, cause);
|
|
108
|
+
this.name = "ConnectionError";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var SessionNotFoundError = class extends McpError {
|
|
112
|
+
constructor(sessionId, cause) {
|
|
113
|
+
super("SESSION_NOT_FOUND", `Session not found: ${sessionId}`, cause);
|
|
114
|
+
this.name = "SessionNotFoundError";
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
var SessionValidationError = class extends McpError {
|
|
118
|
+
constructor(message, cause) {
|
|
119
|
+
super("SESSION_VALIDATION_ERROR", message, cause);
|
|
120
|
+
this.name = "SessionValidationError";
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var AuthenticationError = class extends McpError {
|
|
124
|
+
constructor(message, cause) {
|
|
125
|
+
super("AUTH_ERROR", message, cause);
|
|
126
|
+
this.name = "AuthenticationError";
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var InvalidStateError = class extends McpError {
|
|
130
|
+
constructor(message = "Invalid OAuth state", cause) {
|
|
131
|
+
super("INVALID_STATE", message, cause);
|
|
132
|
+
this.name = "InvalidStateError";
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
var NotConnectedError = class extends McpError {
|
|
136
|
+
constructor(message = "Not connected to server", cause) {
|
|
137
|
+
super("NOT_CONNECTED", message, cause);
|
|
138
|
+
this.name = "NotConnectedError";
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
var ConfigurationError = class extends McpError {
|
|
142
|
+
constructor(message, cause) {
|
|
143
|
+
super("CONFIGURATION_ERROR", message, cause);
|
|
144
|
+
this.name = "ConfigurationError";
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
var ToolExecutionError = class extends McpError {
|
|
148
|
+
constructor(toolName, message, cause) {
|
|
149
|
+
super("TOOL_EXECUTION_ERROR", `Tool '${toolName}' failed: ${message}`, cause);
|
|
150
|
+
this.name = "ToolExecutionError";
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var RpcErrorCodes = {
|
|
154
|
+
EXECUTION_ERROR: "EXECUTION_ERROR",
|
|
155
|
+
MISSING_IDENTITY: "MISSING_IDENTITY",
|
|
156
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
157
|
+
NO_CONNECTION: "NO_CONNECTION",
|
|
158
|
+
UNKNOWN_METHOD: "UNKNOWN_METHOD",
|
|
159
|
+
INVALID_PARAMS: "INVALID_PARAMS"
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// src/shared/types.ts
|
|
163
|
+
function isConnectSuccess(response) {
|
|
164
|
+
return "success" in response && response.success === true;
|
|
165
|
+
}
|
|
166
|
+
function isConnectAuthRequired(response) {
|
|
167
|
+
return "requiresAuth" in response && response.requiresAuth === true;
|
|
168
|
+
}
|
|
169
|
+
function isConnectError(response) {
|
|
170
|
+
return "error" in response;
|
|
171
|
+
}
|
|
172
|
+
function isListToolsSuccess(response) {
|
|
173
|
+
return "tools" in response;
|
|
174
|
+
}
|
|
175
|
+
function isCallToolSuccess(response) {
|
|
176
|
+
return "content" in response;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/shared/utils.ts
|
|
180
|
+
function sanitizeServerLabel(name) {
|
|
181
|
+
let sanitized = name.replace(/[^a-zA-Z0-9-_]/g, "_").replace(/_{2,}/g, "_").toLowerCase();
|
|
182
|
+
if (!/^[a-zA-Z]/.test(sanitized)) {
|
|
183
|
+
sanitized = "s_" + sanitized;
|
|
184
|
+
}
|
|
185
|
+
return sanitized;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export { AuthenticationError, ConfigurationError, ConnectionError, DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, DisposableStore, Emitter, InvalidStateError, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, McpError, NotConnectedError, REDIS_KEY_PREFIX, RpcErrorCodes, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, SessionNotFoundError, SessionValidationError, TOKEN_EXPIRY_BUFFER_MS, ToolExecutionError, UnauthorizedError, isCallToolSuccess, isConnectAuthRequired, isConnectError, isConnectSuccess, isListToolsSuccess, sanitizeServerLabel };
|
|
189
|
+
//# sourceMappingURL=index.mjs.map
|
|
190
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shared/events.ts","../../src/shared/constants.ts","../../src/shared/errors.ts","../../src/shared/types.ts","../../src/shared/utils.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId: string;\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\n"]}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Type definitions for MCP operations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface ConnectRequest {
|
|
8
|
+
serverUrl: string;
|
|
9
|
+
callbackUrl: string;
|
|
10
|
+
}
|
|
11
|
+
interface ConnectSuccessResponse {
|
|
12
|
+
success: true;
|
|
13
|
+
sessionId: string;
|
|
14
|
+
}
|
|
15
|
+
interface ConnectAuthRequiredResponse {
|
|
16
|
+
requiresAuth: true;
|
|
17
|
+
authUrl: string;
|
|
18
|
+
sessionId: string;
|
|
19
|
+
}
|
|
20
|
+
interface ConnectErrorResponse {
|
|
21
|
+
error: string;
|
|
22
|
+
}
|
|
23
|
+
type ConnectResponse = ConnectSuccessResponse | ConnectAuthRequiredResponse | ConnectErrorResponse;
|
|
24
|
+
interface ListToolsSuccessResponse {
|
|
25
|
+
tools: Tool[];
|
|
26
|
+
}
|
|
27
|
+
interface ListToolsErrorResponse {
|
|
28
|
+
error: string;
|
|
29
|
+
}
|
|
30
|
+
type ListToolsResponse = ListToolsSuccessResponse | ListToolsErrorResponse;
|
|
31
|
+
interface CallToolRequest {
|
|
32
|
+
sessionId: string;
|
|
33
|
+
toolName: string;
|
|
34
|
+
toolArgs: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
interface CallToolSuccessResponse {
|
|
37
|
+
content: Array<{
|
|
38
|
+
type: string;
|
|
39
|
+
text?: string;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}>;
|
|
42
|
+
isError: boolean;
|
|
43
|
+
}
|
|
44
|
+
interface CallToolErrorResponse {
|
|
45
|
+
error: string;
|
|
46
|
+
}
|
|
47
|
+
type CallToolResponse = CallToolSuccessResponse | CallToolErrorResponse;
|
|
48
|
+
declare function isConnectSuccess(response: ConnectResponse): response is ConnectSuccessResponse;
|
|
49
|
+
declare function isConnectAuthRequired(response: ConnectResponse): response is ConnectAuthRequiredResponse;
|
|
50
|
+
declare function isConnectError(response: ConnectResponse): response is ConnectErrorResponse;
|
|
51
|
+
declare function isListToolsSuccess(response: ListToolsResponse): response is ListToolsSuccessResponse;
|
|
52
|
+
declare function isCallToolSuccess(response: CallToolResponse): response is CallToolSuccessResponse;
|
|
53
|
+
type ToolInfo = {
|
|
54
|
+
name: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
inputSchema?: unknown;
|
|
57
|
+
};
|
|
58
|
+
type TransportType = 'sse' | 'streamable_http';
|
|
59
|
+
type McpRpcMethod = 'connect' | 'disconnect' | 'listTools' | 'callTool' | 'getSessions' | 'restoreSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource';
|
|
60
|
+
interface McpRpcRequest {
|
|
61
|
+
id: string;
|
|
62
|
+
method: McpRpcMethod;
|
|
63
|
+
params?: McpRpcParams;
|
|
64
|
+
}
|
|
65
|
+
interface McpRpcResponse<T = unknown> {
|
|
66
|
+
id: string;
|
|
67
|
+
result?: T;
|
|
68
|
+
error?: {
|
|
69
|
+
code: string;
|
|
70
|
+
message: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
interface ConnectParams {
|
|
74
|
+
serverId: string;
|
|
75
|
+
serverName: string;
|
|
76
|
+
serverUrl: string;
|
|
77
|
+
callbackUrl: string;
|
|
78
|
+
transportType?: TransportType;
|
|
79
|
+
}
|
|
80
|
+
interface DisconnectParams {
|
|
81
|
+
sessionId: string;
|
|
82
|
+
}
|
|
83
|
+
interface SessionParams {
|
|
84
|
+
sessionId: string;
|
|
85
|
+
}
|
|
86
|
+
interface CallToolParams {
|
|
87
|
+
sessionId: string;
|
|
88
|
+
toolName: string;
|
|
89
|
+
toolArgs: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
interface GetPromptParams {
|
|
92
|
+
sessionId: string;
|
|
93
|
+
name: string;
|
|
94
|
+
args?: Record<string, string>;
|
|
95
|
+
}
|
|
96
|
+
interface ReadResourceParams {
|
|
97
|
+
sessionId: string;
|
|
98
|
+
uri: string;
|
|
99
|
+
}
|
|
100
|
+
interface FinishAuthParams {
|
|
101
|
+
sessionId: string;
|
|
102
|
+
code: string;
|
|
103
|
+
}
|
|
104
|
+
type McpRpcParams = ConnectParams | DisconnectParams | SessionParams | CallToolParams | GetPromptParams | ReadResourceParams | FinishAuthParams | undefined;
|
|
105
|
+
interface SessionInfo {
|
|
106
|
+
sessionId: string;
|
|
107
|
+
serverId?: string;
|
|
108
|
+
serverName?: string;
|
|
109
|
+
serverUrl: string;
|
|
110
|
+
transport: TransportType;
|
|
111
|
+
}
|
|
112
|
+
interface SessionListResult {
|
|
113
|
+
sessions: SessionInfo[];
|
|
114
|
+
}
|
|
115
|
+
interface ConnectResult {
|
|
116
|
+
sessionId: string;
|
|
117
|
+
success: boolean;
|
|
118
|
+
}
|
|
119
|
+
interface DisconnectResult {
|
|
120
|
+
success: boolean;
|
|
121
|
+
}
|
|
122
|
+
interface RestoreSessionResult {
|
|
123
|
+
success: boolean;
|
|
124
|
+
toolCount: number;
|
|
125
|
+
}
|
|
126
|
+
interface FinishAuthResult {
|
|
127
|
+
success: boolean;
|
|
128
|
+
toolCount: number;
|
|
129
|
+
}
|
|
130
|
+
interface ListToolsRpcResult {
|
|
131
|
+
tools: Tool[];
|
|
132
|
+
}
|
|
133
|
+
interface ListPromptsResult {
|
|
134
|
+
prompts: Array<{
|
|
135
|
+
name: string;
|
|
136
|
+
description?: string;
|
|
137
|
+
arguments?: Array<{
|
|
138
|
+
name: string;
|
|
139
|
+
description?: string;
|
|
140
|
+
required?: boolean;
|
|
141
|
+
}>;
|
|
142
|
+
}>;
|
|
143
|
+
}
|
|
144
|
+
interface ListResourcesResult {
|
|
145
|
+
resources: Array<{
|
|
146
|
+
uri: string;
|
|
147
|
+
name: string;
|
|
148
|
+
description?: string;
|
|
149
|
+
mimeType?: string;
|
|
150
|
+
}>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export { type CallToolParams as C, type DisconnectParams as D, type FinishAuthParams as F, type GetPromptParams as G, type ListPromptsResult as L, type McpRpcMethod as M, type ReadResourceParams as R, type SessionInfo as S, type ToolInfo as T, type CallToolRequest as a, type CallToolResponse as b, type ConnectAuthRequiredResponse as c, type ConnectErrorResponse as d, type ConnectParams as e, type ConnectRequest as f, type ConnectResponse as g, type ConnectResult as h, type ConnectSuccessResponse as i, type DisconnectResult as j, type FinishAuthResult as k, type ListResourcesResult as l, type ListToolsResponse as m, type ListToolsRpcResult as n, type McpRpcParams as o, type McpRpcRequest as p, type McpRpcResponse as q, type RestoreSessionResult as r, type SessionListResult as s, type SessionParams as t, type TransportType as u, isCallToolSuccess as v, isConnectAuthRequired as w, isConnectError as x, isConnectSuccess as y, isListToolsSuccess as z };
|