@toolplex/client 0.1.1

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 (91) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +112 -0
  3. package/dist/mcp-server/clientContext.d.ts +35 -0
  4. package/dist/mcp-server/clientContext.js +107 -0
  5. package/dist/mcp-server/index.d.ts +1 -0
  6. package/dist/mcp-server/index.js +22 -0
  7. package/dist/mcp-server/logging/telemetryLogger.d.ts +18 -0
  8. package/dist/mcp-server/logging/telemetryLogger.js +54 -0
  9. package/dist/mcp-server/policy/callToolObserver.d.ts +9 -0
  10. package/dist/mcp-server/policy/callToolObserver.js +25 -0
  11. package/dist/mcp-server/policy/feedbackPolicy.d.ts +27 -0
  12. package/dist/mcp-server/policy/feedbackPolicy.js +39 -0
  13. package/dist/mcp-server/policy/installObserver.d.ts +11 -0
  14. package/dist/mcp-server/policy/installObserver.js +35 -0
  15. package/dist/mcp-server/policy/playbookPolicy.d.ts +29 -0
  16. package/dist/mcp-server/policy/playbookPolicy.js +81 -0
  17. package/dist/mcp-server/policy/policyEnforcer.d.ts +57 -0
  18. package/dist/mcp-server/policy/policyEnforcer.js +105 -0
  19. package/dist/mcp-server/policy/serverPolicy.d.ts +39 -0
  20. package/dist/mcp-server/policy/serverPolicy.js +61 -0
  21. package/dist/mcp-server/promptsCache.d.ts +25 -0
  22. package/dist/mcp-server/promptsCache.js +51 -0
  23. package/dist/mcp-server/registry.d.ts +34 -0
  24. package/dist/mcp-server/registry.js +109 -0
  25. package/dist/mcp-server/serversCache.d.ts +53 -0
  26. package/dist/mcp-server/serversCache.js +100 -0
  27. package/dist/mcp-server/staticPrompts.d.ts +6 -0
  28. package/dist/mcp-server/staticPrompts.js +6 -0
  29. package/dist/mcp-server/toolDefinitionsCache.d.ts +33 -0
  30. package/dist/mcp-server/toolDefinitionsCache.js +67 -0
  31. package/dist/mcp-server/toolHandlers/callToolHandler.d.ts +3 -0
  32. package/dist/mcp-server/toolHandlers/callToolHandler.js +79 -0
  33. package/dist/mcp-server/toolHandlers/getServerConfigHandler.d.ts +3 -0
  34. package/dist/mcp-server/toolHandlers/getServerConfigHandler.js +69 -0
  35. package/dist/mcp-server/toolHandlers/initHandler.d.ts +3 -0
  36. package/dist/mcp-server/toolHandlers/initHandler.js +117 -0
  37. package/dist/mcp-server/toolHandlers/installServerHandler.d.ts +3 -0
  38. package/dist/mcp-server/toolHandlers/installServerHandler.js +151 -0
  39. package/dist/mcp-server/toolHandlers/listServersHandler.d.ts +2 -0
  40. package/dist/mcp-server/toolHandlers/listServersHandler.js +81 -0
  41. package/dist/mcp-server/toolHandlers/listToolsHandler.d.ts +3 -0
  42. package/dist/mcp-server/toolHandlers/listToolsHandler.js +112 -0
  43. package/dist/mcp-server/toolHandlers/logPlaybookUsageHandler.d.ts +3 -0
  44. package/dist/mcp-server/toolHandlers/logPlaybookUsageHandler.js +65 -0
  45. package/dist/mcp-server/toolHandlers/lookupEntityHandler.d.ts +3 -0
  46. package/dist/mcp-server/toolHandlers/lookupEntityHandler.js +112 -0
  47. package/dist/mcp-server/toolHandlers/savePlaybookHandler.d.ts +3 -0
  48. package/dist/mcp-server/toolHandlers/savePlaybookHandler.js +65 -0
  49. package/dist/mcp-server/toolHandlers/searchHandler.d.ts +3 -0
  50. package/dist/mcp-server/toolHandlers/searchHandler.js +114 -0
  51. package/dist/mcp-server/toolHandlers/serverManagerUtils.d.ts +2 -0
  52. package/dist/mcp-server/toolHandlers/serverManagerUtils.js +20 -0
  53. package/dist/mcp-server/toolHandlers/submitFeedbackHandler.d.ts +3 -0
  54. package/dist/mcp-server/toolHandlers/submitFeedbackHandler.js +70 -0
  55. package/dist/mcp-server/toolHandlers/uninstallServerHandler.d.ts +3 -0
  56. package/dist/mcp-server/toolHandlers/uninstallServerHandler.js +83 -0
  57. package/dist/mcp-server/toolplexApi/service.d.ts +32 -0
  58. package/dist/mcp-server/toolplexApi/service.js +222 -0
  59. package/dist/mcp-server/toolplexApi/types.d.ts +124 -0
  60. package/dist/mcp-server/toolplexApi/types.js +1 -0
  61. package/dist/mcp-server/toolplexServer.d.ts +3 -0
  62. package/dist/mcp-server/toolplexServer.js +249 -0
  63. package/dist/mcp-server/tools.d.ts +2 -0
  64. package/dist/mcp-server/tools.js +13 -0
  65. package/dist/mcp-server/utils/initServerManagers.d.ts +6 -0
  66. package/dist/mcp-server/utils/initServerManagers.js +31 -0
  67. package/dist/mcp-server/utils/resultAnnotators.d.ts +23 -0
  68. package/dist/mcp-server/utils/resultAnnotators.js +50 -0
  69. package/dist/mcp-server/utils/runtimeCheck.d.ts +4 -0
  70. package/dist/mcp-server/utils/runtimeCheck.js +30 -0
  71. package/dist/server-manager/index.d.ts +1 -0
  72. package/dist/server-manager/index.js +8 -0
  73. package/dist/server-manager/serverManager.d.ts +37 -0
  74. package/dist/server-manager/serverManager.js +419 -0
  75. package/dist/server-manager/stdioServer.d.ts +9 -0
  76. package/dist/server-manager/stdioServer.js +136 -0
  77. package/dist/server-manager/stdioTransportProtocol.d.ts +31 -0
  78. package/dist/server-manager/stdioTransportProtocol.js +67 -0
  79. package/dist/shared/enhancedPath.d.ts +7 -0
  80. package/dist/shared/enhancedPath.js +52 -0
  81. package/dist/shared/fileLogger.d.ts +13 -0
  82. package/dist/shared/fileLogger.js +66 -0
  83. package/dist/shared/mcpServerTypes.d.ts +398 -0
  84. package/dist/shared/mcpServerTypes.js +148 -0
  85. package/dist/shared/serverManagerTypes.d.ts +179 -0
  86. package/dist/shared/serverManagerTypes.js +73 -0
  87. package/dist/shared/stdioServerManagerClient.d.ts +12 -0
  88. package/dist/shared/stdioServerManagerClient.js +96 -0
  89. package/dist/version.d.ts +1 -0
  90. package/dist/version.js +1 -0
  91. package/package.json +70 -0
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
7
+ import { ClientContext } from './clientContext.js';
8
+ import Registry from './registry.js';
9
+ import { PRE_INITIALIZATION_PROMPTS } from './staticPrompts.js';
10
+ import { createToolDefinitions } from './tools.js';
11
+ import { handleInitialize } from './toolHandlers/initHandler.js';
12
+ import { handleSearchTool } from './toolHandlers/searchHandler.js';
13
+ import { handleInstallServer } from './toolHandlers/installServerHandler.js';
14
+ import { handleListTools } from './toolHandlers/listToolsHandler.js';
15
+ import { handleListServers } from './toolHandlers/listServersHandler.js';
16
+ import { handleCallTool } from './toolHandlers/callToolHandler.js';
17
+ import { handleUninstallServer } from './toolHandlers/uninstallServerHandler.js';
18
+ import { handleSavePlaybook } from './toolHandlers/savePlaybookHandler.js';
19
+ import { handleLogPlaybookUsage } from './toolHandlers/logPlaybookUsageHandler.js';
20
+ import { handleLookupEntityTool } from './toolHandlers/lookupEntityHandler.js';
21
+ import { handleSubmitFeedback } from './toolHandlers/submitFeedbackHandler.js';
22
+ import { handleGetServerConfig } from './toolHandlers/getServerConfigHandler.js';
23
+ import { StdioServerManagerClient } from '../shared/stdioServerManagerClient.js';
24
+ import { FileLogger } from '../shared/fileLogger.js';
25
+ import { CallToolParamsSchema, InitializeToolplexParamsSchema, InstallParamsSchema, ListToolsParamsSchema, SearchParamsSchema, UninstallParamsSchema, SavePlaybookParamsSchema, LogPlaybookUsageParamsSchema, LookupEntityParamsSchema, SubmitFeedbackParamsSchema, GetServerConfigParamsSchema, } from '../shared/mcpServerTypes.js';
26
+ import { version as clientVersion } from '../version.js';
27
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
+ const logger = FileLogger;
29
+ export async function serve(config) {
30
+ const clientContext = new ClientContext();
31
+ clientContext.dev = config.dev;
32
+ clientContext.apiKey = config.apiKey;
33
+ clientContext.clientMode = config.clientMode;
34
+ clientContext.clientVersion = clientVersion;
35
+ await Registry.init(clientContext);
36
+ await logger.info(`Starting Toolplex server in ${config.dev ? 'development' : 'production'} mode`);
37
+ const server = new Server({
38
+ name: 'toolplex-server',
39
+ version: clientContext.clientVersion,
40
+ }, {
41
+ capabilities: {
42
+ resources: {},
43
+ tools: {},
44
+ },
45
+ });
46
+ // Initialize server manager clients
47
+ await logger.info('Initializing server manager clients');
48
+ const serverManagerClients = {
49
+ node: new StdioServerManagerClient('node', [path.join(__dirname, '..', 'server-manager', 'index.js')], { LOG_LEVEL: config.logLevel }),
50
+ };
51
+ // Start all server manager clients
52
+ await logger.info('Starting server manager clients');
53
+ await Promise.all(Object.values(serverManagerClients).map((client) => client.start()));
54
+ await logger.info('All server manager clients started successfully');
55
+ Registry.setServerManagerClients(serverManagerClients);
56
+ // List tools handler
57
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
58
+ await logger.debug('Handling list tools request');
59
+ return {
60
+ tools: createToolDefinitions(),
61
+ };
62
+ });
63
+ // Call tool handler
64
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
65
+ const { name, arguments: params } = request.params;
66
+ await logger.info(`Handling tool call request for tool: ${name}`);
67
+ let result;
68
+ if (!Registry.getToolDefinitionsCache().isInitialized()) {
69
+ result = {
70
+ role: 'system',
71
+ content: [
72
+ {
73
+ type: 'text',
74
+ text: PRE_INITIALIZATION_PROMPTS.tools_initialization_error,
75
+ },
76
+ ],
77
+ };
78
+ return result;
79
+ }
80
+ if (!clientContext.isInitialized() && name !== 'initialize_toolplex') {
81
+ result = {
82
+ role: 'system',
83
+ content: [
84
+ {
85
+ type: 'text',
86
+ text: PRE_INITIALIZATION_PROMPTS.enforce_init_toolplex.replace('{TOOL_NAME}', name),
87
+ },
88
+ ],
89
+ };
90
+ return result;
91
+ }
92
+ try {
93
+ switch (name) {
94
+ case 'initialize_toolplex': {
95
+ await logger.debug('Handling initialize_toolplex request');
96
+ const parsed = InitializeToolplexParamsSchema.safeParse(params);
97
+ if (!parsed.success)
98
+ throw new Error(`Invalid initialize_toolplex params: ${parsed.error}`);
99
+ clientContext.llmContext = parsed.data.llm_context;
100
+ result = await handleInitialize(parsed.data);
101
+ break;
102
+ }
103
+ case 'search': {
104
+ await logger.debug('Handling search request');
105
+ const parsed = SearchParamsSchema.safeParse(params);
106
+ if (!parsed.success)
107
+ throw new Error(`Invalid search params: ${parsed.error}`);
108
+ result = await handleSearchTool(parsed.data);
109
+ break;
110
+ }
111
+ case 'install': {
112
+ await logger.debug('Handling install request');
113
+ const parsed = InstallParamsSchema.safeParse(params);
114
+ if (!parsed.success)
115
+ throw new Error(`Invalid install params: ${parsed.error}`);
116
+ result = await handleInstallServer(parsed.data);
117
+ server.sendToolListChanged();
118
+ break;
119
+ }
120
+ case 'list_tools': {
121
+ await logger.debug('Handling list_tools request');
122
+ const parsed = ListToolsParamsSchema.safeParse(params);
123
+ if (!parsed.success)
124
+ throw new Error(`Invalid list_toolplex_tools params: ${parsed.error}`);
125
+ result = await handleListTools(parsed.data);
126
+ break;
127
+ }
128
+ case 'list_servers': {
129
+ await logger.debug('Handling list_toolplex_tools request');
130
+ result = await handleListServers();
131
+ break;
132
+ }
133
+ case 'call_tool': {
134
+ await logger.debug('Handling call_tool request');
135
+ const parsed = CallToolParamsSchema.safeParse(params);
136
+ if (!parsed.success)
137
+ throw new Error(`Invalid call_tool params: ${parsed.error}`);
138
+ result = await handleCallTool(parsed.data);
139
+ break;
140
+ }
141
+ case 'uninstall': {
142
+ await logger.debug('Handling uninstall request');
143
+ const parsed = UninstallParamsSchema.safeParse(params);
144
+ if (!parsed.success)
145
+ throw new Error(`Invalid uninstall params: ${parsed.error}`);
146
+ result = await handleUninstallServer(parsed.data);
147
+ break;
148
+ }
149
+ case 'save_playbook': {
150
+ await logger.debug('Handling save_playbook request');
151
+ const parsed = SavePlaybookParamsSchema.safeParse(params);
152
+ if (!parsed.success)
153
+ throw new Error(`Invalid save_playbook params: ${parsed.error}`);
154
+ if (!clientContext.isInitialized())
155
+ throw new Error(`ToolPlex is not initialized`);
156
+ result = await handleSavePlaybook(parsed.data);
157
+ break;
158
+ }
159
+ case 'log_playbook_usage': {
160
+ await logger.debug('Handling log_playbook_usage request');
161
+ const parsed = LogPlaybookUsageParamsSchema.safeParse(params);
162
+ if (!parsed.success)
163
+ throw new Error(`Invalid log_playbook_usage params: ${parsed.error}`);
164
+ if (!clientContext.isInitialized())
165
+ throw new Error(`ToolPlex is not initialized`);
166
+ result = await handleLogPlaybookUsage(parsed.data);
167
+ break;
168
+ }
169
+ case 'lookup_entity': {
170
+ await logger.debug('Handling lookup_entity request');
171
+ const parsed = LookupEntityParamsSchema.safeParse(params);
172
+ if (!parsed.success)
173
+ throw new Error(`Invalid lookup_entity params: ${parsed.error}`);
174
+ result = await handleLookupEntityTool(parsed.data);
175
+ break;
176
+ }
177
+ case 'submit_feedback': {
178
+ await logger.debug('Handling submit_feedback request');
179
+ const parsed = SubmitFeedbackParamsSchema.safeParse(params);
180
+ if (!parsed.success)
181
+ throw new Error(`Invalid submit_feedback params: ${parsed.error}`);
182
+ if (!clientContext.isInitialized())
183
+ throw new Error(`ToolPlex is not initialized`);
184
+ result = await handleSubmitFeedback(parsed.data);
185
+ break;
186
+ }
187
+ // Add get_server_config tool handler
188
+ case 'get_server_config': {
189
+ await logger.debug('Handling get_server_config request');
190
+ const parsed = GetServerConfigParamsSchema.safeParse(params);
191
+ if (!parsed.success)
192
+ throw new Error(`Invalid get_server_config params: ${parsed.error}`);
193
+ result = await handleGetServerConfig(parsed.data);
194
+ break;
195
+ }
196
+ default:
197
+ await logger.warn(`Unknown tool requested: ${name}`);
198
+ result = {
199
+ role: 'system',
200
+ content: [
201
+ {
202
+ type: 'text',
203
+ text: PRE_INITIALIZATION_PROMPTS.unknown_tool.replace('{TOOL_NAME}', name),
204
+ },
205
+ ],
206
+ };
207
+ }
208
+ }
209
+ catch (error) {
210
+ let errorMessage = 'Unknown error occurred';
211
+ if (error instanceof Error) {
212
+ errorMessage = error.message;
213
+ }
214
+ await logger.error(`Error calling ToolPlex: ${errorMessage}`);
215
+ result = {
216
+ role: 'system',
217
+ content: [
218
+ {
219
+ type: 'text',
220
+ text: PRE_INITIALIZATION_PROMPTS.unexpected_error.replace('{ERROR}', errorMessage),
221
+ },
222
+ ],
223
+ };
224
+ }
225
+ return result;
226
+ });
227
+ const transport = new StdioServerTransport();
228
+ await logger.info('Connecting server transport');
229
+ await server.connect(transport);
230
+ await logger.info('Server transport connected successfully');
231
+ // Clean up on process exit
232
+ process.on('exit', async () => {
233
+ await logger.info('Process exit - stopping server manager clients');
234
+ await logger.flush();
235
+ Object.values(serverManagerClients).forEach((client) => client.stop());
236
+ });
237
+ process.on('SIGINT', async () => {
238
+ await logger.warn('SIGINT received - stopping server manager clients');
239
+ await logger.flush();
240
+ Object.values(serverManagerClients).forEach((client) => client.stop());
241
+ process.exit();
242
+ });
243
+ process.on('SIGTERM', async () => {
244
+ await logger.warn('SIGTERM received - stopping server manager clients');
245
+ await logger.flush();
246
+ Object.values(serverManagerClients).forEach((client) => client.stop());
247
+ process.exit();
248
+ });
249
+ }
@@ -0,0 +1,2 @@
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ export declare function createToolDefinitions(): Tool[];
@@ -0,0 +1,13 @@
1
+ import Registry from './registry.js';
2
+ export function createToolDefinitions() {
3
+ const toolDefinitionsCache = Registry.getToolDefinitionsCache();
4
+ if (!toolDefinitionsCache.isInitialized()) {
5
+ return [
6
+ {
7
+ name: 'initialize_toolplex',
8
+ inputSchema: { type: 'object', properties: {}, required: [] },
9
+ },
10
+ ];
11
+ }
12
+ return toolDefinitionsCache.getTools();
13
+ }
@@ -0,0 +1,6 @@
1
+ import { StdioServerManagerClient } from '../../shared/stdioServerManagerClient.js';
2
+ import { InitializeResult } from '../../shared/serverManagerTypes.js';
3
+ export declare function initServerManagersOnly(serverManagerClients: Record<string, StdioServerManagerClient>): Promise<{
4
+ succeeded: InitializeResult['succeeded'];
5
+ failures: InitializeResult['failures'];
6
+ }>;
@@ -0,0 +1,31 @@
1
+ import { InitializeResultSchema } from '../../shared/serverManagerTypes.js';
2
+ import { FileLogger } from '../../shared/fileLogger.js';
3
+ const logger = FileLogger;
4
+ export async function initServerManagersOnly(serverManagerClients) {
5
+ await logger.info('Pre-warming server manager clients');
6
+ const initPromises = Object.entries(serverManagerClients).map(async ([runtime, client]) => {
7
+ try {
8
+ const response = await client.sendRequest('initialize', {});
9
+ if ('error' in response)
10
+ throw new Error(response.error.message);
11
+ const parsed = InitializeResultSchema.safeParse(response);
12
+ if (!parsed.success)
13
+ throw new Error(parsed.error.message);
14
+ return { runtime, result: parsed.data };
15
+ }
16
+ catch (err) {
17
+ await logger.error(`Warmup error for ${runtime}: ${err}`);
18
+ return { runtime, result: { succeeded: [], failures: {} } };
19
+ }
20
+ });
21
+ const results = await Promise.all(initPromises);
22
+ const allSucceeded = [];
23
+ const allFailures = {};
24
+ for (const { runtime, result } of results) {
25
+ allSucceeded.push(...(result.succeeded || []));
26
+ Object.assign(allFailures, result.failures || {});
27
+ await logger.debug(`Warmup result for ${runtime}: ${JSON.stringify(result)}`);
28
+ }
29
+ await logger.debug(`Warmup completed: ${allSucceeded.length} successes, ${Object.keys(allFailures).length} failures`);
30
+ return { succeeded: allSucceeded, failures: allFailures };
31
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Annotate a server object with "(installed)" in the server_name or set installed: true,
3
+ * if the server is installed according to the provided serversCache.
4
+ *
5
+ * This is used in both searchHandler and lookupEntityHandler.
6
+ *
7
+ * @param server - The server object to annotate (should have server_id and optionally server_name)
8
+ * @param serversCache - The ServersCache instance with isInstalled(server_id) method
9
+ * @returns The annotated server object (may be the same object if not installed)
10
+ */
11
+ export declare function annotateInstalledServer(server: any, serversCache: {
12
+ isInstalled: (id: string) => boolean;
13
+ }): any;
14
+ /**
15
+ * Annotate an array of server objects with installed status.
16
+ *
17
+ * @param servers - Array of server objects
18
+ * @param serversCache - The ServersCache instance
19
+ * @returns Annotated array of server objects
20
+ */
21
+ export declare function annotateInstalledServers(servers: any[], serversCache: {
22
+ isInstalled: (id: string) => boolean;
23
+ }): any[];
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Annotate a server object with "(installed)" in the server_name or set installed: true,
3
+ * if the server is installed according to the provided serversCache.
4
+ *
5
+ * This is used in both searchHandler and lookupEntityHandler.
6
+ *
7
+ * @param server - The server object to annotate (should have server_id and optionally server_name)
8
+ * @param serversCache - The ServersCache instance with isInstalled(server_id) method
9
+ * @returns The annotated server object (may be the same object if not installed)
10
+ */
11
+ export function annotateInstalledServer(
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ server, serversCache
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ ) {
16
+ if (!server || typeof server !== 'object' || !server.server_id) {
17
+ return server;
18
+ }
19
+ if (serversCache.isInstalled(server.server_id)) {
20
+ if (server.server_name) {
21
+ return {
22
+ ...server,
23
+ server_name: `${server.server_name} (installed)`,
24
+ };
25
+ }
26
+ else {
27
+ return {
28
+ ...server,
29
+ installed: true,
30
+ };
31
+ }
32
+ }
33
+ return server;
34
+ }
35
+ /**
36
+ * Annotate an array of server objects with installed status.
37
+ *
38
+ * @param servers - Array of server objects
39
+ * @param serversCache - The ServersCache instance
40
+ * @returns Annotated array of server objects
41
+ */
42
+ export function annotateInstalledServers(
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ servers, serversCache
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ ) {
47
+ if (!Array.isArray(servers))
48
+ return [];
49
+ return servers.map((server) => annotateInstalledServer(server, serversCache));
50
+ }
@@ -0,0 +1,4 @@
1
+ export declare class RuntimeCheck {
2
+ static validateCommandOrThrow(rawCommand: string): void;
3
+ static extractCommandName(command: string): string;
4
+ }
@@ -0,0 +1,30 @@
1
+ import { getEnhancedPath } from '../../shared/enhancedPath.js';
2
+ import which from 'which';
3
+ const INSTALL_HINTS = {
4
+ uvx: 'Install uvx: https://docs.astral.sh/uv/getting-started/installation/',
5
+ uv: 'Install uv: https://docs.astral.sh/uv/getting-started/installation/',
6
+ python: 'Install Python: https://www.python.org/downloads/. Or check if you have `python3` installed.',
7
+ python3: 'Install Python: https://www.python.org/downloads/. Or check if you have `python` installed.',
8
+ node: 'Install Node.js: https://nodejs.org/en/download/',
9
+ npx: 'Install npx (comes with Node.js): https://nodejs.org/en/download/',
10
+ };
11
+ export class RuntimeCheck {
12
+ static validateCommandOrThrow(rawCommand) {
13
+ const command = this.extractCommandName(rawCommand);
14
+ const enhancedPath = getEnhancedPath();
15
+ const resolved = which.sync(command, {
16
+ path: enhancedPath,
17
+ nothrow: true,
18
+ });
19
+ if (!resolved) {
20
+ const hint = INSTALL_HINTS[command];
21
+ if (hint) {
22
+ throw new Error(`Missing required command: '${command}'.\n👉 ${hint}`);
23
+ }
24
+ throw new Error(`Command '${command}' not found in enhanced PATH. Please install it manually or check your config.`);
25
+ }
26
+ }
27
+ static extractCommandName(command) {
28
+ return command.trim().split(/\s+/)[0];
29
+ }
30
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { ServerManagerProtocol } from './stdioServer.js';
2
+ import { FileLogger } from '../shared/fileLogger.js';
3
+ FileLogger.initialize('server-manager');
4
+ const protocol = new ServerManagerProtocol();
5
+ protocol.start().catch((error) => {
6
+ console.error('Failed to start server:', error);
7
+ process.exit(1);
8
+ });
@@ -0,0 +1,37 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
4
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
5
+ import { ServerConfig } from '../shared/mcpServerTypes.js';
6
+ import { InitializeResult } from '../shared/serverManagerTypes.js';
7
+ export declare class ServerManager {
8
+ private sessions;
9
+ private tools;
10
+ private serverNames;
11
+ private configPath;
12
+ private config;
13
+ private installationPromises;
14
+ private configLock;
15
+ constructor();
16
+ private loadConfig;
17
+ private saveConfig;
18
+ initialize(): Promise<InitializeResult>;
19
+ getServerName(serverId: string): Promise<string>;
20
+ connectWithHandshakeTimeout(client: Client, transport: SSEClientTransport | StdioClientTransport, ms?: number): Promise<{
21
+ tools?: Tool[];
22
+ }>;
23
+ install(serverId: string, serverName: string, description: string, config: ServerConfig): Promise<void>;
24
+ private performInstall;
25
+ callTool(serverId: string, toolName: string, arguments_: Record<string, any>, timeout?: number): Promise<any>;
26
+ uninstall(serverId: string): Promise<void>;
27
+ removeServer(serverId: string): Promise<void>;
28
+ listServers(): Promise<Array<{
29
+ server_id: string;
30
+ server_name: string;
31
+ tool_count: number;
32
+ description: string;
33
+ }>>;
34
+ listTools(serverId: string): Promise<Tool[]>;
35
+ getServerConfig(serverId: string): Promise<ServerConfig>;
36
+ cleanup(): Promise<void>;
37
+ }