@axiom-lattice/gateway 3.0.2 → 3.0.3

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 (155) hide show
  1. package/dist/index.js +31 -9
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +31 -9
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +9 -6
  6. package/.eslintrc.json +0 -22
  7. package/.turbo/turbo-build.log +0 -46
  8. package/AGENTS.md +0 -112
  9. package/CHANGELOG.md +0 -1190
  10. package/LOGGER_CONFIG.md +0 -135
  11. package/RESUME_STREAM_CONTENT_BASED.md +0 -326
  12. package/RESUME_STREAM_README.md +0 -388
  13. package/jest.config.js +0 -72
  14. package/public/sdk/README.md +0 -695
  15. package/public/sdk/dashboard-engine-skill.md +0 -1122
  16. package/public/sdk/dashboard-single-file-spec.md +0 -357
  17. package/public/sdk/data-query-sdk-skill.md +0 -307
  18. package/public/sdk/data-query-sdk.d.ts +0 -252
  19. package/public/sdk/data-query-sdk.js +0 -970
  20. package/public/sdk/occupancy-dashboard.html +0 -363
  21. package/public/sdk/test-dashboard.html +0 -690
  22. package/scripts/seed-lark-installation.ts +0 -54
  23. package/src/__tests__/__mocks__/e2b.ts +0 -1
  24. package/src/__tests__/a2a.test.ts +0 -428
  25. package/src/__tests__/channel-installations.test.ts +0 -199
  26. package/src/__tests__/data-query.test.ts +0 -77
  27. package/src/__tests__/sandbox-provider-registration.test.ts +0 -74
  28. package/src/__tests__/setup.ts +0 -5
  29. package/src/__tests__/workspace.test.ts +0 -400
  30. package/src/channels/__tests__/routes.test.ts +0 -50
  31. package/src/channels/lark/LarkChannelAdapter.ts +0 -217
  32. package/src/channels/lark/README.md +0 -187
  33. package/src/channels/lark/__tests__/controller.test.ts +0 -136
  34. package/src/channels/lark/__tests__/mapping-service.test.ts +0 -118
  35. package/src/channels/lark/__tests__/parser.test.ts +0 -72
  36. package/src/channels/lark/__tests__/sender.test.ts +0 -37
  37. package/src/channels/lark/__tests__/verification.test.ts +0 -157
  38. package/src/channels/lark/controller.ts +0 -48
  39. package/src/channels/lark/mapping-service.ts +0 -138
  40. package/src/channels/lark/parser.ts +0 -68
  41. package/src/channels/lark/routes.ts +0 -22
  42. package/src/channels/lark/sender.ts +0 -58
  43. package/src/channels/lark/types.ts +0 -20
  44. package/src/channels/lark/verification.ts +0 -32
  45. package/src/channels/registry.ts +0 -20
  46. package/src/channels/routes.ts +0 -30
  47. package/src/channels/wechat/WechatChannelAdapter.ts +0 -294
  48. package/src/channels/wechat/__tests__/context-store.test.ts +0 -148
  49. package/src/channels/wechat/context-store.ts +0 -54
  50. package/src/channels/wechat/controller.ts +0 -59
  51. package/src/channels/wechat/routes.ts +0 -7
  52. package/src/channels/wechat/types.ts +0 -62
  53. package/src/channels/wechat/wechat-client.ts +0 -162
  54. package/src/config/local-a2a-templates.ts +0 -59
  55. package/src/config.ts +0 -124
  56. package/src/controllers/__tests__/assistant-local-a2a.test.ts +0 -147
  57. package/src/controllers/__tests__/local-a2a-templates.test.ts +0 -112
  58. package/src/controllers/__tests__/mime.test.ts +0 -74
  59. package/src/controllers/__tests__/resources.test.ts +0 -122
  60. package/src/controllers/__tests__/run.test.ts +0 -115
  61. package/src/controllers/__tests__/tasks.test.ts +0 -215
  62. package/src/controllers/__tests__/workflow-tracking.test.ts +0 -113
  63. package/src/controllers/agent_task.ts +0 -72
  64. package/src/controllers/assistant.ts +0 -490
  65. package/src/controllers/auth.ts +0 -524
  66. package/src/controllers/channel-bindings.ts +0 -135
  67. package/src/controllers/channel-installations.ts +0 -409
  68. package/src/controllers/collections.ts +0 -176
  69. package/src/controllers/config.ts +0 -126
  70. package/src/controllers/connections.ts +0 -181
  71. package/src/controllers/data-query.ts +0 -236
  72. package/src/controllers/database-configs.ts +0 -440
  73. package/src/controllers/embeddings.ts +0 -22
  74. package/src/controllers/entries.ts +0 -167
  75. package/src/controllers/eval.ts +0 -513
  76. package/src/controllers/export-import.ts +0 -166
  77. package/src/controllers/health.ts +0 -36
  78. package/src/controllers/local-a2a-templates.ts +0 -18
  79. package/src/controllers/local-a2a.ts +0 -149
  80. package/src/controllers/mcp-configs.ts +0 -673
  81. package/src/controllers/memory.ts +0 -257
  82. package/src/controllers/menu-items.ts +0 -114
  83. package/src/controllers/metrics-configs.ts +0 -1061
  84. package/src/controllers/middleware-types.ts +0 -15
  85. package/src/controllers/models.ts +0 -199
  86. package/src/controllers/personal-assistant.ts +0 -191
  87. package/src/controllers/resources.ts +0 -477
  88. package/src/controllers/run.ts +0 -338
  89. package/src/controllers/sandbox.ts +0 -255
  90. package/src/controllers/schedules.ts +0 -336
  91. package/src/controllers/skills.ts +0 -256
  92. package/src/controllers/tasks.ts +0 -213
  93. package/src/controllers/tenants.ts +0 -121
  94. package/src/controllers/thread_status.ts +0 -66
  95. package/src/controllers/threads.ts +0 -260
  96. package/src/controllers/tools.ts +0 -139
  97. package/src/controllers/users.ts +0 -135
  98. package/src/controllers/workflow-tracking.ts +0 -693
  99. package/src/controllers/workspace.ts +0 -879
  100. package/src/export_registrations/a2a-api-key.registration.ts +0 -89
  101. package/src/export_registrations/agent.registration.ts +0 -80
  102. package/src/export_registrations/binding.registration.ts +0 -106
  103. package/src/export_registrations/channel-installation.registration.ts +0 -88
  104. package/src/export_registrations/collection.registration.ts +0 -85
  105. package/src/export_registrations/connection.registration.ts +0 -97
  106. package/src/export_registrations/database-config.registration.ts +0 -94
  107. package/src/export_registrations/eval.registration.ts +0 -334
  108. package/src/export_registrations/index.ts +0 -31
  109. package/src/export_registrations/mcp-config.registration.ts +0 -97
  110. package/src/export_registrations/menu.registration.ts +0 -91
  111. package/src/export_registrations/metrics-config.registration.ts +0 -94
  112. package/src/export_registrations/skill.registration.ts +0 -88
  113. package/src/export_registrations/task.registration.ts +0 -99
  114. package/src/index.ts +0 -497
  115. package/src/logger/Logger.ts +0 -186
  116. package/src/router/MessageContext.ts +0 -14
  117. package/src/router/MessageRouter.ts +0 -490
  118. package/src/router/middlewares/auditLogger.ts +0 -34
  119. package/src/router/middlewares/deduplication.ts +0 -38
  120. package/src/router/middlewares/index.ts +0 -3
  121. package/src/router/middlewares/rateLimit.ts +0 -46
  122. package/src/routes/__tests__/a2a-test-connection.test.ts +0 -177
  123. package/src/routes/a2a-bridge.ts +0 -266
  124. package/src/routes/a2a-test-connection.ts +0 -126
  125. package/src/routes/a2a.ts +0 -851
  126. package/src/routes/channel-bindings.ts +0 -11
  127. package/src/routes/channel-installations.ts +0 -33
  128. package/src/routes/index.ts +0 -640
  129. package/src/routes/menu-items.ts +0 -10
  130. package/src/routes/resource-routes.ts +0 -35
  131. package/src/routes/stt.ts +0 -102
  132. package/src/schemas/data-query.ts +0 -69
  133. package/src/schemas/index.ts +0 -852
  134. package/src/services/ExportImportService.ts +0 -296
  135. package/src/services/__tests__/ExportImportService.test.ts +0 -130
  136. package/src/services/__tests__/eval-runner.test.ts +0 -131
  137. package/src/services/__tests__/local-a2a.test.ts +0 -124
  138. package/src/services/agent_task_consumer.ts +0 -348
  139. package/src/services/collection_service.ts +0 -258
  140. package/src/services/eval-runner.ts +0 -283
  141. package/src/services/local-a2a.ts +0 -354
  142. package/src/services/queue_service.ts +0 -104
  143. package/src/services/sandbox_service.ts +0 -223
  144. package/src/services/skill_service.ts +0 -97
  145. package/src/services/supabase.ts +0 -60
  146. package/src/swagger.ts +0 -77
  147. package/src/types/index.ts +0 -118
  148. package/src/types/koa.d.ts +0 -7
  149. package/src/utils/__tests__/local-a2a-runtime.test.ts +0 -77
  150. package/src/utils/__tests__/path-containment.test.ts +0 -35
  151. package/src/utils/a2a-url.ts +0 -20
  152. package/src/utils/local-a2a-runtime.ts +0 -107
  153. package/src/utils/mime.ts +0 -44
  154. package/src/utils/path-containment.ts +0 -38
  155. package/tsconfig.json +0 -26
@@ -1,673 +0,0 @@
1
- /**
2
- * MCP Server Config Controller
3
- * Handles MCP server configuration CRUD operations with automatic tool registration
4
- */
5
-
6
- import { FastifyRequest, FastifyReply } from "fastify";
7
- import {
8
- getStoreLattice,
9
- mcpManager,
10
- McpLatticeManager,
11
- } from "@axiom-lattice/core";
12
- import type {
13
- McpServerConfigStore,
14
- McpServerConfigEntry,
15
- CreateMcpServerConfigRequest,
16
- UpdateMcpServerConfigRequest,
17
- McpServerConfig,
18
- McpTool,
19
- } from "@axiom-lattice/protocols";
20
- import { randomUUID } from "crypto";
21
-
22
- /**
23
- * Get tenant ID from authenticated user context
24
- * Falls back to request headers for backward compatibility
25
- */
26
- function getTenantId(request: FastifyRequest): string {
27
- // First try to get from authenticated user context
28
- const userTenantId = (request as any).user?.tenantId;
29
- if (userTenantId) {
30
- return userTenantId;
31
- }
32
-
33
- // Fallback to request headers for backward compatibility
34
- return (request.headers["x-tenant-id"] as string) || "default";
35
- }
36
-
37
- /**
38
- * MCP server config list response
39
- */
40
- interface McpServerConfigListResponse {
41
- success: boolean;
42
- message: string;
43
- data: {
44
- records: McpServerConfigEntry[];
45
- total: number;
46
- };
47
- }
48
-
49
- /**
50
- * MCP server config response
51
- */
52
- interface McpServerConfigResponse {
53
- success: boolean;
54
- message: string;
55
- data?: McpServerConfigEntry;
56
- }
57
-
58
- /**
59
- * Test connection response
60
- */
61
- interface TestConnectionResponse {
62
- success: boolean;
63
- message: string;
64
- data?: {
65
- connected: boolean;
66
- latency?: number;
67
- error?: string;
68
- };
69
- }
70
-
71
- /**
72
- * List tools response
73
- */
74
- interface ListToolsResponse {
75
- success: boolean;
76
- message: string;
77
- data?: {
78
- tools: McpTool[];
79
- };
80
- }
81
-
82
- /**
83
- * Get all MCP server configs for a tenant
84
- */
85
- export async function getMcpServerConfigList(
86
- request: FastifyRequest,
87
- reply: FastifyReply
88
- ): Promise<McpServerConfigListResponse> {
89
- const tenantId = getTenantId(request);
90
-
91
- try {
92
- const storeLattice = getStoreLattice("default", "mcp");
93
- const store: McpServerConfigStore = storeLattice.store;
94
-
95
- const configs = await store.getAllConfigs(tenantId);
96
-
97
- return {
98
- success: true,
99
- message: "MCP server configurations retrieved successfully",
100
- data: {
101
- records: configs,
102
- total: configs.length,
103
- },
104
- };
105
- } catch (error) {
106
- console.error("Failed to get MCP server configs:", error);
107
- return {
108
- success: false,
109
- message: "Failed to retrieve MCP server configurations",
110
- data: {
111
- records: [],
112
- total: 0,
113
- },
114
- };
115
- }
116
- }
117
-
118
- /**
119
- * Get MCP server config by key
120
- */
121
- export async function getMcpServerConfig(
122
- request: FastifyRequest,
123
- reply: FastifyReply
124
- ): Promise<McpServerConfigResponse> {
125
- const tenantId = getTenantId(request);
126
- const { key } = request.params as { key: string };
127
-
128
- try {
129
- const storeLattice = getStoreLattice("default", "mcp");
130
- const store: McpServerConfigStore = storeLattice.store;
131
-
132
- const config = await store.getConfigByKey(tenantId, key);
133
-
134
- if (!config) {
135
- return {
136
- success: false,
137
- message: "MCP server configuration not found",
138
- };
139
- }
140
-
141
- return {
142
- success: true,
143
- message: "MCP server configuration retrieved successfully",
144
- data: config,
145
- };
146
- } catch (error) {
147
- console.error("Failed to get MCP server config:", error);
148
- return {
149
- success: false,
150
- message: "Failed to retrieve MCP server configuration",
151
- };
152
- }
153
- }
154
-
155
- /**
156
- * Create new MCP server config
157
- */
158
- export async function createMcpServerConfig(
159
- request: FastifyRequest,
160
- reply: FastifyReply
161
- ): Promise<McpServerConfigResponse> {
162
- const tenantId = getTenantId(request);
163
- const body = request.body as CreateMcpServerConfigRequest & {
164
- id?: string;
165
- };
166
-
167
- try {
168
- const storeLattice = getStoreLattice("default", "mcp");
169
- const store: McpServerConfigStore = storeLattice.store;
170
-
171
- // Check if key already exists
172
- const existing = await store.getConfigByKey(tenantId, body.key);
173
- if (existing) {
174
- reply.code(409);
175
- return {
176
- success: false,
177
- message: "MCP server configuration with this key already exists",
178
- };
179
- }
180
-
181
- const id = body.id || randomUUID();
182
- const config = await store.createConfig(tenantId, id, body);
183
-
184
- // Auto-connect and register tools
185
- try {
186
- await connectAndRegisterTools(config);
187
- // Update status to connected
188
- await store.updateConfig(tenantId, id, { status: "connected" });
189
- config.status = "connected";
190
- } catch (error) {
191
- console.warn("Failed to auto-connect MCP server:", error);
192
- // Update status to error but don't fail the creation
193
- await store.updateConfig(tenantId, id, { status: "error" });
194
- config.status = "error";
195
- }
196
-
197
- reply.code(201);
198
- return {
199
- success: true,
200
- message: "MCP server configuration created successfully",
201
- data: config,
202
- };
203
- } catch (error) {
204
- console.error("Failed to create MCP server config:", error);
205
- return {
206
- success: false,
207
- message: "Failed to create MCP server configuration",
208
- };
209
- }
210
- }
211
-
212
- /**
213
- * Update MCP server config
214
- */
215
- export async function updateMcpServerConfig(
216
- request: FastifyRequest,
217
- reply: FastifyReply
218
- ): Promise<McpServerConfigResponse> {
219
- const tenantId = getTenantId(request);
220
- const { key } = request.params as { key: string };
221
- const updates = request.body as Partial<UpdateMcpServerConfigRequest>;
222
-
223
- try {
224
- const storeLattice = getStoreLattice("default", "mcp");
225
- const store: McpServerConfigStore = storeLattice.store;
226
-
227
- const existing = await store.getConfigByKey(tenantId, key);
228
- if (!existing) {
229
- reply.code(404);
230
- return {
231
- success: false,
232
- message: "MCP server configuration not found",
233
- };
234
- }
235
-
236
- // If config is being updated, we need to reconnect
237
- const shouldReconnect = updates.config !== undefined;
238
-
239
- const updated = await store.updateConfig(tenantId, existing.id, updates);
240
-
241
- if (!updated) {
242
- return {
243
- success: false,
244
- message: "Failed to update MCP server configuration",
245
- };
246
- }
247
-
248
- // Reconnect and re-register tools if config changed
249
- if (shouldReconnect) {
250
- try {
251
- // Reconnect single server without affecting others
252
- await mcpManager.reconnectServer(key);
253
-
254
- // Re-register tools with new config
255
- await mcpManager.registerToolsToToolLattice(key, updated.selectedTools);
256
-
257
- await store.updateConfig(tenantId, existing.id, { status: "connected" });
258
- updated.status = "connected";
259
- } catch (error) {
260
- console.warn("Failed to reconnect MCP server:", error);
261
- await store.updateConfig(tenantId, existing.id, { status: "error" });
262
- updated.status = "error";
263
- }
264
- }
265
-
266
- return {
267
- success: true,
268
- message: "MCP server configuration updated successfully",
269
- data: updated,
270
- };
271
- } catch (error) {
272
- console.error("Failed to update MCP server config:", error);
273
- return {
274
- success: false,
275
- message: "Failed to update MCP server configuration",
276
- };
277
- }
278
- }
279
-
280
- /**
281
- * Delete MCP server config by key or id
282
- */
283
- export async function deleteMcpServerConfig(
284
- request: FastifyRequest,
285
- reply: FastifyReply
286
- ): Promise<McpServerConfigResponse> {
287
- const tenantId = getTenantId(request);
288
- const { keyOrId } = request.params as { keyOrId: string };
289
-
290
- try {
291
- const storeLattice = getStoreLattice("default", "mcp");
292
- const store: McpServerConfigStore = storeLattice.store;
293
-
294
- // Try to find by key first, then by id
295
- let config = await store.getConfigByKey(tenantId, keyOrId);
296
- let configKey = keyOrId;
297
-
298
- if (!config) {
299
- // Try to find by id
300
- config = await store.getConfigById(tenantId, keyOrId);
301
- if (config) {
302
- configKey = config.key;
303
- }
304
- }
305
-
306
- if (!config) {
307
- reply.code(404);
308
- return {
309
- success: false,
310
- message: "MCP server configuration not found",
311
- };
312
- }
313
-
314
- // Disconnect and remove from MCP manager
315
- try {
316
- if (mcpManager.hasServer(configKey)) {
317
- await mcpManager.removeServer(configKey);
318
- }
319
- } catch (error) {
320
- console.warn("Failed to remove from MCP manager:", error);
321
- }
322
-
323
- const deleted = await store.deleteConfig(tenantId, config.id);
324
-
325
- if (!deleted) {
326
- return {
327
- success: false,
328
- message: "Failed to delete MCP server configuration",
329
- };
330
- }
331
-
332
- return {
333
- success: true,
334
- message: "MCP server configuration deleted successfully",
335
- };
336
- } catch (error) {
337
- console.error("Failed to delete MCP server config:", error);
338
- return {
339
- success: false,
340
- message: "Failed to delete MCP server configuration",
341
- };
342
- }
343
- }
344
-
345
- /**
346
- * Test MCP server connection
347
- */
348
- export async function testMcpServerConnection(
349
- request: FastifyRequest,
350
- reply: FastifyReply
351
- ): Promise<TestConnectionResponse> {
352
- const tenantId = getTenantId(request);
353
- const { key } = request.params as { key: string };
354
-
355
- try {
356
- const storeLattice = getStoreLattice("default", "mcp");
357
- const store: McpServerConfigStore = storeLattice.store;
358
-
359
- const config = await store.getConfigByKey(tenantId, key);
360
- if (!config) {
361
- reply.code(404);
362
- return {
363
- success: false,
364
- message: "MCP server configuration not found",
365
- };
366
- }
367
-
368
- // Test connection by creating a standalone client
369
- try {
370
- const testKey = `__test_${key}_${Date.now()}`;
371
- const connection = convertToConnection(config.config);
372
- const { latency } = await McpLatticeManager.testConnection(testKey, connection);
373
-
374
- return {
375
- success: true,
376
- message: "Connection test successful",
377
- data: {
378
- connected: true,
379
- latency,
380
- },
381
- };
382
- } catch (error) {
383
- return {
384
- success: true,
385
- message: "Connection test failed",
386
- data: {
387
- connected: false,
388
- error: error instanceof Error ? error.message : "Unknown error",
389
- },
390
- };
391
- }
392
- } catch (error) {
393
- console.error("Failed to test MCP server connection:", error);
394
- return {
395
- success: false,
396
- message: "Failed to test MCP server connection",
397
- data: {
398
- connected: false,
399
- error: error instanceof Error ? error.message : "Unknown error",
400
- },
401
- };
402
- }
403
- }
404
-
405
- /**
406
- * List available tools from an MCP server
407
- */
408
- export async function listMcpServerTools(
409
- request: FastifyRequest,
410
- reply: FastifyReply
411
- ): Promise<ListToolsResponse> {
412
- const tenantId = getTenantId(request);
413
- const { key } = request.params as { key: string };
414
-
415
- try {
416
- const storeLattice = getStoreLattice("default", "mcp");
417
- const store: McpServerConfigStore = storeLattice.store;
418
-
419
- const config = await store.getConfigByKey(tenantId, key);
420
- if (!config) {
421
- reply.code(404);
422
- return {
423
- success: false,
424
- message: "MCP server configuration not found",
425
- };
426
- }
427
-
428
- // Ensure server is connected
429
- if (!mcpManager.hasServer(key)) {
430
- await connectAndRegisterTools(config);
431
- }
432
-
433
- const tools = await mcpManager.getServerTools(key);
434
-
435
- return {
436
- success: true,
437
- message: "Tools retrieved successfully",
438
- data: {
439
- tools,
440
- },
441
- };
442
- } catch (error) {
443
- console.error("Failed to list MCP tools:", error);
444
- return {
445
- success: false,
446
- message: "Failed to retrieve tools",
447
- };
448
- }
449
- }
450
-
451
- /**
452
- * Connect to MCP server and register tools
453
- */
454
- export async function connectMcpServer(
455
- request: FastifyRequest,
456
- reply: FastifyReply
457
- ): Promise<McpServerConfigResponse> {
458
- const tenantId = getTenantId(request);
459
- const { key } = request.params as { key: string };
460
-
461
- try {
462
- const storeLattice = getStoreLattice("default", "mcp");
463
- const store: McpServerConfigStore = storeLattice.store;
464
-
465
- const config = await store.getConfigByKey(tenantId, key);
466
- if (!config) {
467
- reply.code(404);
468
- return {
469
- success: false,
470
- message: "MCP server configuration not found",
471
- };
472
- }
473
-
474
- await connectAndRegisterTools(config);
475
-
476
- // Update status
477
- const updated = await store.updateConfig(tenantId, config.id, {
478
- status: "connected",
479
- });
480
-
481
- return {
482
- success: true,
483
- message: "MCP server connected successfully",
484
- data: updated || config,
485
- };
486
- } catch (error) {
487
- console.error("Failed to connect MCP server:", error);
488
-
489
- // Update status to error
490
- const storeLattice = getStoreLattice("default", "mcp");
491
- const store: McpServerConfigStore = storeLattice.store;
492
- const config = await store.getConfigByKey(tenantId, key);
493
- if (config) {
494
- await store.updateConfig(tenantId, config.id, { status: "error" });
495
- }
496
-
497
- return {
498
- success: false,
499
- message: `Failed to connect MCP server: ${
500
- error instanceof Error ? error.message : "Unknown error"
501
- }`,
502
- };
503
- }
504
- }
505
-
506
- /**
507
- * Disconnect from MCP server
508
- */
509
- export async function disconnectMcpServer(
510
- request: FastifyRequest,
511
- reply: FastifyReply
512
- ): Promise<McpServerConfigResponse> {
513
- const tenantId = getTenantId(request);
514
- const { key } = request.params as { key: string };
515
-
516
- try {
517
- const storeLattice = getStoreLattice("default", "mcp");
518
- const store: McpServerConfigStore = storeLattice.store;
519
-
520
- const config = await store.getConfigByKey(tenantId, key);
521
- if (!config) {
522
- reply.code(404);
523
- return {
524
- success: false,
525
- message: "MCP server configuration not found",
526
- };
527
- }
528
-
529
- // Disconnect from MCP manager
530
- if (mcpManager.hasServer(key)) {
531
- await mcpManager.removeServer(key);
532
- }
533
-
534
- // Update status
535
- const updated = await store.updateConfig(tenantId, config.id, {
536
- status: "disconnected",
537
- });
538
-
539
- return {
540
- success: true,
541
- message: "MCP server disconnected successfully",
542
- data: updated || config,
543
- };
544
- } catch (error) {
545
- console.error("Failed to disconnect MCP server:", error);
546
- return {
547
- success: false,
548
- message: "Failed to disconnect MCP server",
549
- };
550
- }
551
- }
552
-
553
- /**
554
- * Test MCP server connection and list tools without saving config
555
- * Used for multi-step configuration flow
556
- */
557
- export async function testMcpServerTools(
558
- request: FastifyRequest,
559
- reply: FastifyReply
560
- ): Promise<ListToolsResponse> {
561
- const body = request.body as {
562
- config: McpServerConfig;
563
- };
564
-
565
- try {
566
- if (!body.config) {
567
- reply.code(400);
568
- return {
569
- success: false,
570
- message: "config is required",
571
- };
572
- }
573
-
574
- const testKey = `__test_${Date.now()}`;
575
-
576
- // Create standalone client for testing — does not affect global mcpManager
577
- const connection = convertToConnection(body.config);
578
- const { tools } = await McpLatticeManager.testConnection(testKey, connection);
579
-
580
- return {
581
- success: true,
582
- message: "Tools retrieved successfully",
583
- data: {
584
- tools,
585
- },
586
- };
587
- } catch (error) {
588
- console.error("Failed to test MCP server tools:", error);
589
- return {
590
- success: false,
591
- message: `Failed to retrieve tools: ${
592
- error instanceof Error ? error.message : String(error)
593
- }`,
594
- };
595
- }
596
- }
597
-
598
- /**
599
- * Convert McpServerConfig to Connection format compatible with @langchain/mcp-adapters
600
- */
601
- export function convertToConnection(config: McpServerConfig): any {
602
- const baseConfig = {
603
- env: config.env,
604
- };
605
-
606
- if (config.transport === "stdio") {
607
- return {
608
- ...baseConfig,
609
- transport: "stdio" as const,
610
- command: config.command!,
611
- args: config.args || [],
612
- };
613
- } else {
614
- // For HTTP/SSE transports
615
- return {
616
- ...baseConfig,
617
- transport: config.transport === "streamable_http" ? "http" : config.transport,
618
- url: config.url!,
619
- };
620
- }
621
- }
622
-
623
- /**
624
- * Helper function to connect to MCP server and register selected tools
625
- */
626
- async function connectAndRegisterTools(
627
- config: McpServerConfigEntry
628
- ): Promise<void> {
629
- // Add server to MCP manager
630
- const connection = convertToConnection(config.config);
631
- mcpManager.addServer(config.key, connection);
632
-
633
- // Connect only unconnected servers (new server gets connected)
634
- await mcpManager.connect();
635
-
636
- // Register tools for this server (handles unregister + filter + prefix)
637
- await mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
638
- }
639
-
640
- /**
641
- * Register MCP server config routes
642
- */
643
- export function registerMcpServerConfigRoutes(app: any): void {
644
- // Get all configs
645
- app.get("/api/mcp-servers", getMcpServerConfigList);
646
-
647
- // Get config by key
648
- app.get("/api/mcp-servers/:key", getMcpServerConfig);
649
-
650
- // Create config
651
- app.post("/api/mcp-servers", createMcpServerConfig);
652
-
653
- // Update config
654
- app.put("/api/mcp-servers/:key", updateMcpServerConfig);
655
-
656
- // Delete config by key or id
657
- app.delete("/api/mcp-servers/:keyOrId", deleteMcpServerConfig);
658
-
659
- // Test connection
660
- app.post("/api/mcp-servers/:key/test", testMcpServerConnection);
661
-
662
- // List available tools
663
- app.get("/api/mcp-servers/:key/tools", listMcpServerTools);
664
-
665
- // Connect to server
666
- app.post("/api/mcp-servers/:key/connect", connectMcpServer);
667
-
668
- // Disconnect from server
669
- app.post("/api/mcp-servers/:key/disconnect", disconnectMcpServer);
670
-
671
- // Test tools without saving config (for multi-step config flow)
672
- app.post("/api/mcp-servers/test-tools", testMcpServerTools);
673
- }