@axiom-lattice/gateway 2.1.34 → 2.1.36
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/.turbo/turbo-build.log +8 -12
- package/CHANGELOG.md +16 -0
- package/dist/index.js +603 -252
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +510 -53
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/controllers/mcp-configs.ts +691 -0
- package/src/routes/index.ts +3 -0
- package/src/services/agent_service.ts +0 -53
- package/dist/chunk-FSASG3SB.mjs +0 -94
- package/dist/chunk-FSASG3SB.mjs.map +0 -1
- package/dist/config-F3FCBSPH.mjs +0 -9
- package/dist/config-F3FCBSPH.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
configService
|
|
3
|
-
} from "./chunk-FSASG3SB.mjs";
|
|
4
|
-
|
|
5
1
|
// src/index.ts
|
|
6
2
|
import fastify from "fastify";
|
|
7
3
|
import cors from "@fastify/cors";
|
|
@@ -24,31 +20,6 @@ import {
|
|
|
24
20
|
getChunkBuffer,
|
|
25
21
|
hasChunkBuffer
|
|
26
22
|
} from "@axiom-lattice/core";
|
|
27
|
-
async function fetchDatabaseConfigs(baseURL, apiKey, tenantId) {
|
|
28
|
-
try {
|
|
29
|
-
const headers = {};
|
|
30
|
-
if (apiKey) {
|
|
31
|
-
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
32
|
-
}
|
|
33
|
-
if (tenantId) {
|
|
34
|
-
headers["x-tenant-id"] = tenantId;
|
|
35
|
-
}
|
|
36
|
-
const response = await fetch(`${baseURL}/api/database-configs`, { headers });
|
|
37
|
-
if (response.ok) {
|
|
38
|
-
const data = await response.json();
|
|
39
|
-
if (data.success && data.data && Array.isArray(data.data.records)) {
|
|
40
|
-
return data.data.records.map((record) => ({
|
|
41
|
-
key: record.key,
|
|
42
|
-
name: record.name,
|
|
43
|
-
description: record.description
|
|
44
|
-
}));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.error("Failed to fetch database configs:", error);
|
|
49
|
-
}
|
|
50
|
-
return [];
|
|
51
|
-
}
|
|
52
23
|
function getOrCreateChunkBuffer() {
|
|
53
24
|
if (!hasChunkBuffer("default")) {
|
|
54
25
|
const buffer = new InMemoryChunkBuffer({
|
|
@@ -80,14 +51,6 @@ async function agent_invoke({
|
|
|
80
51
|
if (!runnable_agent) {
|
|
81
52
|
throw new Error(`Agent ${assistant_id} not found`);
|
|
82
53
|
}
|
|
83
|
-
const { configService: configService2 } = await import("./config-F3FCBSPH.mjs");
|
|
84
|
-
const gatewayConfig = configService2.getConfig();
|
|
85
|
-
const databaseConfigs = await fetchDatabaseConfigs(
|
|
86
|
-
gatewayConfig.baseURL || "http://localhost:4001",
|
|
87
|
-
void 0,
|
|
88
|
-
tenant_id
|
|
89
|
-
);
|
|
90
|
-
global.__DATABASE_CONFIGS__ = databaseConfigs;
|
|
91
54
|
const runConfig = {
|
|
92
55
|
...agentLattice?.config?.runConfig || {},
|
|
93
56
|
workspaceId: workspace_id,
|
|
@@ -141,14 +104,6 @@ async function agent_stream({
|
|
|
141
104
|
messages = [humanMessage];
|
|
142
105
|
}
|
|
143
106
|
const chunkBuffer = getOrCreateChunkBuffer();
|
|
144
|
-
const { configService: configService2 } = await import("./config-F3FCBSPH.mjs");
|
|
145
|
-
const gatewayConfig = configService2.getConfig();
|
|
146
|
-
const databaseConfigs = await fetchDatabaseConfigs(
|
|
147
|
-
gatewayConfig.baseURL || "http://localhost:4001",
|
|
148
|
-
void 0,
|
|
149
|
-
tenant_id
|
|
150
|
-
);
|
|
151
|
-
global.__DATABASE_CONFIGS__ = databaseConfigs;
|
|
152
107
|
const runConfig = {
|
|
153
108
|
...agentLattice?.config?.runConfig || {},
|
|
154
109
|
workspaceId: workspace_id,
|
|
@@ -1087,6 +1042,78 @@ async function resumeScheduledTask(request, reply) {
|
|
|
1087
1042
|
}
|
|
1088
1043
|
}
|
|
1089
1044
|
|
|
1045
|
+
// src/config.ts
|
|
1046
|
+
var ConfigService = class {
|
|
1047
|
+
constructor() {
|
|
1048
|
+
this.config = this.loadFromEnv();
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Load configuration from environment variables
|
|
1052
|
+
*/
|
|
1053
|
+
loadFromEnv() {
|
|
1054
|
+
return {
|
|
1055
|
+
port: process.env.PORT ? Number(process.env.PORT) : void 0,
|
|
1056
|
+
queueServiceType: process.env.QUEUE_SERVICE_TYPE,
|
|
1057
|
+
redisUrl: process.env.REDIS_URL,
|
|
1058
|
+
redisPassword: process.env.REDIS_PASSWORD,
|
|
1059
|
+
queueName: process.env.QUEUE_NAME
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Update configuration from JSON object
|
|
1064
|
+
* This will update both the internal config and process.env
|
|
1065
|
+
*/
|
|
1066
|
+
updateConfig(jsonConfig) {
|
|
1067
|
+
for (const [key, value] of Object.entries(jsonConfig)) {
|
|
1068
|
+
if (value !== null && value !== void 0) {
|
|
1069
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
1070
|
+
for (const [nestedKey, nestedValue] of Object.entries(value)) {
|
|
1071
|
+
const envKey = `${key.toUpperCase()}_${nestedKey.toUpperCase()}`;
|
|
1072
|
+
process.env[envKey] = String(nestedValue);
|
|
1073
|
+
}
|
|
1074
|
+
} else {
|
|
1075
|
+
process.env[key.toUpperCase()] = String(value);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
this.config = this.loadFromEnv();
|
|
1080
|
+
this.config = this.deepMerge(this.config, jsonConfig);
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Deep merge two objects
|
|
1084
|
+
*/
|
|
1085
|
+
deepMerge(target, source) {
|
|
1086
|
+
const output = { ...target };
|
|
1087
|
+
if (this.isObject(target) && this.isObject(source)) {
|
|
1088
|
+
Object.keys(source).forEach((key) => {
|
|
1089
|
+
if (this.isObject(source[key])) {
|
|
1090
|
+
if (!(key in target)) {
|
|
1091
|
+
Object.assign(output, { [key]: source[key] });
|
|
1092
|
+
} else {
|
|
1093
|
+
output[key] = this.deepMerge(target[key], source[key]);
|
|
1094
|
+
}
|
|
1095
|
+
} else {
|
|
1096
|
+
Object.assign(output, { [key]: source[key] });
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
return output;
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Check if value is a plain object
|
|
1104
|
+
*/
|
|
1105
|
+
isObject(item) {
|
|
1106
|
+
return item && typeof item === "object" && !Array.isArray(item);
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Get current configuration
|
|
1110
|
+
*/
|
|
1111
|
+
getConfig() {
|
|
1112
|
+
return { ...this.config };
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
var configService = new ConfigService();
|
|
1116
|
+
|
|
1090
1117
|
// src/services/queue_service.ts
|
|
1091
1118
|
import {
|
|
1092
1119
|
queueLatticeManager,
|
|
@@ -3544,12 +3571,441 @@ function registerMetricsServerConfigRoutes(app2) {
|
|
|
3544
3571
|
app2.post("/api/metrics-configs/test-datasources/:datasourceId/meta", testDatasourceMetrics);
|
|
3545
3572
|
}
|
|
3546
3573
|
|
|
3574
|
+
// src/controllers/mcp-configs.ts
|
|
3575
|
+
import {
|
|
3576
|
+
getStoreLattice as getStoreLattice8,
|
|
3577
|
+
mcpManager,
|
|
3578
|
+
toolLatticeManager as toolLatticeManager2
|
|
3579
|
+
} from "@axiom-lattice/core";
|
|
3580
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
3581
|
+
function getTenantId3(request) {
|
|
3582
|
+
return request.headers["x-tenant-id"] || "default";
|
|
3583
|
+
}
|
|
3584
|
+
async function getMcpServerConfigList(request, reply) {
|
|
3585
|
+
const tenantId = getTenantId3(request);
|
|
3586
|
+
try {
|
|
3587
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3588
|
+
const store = storeLattice.store;
|
|
3589
|
+
const configs = await store.getAllConfigs(tenantId);
|
|
3590
|
+
return {
|
|
3591
|
+
success: true,
|
|
3592
|
+
message: "MCP server configurations retrieved successfully",
|
|
3593
|
+
data: {
|
|
3594
|
+
records: configs,
|
|
3595
|
+
total: configs.length
|
|
3596
|
+
}
|
|
3597
|
+
};
|
|
3598
|
+
} catch (error) {
|
|
3599
|
+
console.error("Failed to get MCP server configs:", error);
|
|
3600
|
+
return {
|
|
3601
|
+
success: false,
|
|
3602
|
+
message: "Failed to retrieve MCP server configurations",
|
|
3603
|
+
data: {
|
|
3604
|
+
records: [],
|
|
3605
|
+
total: 0
|
|
3606
|
+
}
|
|
3607
|
+
};
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
async function getMcpServerConfig(request, reply) {
|
|
3611
|
+
const tenantId = getTenantId3(request);
|
|
3612
|
+
const { key } = request.params;
|
|
3613
|
+
try {
|
|
3614
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3615
|
+
const store = storeLattice.store;
|
|
3616
|
+
const config = await store.getConfigByKey(tenantId, key);
|
|
3617
|
+
if (!config) {
|
|
3618
|
+
return {
|
|
3619
|
+
success: false,
|
|
3620
|
+
message: "MCP server configuration not found"
|
|
3621
|
+
};
|
|
3622
|
+
}
|
|
3623
|
+
return {
|
|
3624
|
+
success: true,
|
|
3625
|
+
message: "MCP server configuration retrieved successfully",
|
|
3626
|
+
data: config
|
|
3627
|
+
};
|
|
3628
|
+
} catch (error) {
|
|
3629
|
+
console.error("Failed to get MCP server config:", error);
|
|
3630
|
+
return {
|
|
3631
|
+
success: false,
|
|
3632
|
+
message: "Failed to retrieve MCP server configuration"
|
|
3633
|
+
};
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
async function createMcpServerConfig(request, reply) {
|
|
3637
|
+
const tenantId = getTenantId3(request);
|
|
3638
|
+
const body = request.body;
|
|
3639
|
+
try {
|
|
3640
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3641
|
+
const store = storeLattice.store;
|
|
3642
|
+
const existing = await store.getConfigByKey(tenantId, body.key);
|
|
3643
|
+
if (existing) {
|
|
3644
|
+
reply.code(409);
|
|
3645
|
+
return {
|
|
3646
|
+
success: false,
|
|
3647
|
+
message: "MCP server configuration with this key already exists"
|
|
3648
|
+
};
|
|
3649
|
+
}
|
|
3650
|
+
const id = body.id || randomUUID5();
|
|
3651
|
+
const config = await store.createConfig(tenantId, id, body);
|
|
3652
|
+
try {
|
|
3653
|
+
await connectAndRegisterTools(config);
|
|
3654
|
+
await store.updateConfig(tenantId, id, { status: "connected" });
|
|
3655
|
+
config.status = "connected";
|
|
3656
|
+
} catch (error) {
|
|
3657
|
+
console.warn("Failed to auto-connect MCP server:", error);
|
|
3658
|
+
await store.updateConfig(tenantId, id, { status: "error" });
|
|
3659
|
+
config.status = "error";
|
|
3660
|
+
}
|
|
3661
|
+
reply.code(201);
|
|
3662
|
+
return {
|
|
3663
|
+
success: true,
|
|
3664
|
+
message: "MCP server configuration created successfully",
|
|
3665
|
+
data: config
|
|
3666
|
+
};
|
|
3667
|
+
} catch (error) {
|
|
3668
|
+
console.error("Failed to create MCP server config:", error);
|
|
3669
|
+
return {
|
|
3670
|
+
success: false,
|
|
3671
|
+
message: "Failed to create MCP server configuration"
|
|
3672
|
+
};
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
async function updateMcpServerConfig(request, reply) {
|
|
3676
|
+
const tenantId = getTenantId3(request);
|
|
3677
|
+
const { key } = request.params;
|
|
3678
|
+
const updates = request.body;
|
|
3679
|
+
try {
|
|
3680
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3681
|
+
const store = storeLattice.store;
|
|
3682
|
+
const existing = await store.getConfigByKey(tenantId, key);
|
|
3683
|
+
if (!existing) {
|
|
3684
|
+
reply.code(404);
|
|
3685
|
+
return {
|
|
3686
|
+
success: false,
|
|
3687
|
+
message: "MCP server configuration not found"
|
|
3688
|
+
};
|
|
3689
|
+
}
|
|
3690
|
+
const shouldReconnect = updates.config !== void 0;
|
|
3691
|
+
const updated = await store.updateConfig(tenantId, existing.id, updates);
|
|
3692
|
+
if (!updated) {
|
|
3693
|
+
return {
|
|
3694
|
+
success: false,
|
|
3695
|
+
message: "Failed to update MCP server configuration"
|
|
3696
|
+
};
|
|
3697
|
+
}
|
|
3698
|
+
if (shouldReconnect) {
|
|
3699
|
+
try {
|
|
3700
|
+
if (mcpManager.hasServer(key)) {
|
|
3701
|
+
await mcpManager.removeServer(key);
|
|
3702
|
+
}
|
|
3703
|
+
await connectAndRegisterTools(updated);
|
|
3704
|
+
await store.updateConfig(tenantId, existing.id, { status: "connected" });
|
|
3705
|
+
updated.status = "connected";
|
|
3706
|
+
} catch (error) {
|
|
3707
|
+
console.warn("Failed to reconnect MCP server:", error);
|
|
3708
|
+
await store.updateConfig(tenantId, existing.id, { status: "error" });
|
|
3709
|
+
updated.status = "error";
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
return {
|
|
3713
|
+
success: true,
|
|
3714
|
+
message: "MCP server configuration updated successfully",
|
|
3715
|
+
data: updated
|
|
3716
|
+
};
|
|
3717
|
+
} catch (error) {
|
|
3718
|
+
console.error("Failed to update MCP server config:", error);
|
|
3719
|
+
return {
|
|
3720
|
+
success: false,
|
|
3721
|
+
message: "Failed to update MCP server configuration"
|
|
3722
|
+
};
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
async function deleteMcpServerConfig(request, reply) {
|
|
3726
|
+
const tenantId = getTenantId3(request);
|
|
3727
|
+
const { keyOrId } = request.params;
|
|
3728
|
+
try {
|
|
3729
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3730
|
+
const store = storeLattice.store;
|
|
3731
|
+
let config = await store.getConfigByKey(tenantId, keyOrId);
|
|
3732
|
+
let configKey = keyOrId;
|
|
3733
|
+
if (!config) {
|
|
3734
|
+
config = await store.getConfigById(tenantId, keyOrId);
|
|
3735
|
+
if (config) {
|
|
3736
|
+
configKey = config.key;
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
if (!config) {
|
|
3740
|
+
reply.code(404);
|
|
3741
|
+
return {
|
|
3742
|
+
success: false,
|
|
3743
|
+
message: "MCP server configuration not found"
|
|
3744
|
+
};
|
|
3745
|
+
}
|
|
3746
|
+
try {
|
|
3747
|
+
if (mcpManager.hasServer(configKey)) {
|
|
3748
|
+
await mcpManager.removeServer(configKey);
|
|
3749
|
+
}
|
|
3750
|
+
} catch (error) {
|
|
3751
|
+
console.warn("Failed to remove from MCP manager:", error);
|
|
3752
|
+
}
|
|
3753
|
+
const deleted = await store.deleteConfig(tenantId, config.id);
|
|
3754
|
+
if (!deleted) {
|
|
3755
|
+
return {
|
|
3756
|
+
success: false,
|
|
3757
|
+
message: "Failed to delete MCP server configuration"
|
|
3758
|
+
};
|
|
3759
|
+
}
|
|
3760
|
+
return {
|
|
3761
|
+
success: true,
|
|
3762
|
+
message: "MCP server configuration deleted successfully"
|
|
3763
|
+
};
|
|
3764
|
+
} catch (error) {
|
|
3765
|
+
console.error("Failed to delete MCP server config:", error);
|
|
3766
|
+
return {
|
|
3767
|
+
success: false,
|
|
3768
|
+
message: "Failed to delete MCP server configuration"
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
async function testMcpServerConnection(request, reply) {
|
|
3773
|
+
const tenantId = getTenantId3(request);
|
|
3774
|
+
const { key } = request.params;
|
|
3775
|
+
try {
|
|
3776
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3777
|
+
const store = storeLattice.store;
|
|
3778
|
+
const config = await store.getConfigByKey(tenantId, key);
|
|
3779
|
+
if (!config) {
|
|
3780
|
+
reply.code(404);
|
|
3781
|
+
return {
|
|
3782
|
+
success: false,
|
|
3783
|
+
message: "MCP server configuration not found"
|
|
3784
|
+
};
|
|
3785
|
+
}
|
|
3786
|
+
const startTime = Date.now();
|
|
3787
|
+
try {
|
|
3788
|
+
const testKey = `__test_${key}_${Date.now()}`;
|
|
3789
|
+
const connection = convertToConnection(config.config);
|
|
3790
|
+
mcpManager.addServer(testKey, connection);
|
|
3791
|
+
await mcpManager.connect();
|
|
3792
|
+
const tools = await mcpManager.getAllTools();
|
|
3793
|
+
const latency = Date.now() - startTime;
|
|
3794
|
+
await mcpManager.removeServer(testKey);
|
|
3795
|
+
return {
|
|
3796
|
+
success: true,
|
|
3797
|
+
message: "Connection test successful",
|
|
3798
|
+
data: {
|
|
3799
|
+
connected: true,
|
|
3800
|
+
latency
|
|
3801
|
+
}
|
|
3802
|
+
};
|
|
3803
|
+
} catch (error) {
|
|
3804
|
+
return {
|
|
3805
|
+
success: true,
|
|
3806
|
+
message: "Connection test failed",
|
|
3807
|
+
data: {
|
|
3808
|
+
connected: false,
|
|
3809
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
3810
|
+
}
|
|
3811
|
+
};
|
|
3812
|
+
}
|
|
3813
|
+
} catch (error) {
|
|
3814
|
+
console.error("Failed to test MCP server connection:", error);
|
|
3815
|
+
return {
|
|
3816
|
+
success: false,
|
|
3817
|
+
message: "Failed to test MCP server connection",
|
|
3818
|
+
data: {
|
|
3819
|
+
connected: false,
|
|
3820
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
3821
|
+
}
|
|
3822
|
+
};
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
async function listMcpServerTools(request, reply) {
|
|
3826
|
+
const tenantId = getTenantId3(request);
|
|
3827
|
+
const { key } = request.params;
|
|
3828
|
+
try {
|
|
3829
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3830
|
+
const store = storeLattice.store;
|
|
3831
|
+
const config = await store.getConfigByKey(tenantId, key);
|
|
3832
|
+
if (!config) {
|
|
3833
|
+
reply.code(404);
|
|
3834
|
+
return {
|
|
3835
|
+
success: false,
|
|
3836
|
+
message: "MCP server configuration not found"
|
|
3837
|
+
};
|
|
3838
|
+
}
|
|
3839
|
+
if (!mcpManager.hasServer(key)) {
|
|
3840
|
+
await connectAndRegisterTools(config);
|
|
3841
|
+
}
|
|
3842
|
+
const tools = await mcpManager.getAllTools();
|
|
3843
|
+
return {
|
|
3844
|
+
success: true,
|
|
3845
|
+
message: "Tools retrieved successfully",
|
|
3846
|
+
data: {
|
|
3847
|
+
tools
|
|
3848
|
+
}
|
|
3849
|
+
};
|
|
3850
|
+
} catch (error) {
|
|
3851
|
+
console.error("Failed to list MCP tools:", error);
|
|
3852
|
+
return {
|
|
3853
|
+
success: false,
|
|
3854
|
+
message: "Failed to retrieve tools"
|
|
3855
|
+
};
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
async function connectMcpServer(request, reply) {
|
|
3859
|
+
const tenantId = getTenantId3(request);
|
|
3860
|
+
const { key } = request.params;
|
|
3861
|
+
try {
|
|
3862
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3863
|
+
const store = storeLattice.store;
|
|
3864
|
+
const config = await store.getConfigByKey(tenantId, key);
|
|
3865
|
+
if (!config) {
|
|
3866
|
+
reply.code(404);
|
|
3867
|
+
return {
|
|
3868
|
+
success: false,
|
|
3869
|
+
message: "MCP server configuration not found"
|
|
3870
|
+
};
|
|
3871
|
+
}
|
|
3872
|
+
await connectAndRegisterTools(config);
|
|
3873
|
+
const updated = await store.updateConfig(tenantId, config.id, {
|
|
3874
|
+
status: "connected"
|
|
3875
|
+
});
|
|
3876
|
+
return {
|
|
3877
|
+
success: true,
|
|
3878
|
+
message: "MCP server connected successfully",
|
|
3879
|
+
data: updated || config
|
|
3880
|
+
};
|
|
3881
|
+
} catch (error) {
|
|
3882
|
+
console.error("Failed to connect MCP server:", error);
|
|
3883
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3884
|
+
const store = storeLattice.store;
|
|
3885
|
+
const config = await store.getConfigByKey(tenantId, key);
|
|
3886
|
+
if (config) {
|
|
3887
|
+
await store.updateConfig(tenantId, config.id, { status: "error" });
|
|
3888
|
+
}
|
|
3889
|
+
return {
|
|
3890
|
+
success: false,
|
|
3891
|
+
message: `Failed to connect MCP server: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3892
|
+
};
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
async function disconnectMcpServer(request, reply) {
|
|
3896
|
+
const tenantId = getTenantId3(request);
|
|
3897
|
+
const { key } = request.params;
|
|
3898
|
+
try {
|
|
3899
|
+
const storeLattice = getStoreLattice8("default", "mcp");
|
|
3900
|
+
const store = storeLattice.store;
|
|
3901
|
+
const config = await store.getConfigByKey(tenantId, key);
|
|
3902
|
+
if (!config) {
|
|
3903
|
+
reply.code(404);
|
|
3904
|
+
return {
|
|
3905
|
+
success: false,
|
|
3906
|
+
message: "MCP server configuration not found"
|
|
3907
|
+
};
|
|
3908
|
+
}
|
|
3909
|
+
if (mcpManager.hasServer(key)) {
|
|
3910
|
+
await mcpManager.removeServer(key);
|
|
3911
|
+
}
|
|
3912
|
+
const updated = await store.updateConfig(tenantId, config.id, {
|
|
3913
|
+
status: "disconnected"
|
|
3914
|
+
});
|
|
3915
|
+
return {
|
|
3916
|
+
success: true,
|
|
3917
|
+
message: "MCP server disconnected successfully",
|
|
3918
|
+
data: updated || config
|
|
3919
|
+
};
|
|
3920
|
+
} catch (error) {
|
|
3921
|
+
console.error("Failed to disconnect MCP server:", error);
|
|
3922
|
+
return {
|
|
3923
|
+
success: false,
|
|
3924
|
+
message: "Failed to disconnect MCP server"
|
|
3925
|
+
};
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
async function testMcpServerTools(request, reply) {
|
|
3929
|
+
const body = request.body;
|
|
3930
|
+
try {
|
|
3931
|
+
if (!body.config) {
|
|
3932
|
+
reply.code(400);
|
|
3933
|
+
return {
|
|
3934
|
+
success: false,
|
|
3935
|
+
message: "config is required"
|
|
3936
|
+
};
|
|
3937
|
+
}
|
|
3938
|
+
const testKey = `__test_${Date.now()}`;
|
|
3939
|
+
const connection = convertToConnection(body.config);
|
|
3940
|
+
mcpManager.addServer(testKey, connection);
|
|
3941
|
+
await mcpManager.connect();
|
|
3942
|
+
const tools = await mcpManager.getAllTools();
|
|
3943
|
+
await mcpManager.removeServer(testKey);
|
|
3944
|
+
return {
|
|
3945
|
+
success: true,
|
|
3946
|
+
message: "Tools retrieved successfully",
|
|
3947
|
+
data: {
|
|
3948
|
+
tools
|
|
3949
|
+
}
|
|
3950
|
+
};
|
|
3951
|
+
} catch (error) {
|
|
3952
|
+
console.error("Failed to test MCP server tools:", error);
|
|
3953
|
+
return {
|
|
3954
|
+
success: false,
|
|
3955
|
+
message: `Failed to retrieve tools: ${error instanceof Error ? error.message : String(error)}`
|
|
3956
|
+
};
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
function convertToConnection(config) {
|
|
3960
|
+
const baseConfig = {
|
|
3961
|
+
env: config.env
|
|
3962
|
+
};
|
|
3963
|
+
if (config.transport === "stdio") {
|
|
3964
|
+
return {
|
|
3965
|
+
...baseConfig,
|
|
3966
|
+
transport: "stdio",
|
|
3967
|
+
command: config.command,
|
|
3968
|
+
args: config.args || []
|
|
3969
|
+
};
|
|
3970
|
+
} else {
|
|
3971
|
+
return {
|
|
3972
|
+
...baseConfig,
|
|
3973
|
+
transport: config.transport === "streamable_http" ? "http" : config.transport,
|
|
3974
|
+
url: config.url
|
|
3975
|
+
};
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
async function connectAndRegisterTools(config) {
|
|
3979
|
+
const connection = convertToConnection(config.config);
|
|
3980
|
+
mcpManager.addServer(config.key, connection);
|
|
3981
|
+
await mcpManager.connect();
|
|
3982
|
+
const allTools = await mcpManager.getAllTools();
|
|
3983
|
+
const selectedTools = allTools.filter(
|
|
3984
|
+
(tool) => config.selectedTools.includes(tool.name)
|
|
3985
|
+
);
|
|
3986
|
+
for (const tool of selectedTools) {
|
|
3987
|
+
toolLatticeManager2.registerExistingTool(tool.name, tool);
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
function registerMcpServerConfigRoutes(app2) {
|
|
3991
|
+
app2.get("/api/mcp-servers", getMcpServerConfigList);
|
|
3992
|
+
app2.get("/api/mcp-servers/:key", getMcpServerConfig);
|
|
3993
|
+
app2.post("/api/mcp-servers", createMcpServerConfig);
|
|
3994
|
+
app2.put("/api/mcp-servers/:key", updateMcpServerConfig);
|
|
3995
|
+
app2.delete("/api/mcp-servers/:keyOrId", deleteMcpServerConfig);
|
|
3996
|
+
app2.post("/api/mcp-servers/:key/test", testMcpServerConnection);
|
|
3997
|
+
app2.get("/api/mcp-servers/:key/tools", listMcpServerTools);
|
|
3998
|
+
app2.post("/api/mcp-servers/:key/connect", connectMcpServer);
|
|
3999
|
+
app2.post("/api/mcp-servers/:key/disconnect", disconnectMcpServer);
|
|
4000
|
+
app2.post("/api/mcp-servers/test-tools", testMcpServerTools);
|
|
4001
|
+
}
|
|
4002
|
+
|
|
3547
4003
|
// src/controllers/users.ts
|
|
3548
|
-
import { getStoreLattice as
|
|
4004
|
+
import { getStoreLattice as getStoreLattice9 } from "@axiom-lattice/core";
|
|
3549
4005
|
import { v4 as uuidv42 } from "uuid";
|
|
3550
4006
|
var UsersController = class {
|
|
3551
4007
|
constructor() {
|
|
3552
|
-
this.userStore =
|
|
4008
|
+
this.userStore = getStoreLattice9("default", "user").store;
|
|
3553
4009
|
}
|
|
3554
4010
|
async listUsers(request, reply) {
|
|
3555
4011
|
const { email } = request.query;
|
|
@@ -3627,11 +4083,11 @@ function registerUserRoutes(app2) {
|
|
|
3627
4083
|
}
|
|
3628
4084
|
|
|
3629
4085
|
// src/controllers/tenants.ts
|
|
3630
|
-
import { getStoreLattice as
|
|
4086
|
+
import { getStoreLattice as getStoreLattice10 } from "@axiom-lattice/core";
|
|
3631
4087
|
import { v4 as uuidv43 } from "uuid";
|
|
3632
4088
|
var TenantsController = class {
|
|
3633
4089
|
constructor() {
|
|
3634
|
-
this.tenantStore =
|
|
4090
|
+
this.tenantStore = getStoreLattice10("default", "tenant").store;
|
|
3635
4091
|
}
|
|
3636
4092
|
// ==================== Tenant CRUD ====================
|
|
3637
4093
|
async listTenants(request, reply) {
|
|
@@ -3695,7 +4151,7 @@ function registerTenantRoutes(app2) {
|
|
|
3695
4151
|
}
|
|
3696
4152
|
|
|
3697
4153
|
// src/controllers/auth.ts
|
|
3698
|
-
import { getStoreLattice as
|
|
4154
|
+
import { getStoreLattice as getStoreLattice11 } from "@axiom-lattice/core";
|
|
3699
4155
|
import { v4 as uuidv44 } from "uuid";
|
|
3700
4156
|
var defaultAuthConfig = {
|
|
3701
4157
|
autoApproveUsers: true,
|
|
@@ -3704,9 +4160,9 @@ var defaultAuthConfig = {
|
|
|
3704
4160
|
};
|
|
3705
4161
|
var AuthController = class {
|
|
3706
4162
|
constructor(config = {}) {
|
|
3707
|
-
this.userStore =
|
|
3708
|
-
this.tenantStore =
|
|
3709
|
-
this.userTenantLinkStore =
|
|
4163
|
+
this.userStore = getStoreLattice11("default", "user").store;
|
|
4164
|
+
this.tenantStore = getStoreLattice11("default", "tenant").store;
|
|
4165
|
+
this.userTenantLinkStore = getStoreLattice11("default", "userTenantLink").store;
|
|
3710
4166
|
this.config = { ...defaultAuthConfig, ...config };
|
|
3711
4167
|
}
|
|
3712
4168
|
async register(request, reply) {
|
|
@@ -4143,6 +4599,7 @@ var registerLatticeRoutes = (app2) => {
|
|
|
4143
4599
|
registerWorkspaceRoutes(app2);
|
|
4144
4600
|
registerDatabaseConfigRoutes(app2);
|
|
4145
4601
|
registerMetricsServerConfigRoutes(app2);
|
|
4602
|
+
registerMcpServerConfigRoutes(app2);
|
|
4146
4603
|
registerUserRoutes(app2);
|
|
4147
4604
|
registerTenantRoutes(app2);
|
|
4148
4605
|
registerAuthRoutes(app2, {
|