@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1027.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.
- package/dist/botlit/BotlitRoutes.js +142 -132
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/components/AgentApprovalPanel.js +144 -126
- package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
- package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
- package/dist/botlit/components/VersionHistoryPanel.js +92 -83
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/A2ARegistryPage.js +129 -117
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
- package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
- package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
- package/dist/botlit/pages/AgentBuilderPage.js +18 -18
- package/dist/botlit/pages/AgentDetailPage.js +298 -273
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.js +145 -121
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.js +238 -226
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotDetailPage.js +307 -288
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.js +125 -116
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.js +159 -144
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.js +279 -258
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js +346 -328
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
- package/dist/botlit/pages/ChannelsPage.js +163 -148
- package/dist/botlit/pages/ChannelsPage.js.map +1 -1
- package/dist/botlit/pages/DashboardPage.js +129 -114
- package/dist/botlit/pages/DashboardPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
- package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.js +14 -14
- package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
- package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.js +170 -155
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/PoliciesPage.js +113 -104
- package/dist/botlit/pages/PoliciesPage.js.map +1 -1
- package/dist/botlit/pages/PolicyDetailPage.js +145 -133
- package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptStudioPage.js +106 -97
- package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
- package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
- package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
- package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +264 -252
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillDetailPage.js +235 -226
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
- package/dist/botlit/pages/SkillsPage.js +115 -106
- package/dist/botlit/pages/SkillsPage.js.map +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.js +161 -155
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/dist/botlit/permissions/PermissionRequired.js +45 -0
- package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
- package/dist/botlit/permissions/botmanorPermissions.js +72 -0
- package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
- package/dist/botlit/permissions/index.js +3 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
- package/package.json +1 -1
|
@@ -2,314 +2,329 @@ import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
|
2
2
|
import { useBotlit as t } from "../providers/BotlitProvider.js";
|
|
3
3
|
import { isMCPServerHealthy as n, mcpServerDescription as r, mcpServerEndpoint as i, useCreateMCPServer as a, useDeleteMCPServer as o, useMCPServers as s, useTestMCPConnection as c } from "../hooks/useMCPServers.js";
|
|
4
4
|
import { formatRelativeTime as l } from "../utils/formatters.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
5
|
+
import { BOTMANOR_PERMISSIONS as u } from "../permissions/botmanorPermissions.js";
|
|
6
|
+
import { BotmanorPermissionGate as d } from "../permissions/useBotmanorPermissions.js";
|
|
7
|
+
import { PageLayout as f } from "../components/PageLayout.js";
|
|
8
|
+
import { Button as p } from "../components/Button.js";
|
|
9
|
+
import "../permissions/index.js";
|
|
10
|
+
import { Card as m, CardContent as h, CardDescription as g, CardHeader as _, CardTitle as v } from "../components/Card.js";
|
|
11
|
+
import { Badge as y, StatusBadge as b } from "../components/Badge.js";
|
|
12
|
+
import { EmptyState as x } from "../components/EmptyState.js";
|
|
13
|
+
import { FormField as S, Input as C } from "../components/Input.js";
|
|
14
|
+
import { ErrorState as w } from "../components/ErrorState.js";
|
|
15
|
+
import { useState as T } from "react";
|
|
16
|
+
import { GlassCard as E, PagePurpose as D } from "@burdenoff/fe-libs/ui";
|
|
17
|
+
import { jsx as O, jsxs as k } from "react/jsx-runtime";
|
|
18
|
+
import { Plug as A, PlugZap as j, Plus as M, Settings as N, Trash2 as P } from "lucide-react";
|
|
19
|
+
import { toast as F } from "sonner";
|
|
17
20
|
//#region src/botlit/pages/MCPServersPage.tsx
|
|
18
|
-
var
|
|
19
|
-
let
|
|
21
|
+
var I = () => {
|
|
22
|
+
let I = e(), { navigateTo: L } = t(), { data: R, loading: z, error: B, refetch: V } = s(), [H, U] = a(), [W, G] = o(), [K, q] = c(), [J, Y] = T(!1), [X, Z] = T({
|
|
20
23
|
name: "",
|
|
21
24
|
description: "",
|
|
22
25
|
transport: "HTTP_JSON",
|
|
23
26
|
baseUrl: ""
|
|
24
|
-
}),
|
|
25
|
-
if (!(!
|
|
27
|
+
}), Q = async () => {
|
|
28
|
+
if (!(!X.name || !X.baseUrl)) {
|
|
26
29
|
try {
|
|
27
|
-
await
|
|
28
|
-
name:
|
|
29
|
-
type:
|
|
30
|
+
await H({
|
|
31
|
+
name: X.name,
|
|
32
|
+
type: X.transport,
|
|
30
33
|
config: {
|
|
31
|
-
url:
|
|
32
|
-
description:
|
|
34
|
+
url: X.baseUrl,
|
|
35
|
+
description: X.description
|
|
33
36
|
}
|
|
34
37
|
});
|
|
35
38
|
} catch (e) {
|
|
36
|
-
|
|
39
|
+
F.error(e instanceof Error ? e.message : I("botlit.mcpServers.toast.connectError", "Failed to connect MCP server"));
|
|
37
40
|
return;
|
|
38
41
|
}
|
|
39
|
-
|
|
42
|
+
F.success(I("botlit.mcpServers.toast.connectSuccess", "Connected \"{{name}}\"", { name: X.name })), V(), Z({
|
|
40
43
|
name: "",
|
|
41
44
|
description: "",
|
|
42
45
|
transport: "HTTP_JSON",
|
|
43
46
|
baseUrl: ""
|
|
44
|
-
}),
|
|
47
|
+
}), Y(!1);
|
|
45
48
|
}
|
|
46
|
-
},
|
|
49
|
+
}, $ = async (e) => {
|
|
47
50
|
try {
|
|
48
|
-
await
|
|
51
|
+
await W(e.id), F.success(I("botlit.mcpServers.toast.disconnectSuccess", "Disconnected \"{{name}}\"", { name: e.name })), V();
|
|
49
52
|
} catch (e) {
|
|
50
|
-
|
|
53
|
+
F.error(e instanceof Error ? e.message : I("botlit.mcpServers.toast.disconnectError", "Failed to disconnect MCP server"));
|
|
51
54
|
}
|
|
52
|
-
},
|
|
55
|
+
}, ee = async (e) => {
|
|
53
56
|
try {
|
|
54
|
-
await
|
|
57
|
+
await K(e.id) ? F.success(I("botlit.mcpServers.toast.reachable", "\"{{name}}\" is reachable", { name: e.name })) : F.error(I("botlit.mcpServers.toast.unreachable", "\"{{name}}\" did not respond", { name: e.name })), V();
|
|
55
58
|
} catch (e) {
|
|
56
|
-
|
|
59
|
+
F.error(e instanceof Error ? e.message : I("botlit.mcpServers.toast.testError", "Failed to test MCP connection"));
|
|
57
60
|
}
|
|
58
61
|
};
|
|
59
|
-
return /* @__PURE__ */
|
|
60
|
-
title:
|
|
61
|
-
description:
|
|
62
|
-
actions: /* @__PURE__ */
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
return /* @__PURE__ */ O(f, {
|
|
63
|
+
title: I("botlit.mcpServers.title", "MCP Servers"),
|
|
64
|
+
description: I("botlit.mcpServers.description", "Connect Model Context Protocol servers to extend agent capabilities"),
|
|
65
|
+
actions: /* @__PURE__ */ O(d, {
|
|
66
|
+
permission: u.MCP_CREATE,
|
|
67
|
+
children: /* @__PURE__ */ O(p, {
|
|
68
|
+
leftIcon: /* @__PURE__ */ O(M, { size: 16 }),
|
|
69
|
+
onClick: () => Y(!0),
|
|
70
|
+
children: I("botlit.mcpServers.actions.add", "Add MCP Server")
|
|
71
|
+
})
|
|
66
72
|
}),
|
|
67
|
-
children: /* @__PURE__ */
|
|
73
|
+
children: /* @__PURE__ */ k("div", {
|
|
68
74
|
className: "space-y-6",
|
|
69
75
|
children: [
|
|
70
|
-
/* @__PURE__ */
|
|
71
|
-
icon: /* @__PURE__ */
|
|
72
|
-
children:
|
|
76
|
+
/* @__PURE__ */ O(D, {
|
|
77
|
+
icon: /* @__PURE__ */ O(A, { size: 18 }),
|
|
78
|
+
children: I("botlit.mcpServers.purpose", "MCP (Model Context Protocol) servers are how your agents reach the outside world — they expose real tools an agent can call, like searching the web, reading a GitHub repo, querying a database or posting to Slack. Connect a server here and its tools become available to your agents (gated by your tool policies), turning a chatbot into something that can take action.")
|
|
73
79
|
}),
|
|
74
|
-
|
|
80
|
+
z ? /* @__PURE__ */ O("div", {
|
|
75
81
|
className: "grid grid-cols-1 md:grid-cols-2 gap-4",
|
|
76
82
|
children: [
|
|
77
83
|
1,
|
|
78
84
|
2,
|
|
79
85
|
3
|
|
80
|
-
].map((e) => /* @__PURE__ */
|
|
81
|
-
}) :
|
|
86
|
+
].map((e) => /* @__PURE__ */ O("div", { className: "h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
|
|
87
|
+
}) : B ? /* @__PURE__ */ O(w, {
|
|
82
88
|
resource: "MCP servers",
|
|
83
|
-
error:
|
|
84
|
-
onRetry: () => void
|
|
85
|
-
}) :
|
|
89
|
+
error: B,
|
|
90
|
+
onRetry: () => void V()
|
|
91
|
+
}) : R.length > 0 ? /* @__PURE__ */ O("div", {
|
|
86
92
|
className: "grid grid-cols-1 md:grid-cols-2 gap-4",
|
|
87
|
-
children:
|
|
93
|
+
children: R.map((e) => /* @__PURE__ */ k(m, { children: [/* @__PURE__ */ k(_, {
|
|
88
94
|
className: "flex flex-row items-start justify-between",
|
|
89
|
-
children: [/* @__PURE__ */
|
|
95
|
+
children: [/* @__PURE__ */ k("div", {
|
|
90
96
|
className: "flex items-start gap-3",
|
|
91
|
-
children: [/* @__PURE__ */
|
|
97
|
+
children: [/* @__PURE__ */ O("div", {
|
|
92
98
|
className: `p-2 rounded-lg ${n(e.status) ? "bg-status-success-bg-subtle" : "bg-bg-sunken"}`,
|
|
93
|
-
children: n(e.status) ? /* @__PURE__ */
|
|
94
|
-
}), /* @__PURE__ */
|
|
99
|
+
children: n(e.status) ? /* @__PURE__ */ O(j, { className: "h-5 w-5 text-status-success-text" }) : /* @__PURE__ */ O(A, { className: "h-5 w-5 text-text-secondary" })
|
|
100
|
+
}), /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O(v, {
|
|
95
101
|
className: "text-base",
|
|
96
102
|
children: e.name
|
|
97
|
-
}), /* @__PURE__ */
|
|
98
|
-
}), /* @__PURE__ */
|
|
99
|
-
}), /* @__PURE__ */
|
|
103
|
+
}), /* @__PURE__ */ O(g, { children: r(e) })] })]
|
|
104
|
+
}), /* @__PURE__ */ O(b, { status: e.status })]
|
|
105
|
+
}), /* @__PURE__ */ O(h, { children: /* @__PURE__ */ k("div", {
|
|
100
106
|
className: "space-y-4",
|
|
101
107
|
children: [
|
|
102
|
-
/* @__PURE__ */
|
|
108
|
+
/* @__PURE__ */ k("div", {
|
|
103
109
|
className: "flex flex-wrap items-center gap-4 text-sm",
|
|
104
|
-
children: [/* @__PURE__ */
|
|
110
|
+
children: [/* @__PURE__ */ O(y, {
|
|
105
111
|
variant: "outline",
|
|
106
112
|
className: "capitalize",
|
|
107
113
|
children: e.type.toLowerCase().replace("_", " ")
|
|
108
|
-
}), e.lastConnectedAt && /* @__PURE__ */
|
|
114
|
+
}), e.lastConnectedAt && /* @__PURE__ */ k("span", {
|
|
109
115
|
className: "text-text-secondary",
|
|
110
116
|
children: [
|
|
111
|
-
|
|
117
|
+
I("botlit.botsList.createdLabel", "Created"),
|
|
112
118
|
" ",
|
|
113
119
|
l(e.lastConnectedAt)
|
|
114
120
|
]
|
|
115
121
|
})]
|
|
116
122
|
}),
|
|
117
|
-
i(e) && /* @__PURE__ */
|
|
123
|
+
i(e) && /* @__PURE__ */ O("p", {
|
|
118
124
|
className: "truncate text-sm text-text-secondary",
|
|
119
125
|
children: i(e)
|
|
120
126
|
}),
|
|
121
|
-
e.errorMessage && /* @__PURE__ */
|
|
127
|
+
e.errorMessage && /* @__PURE__ */ O("p", {
|
|
122
128
|
className: "text-sm text-status-error-text",
|
|
123
129
|
children: e.errorMessage
|
|
124
130
|
}),
|
|
125
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ k("div", {
|
|
126
132
|
className: "flex items-center gap-2 pt-2 border-t border-border-subtle",
|
|
127
133
|
children: [
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
/* @__PURE__ */ O(d, {
|
|
135
|
+
permission: u.MCP_TEST,
|
|
136
|
+
children: /* @__PURE__ */ O(p, {
|
|
137
|
+
variant: "outline",
|
|
138
|
+
size: "sm",
|
|
139
|
+
onClick: () => void ee(e),
|
|
140
|
+
isLoading: q.loading,
|
|
141
|
+
children: I("botlit.mcpServers.actions.testConnection", "Test connection")
|
|
142
|
+
})
|
|
134
143
|
}),
|
|
135
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ O(p, {
|
|
136
145
|
variant: "ghost",
|
|
137
146
|
size: "sm",
|
|
138
|
-
leftIcon: /* @__PURE__ */
|
|
139
|
-
onClick: () =>
|
|
140
|
-
children:
|
|
147
|
+
leftIcon: /* @__PURE__ */ O(N, { size: 14 }),
|
|
148
|
+
onClick: () => L(`mcp/${e.id}`),
|
|
149
|
+
children: I("botlit.mcpServers.actions.configure", "Configure")
|
|
141
150
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
151
|
+
/* @__PURE__ */ O(d, {
|
|
152
|
+
permission: u.MCP_DELETE,
|
|
153
|
+
children: /* @__PURE__ */ O(p, {
|
|
154
|
+
variant: "ghost",
|
|
155
|
+
size: "icon",
|
|
156
|
+
className: "ml-auto",
|
|
157
|
+
"aria-label": `Disconnect ${e.name}`,
|
|
158
|
+
onClick: () => void $(e),
|
|
159
|
+
isLoading: G.loading,
|
|
160
|
+
children: /* @__PURE__ */ O(P, { size: 16 })
|
|
161
|
+
})
|
|
150
162
|
})
|
|
151
163
|
]
|
|
152
164
|
})
|
|
153
165
|
]
|
|
154
166
|
}) })] }, e.id))
|
|
155
|
-
}) : /* @__PURE__ */
|
|
167
|
+
}) : /* @__PURE__ */ O(x, {
|
|
156
168
|
illustration: "empty-generic",
|
|
157
|
-
title:
|
|
158
|
-
description:
|
|
159
|
-
action: /* @__PURE__ */
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
title: I("botlit.mcpServers.empty.title", "No MCP servers connected"),
|
|
170
|
+
description: I("botlit.mcpServers.empty.description", "Connect MCP servers to give your agents access to external tools and resources."),
|
|
171
|
+
action: /* @__PURE__ */ O(d, {
|
|
172
|
+
permission: u.MCP_CREATE,
|
|
173
|
+
children: /* @__PURE__ */ O(p, {
|
|
174
|
+
leftIcon: /* @__PURE__ */ O(M, { size: 16 }),
|
|
175
|
+
onClick: () => Y(!0),
|
|
176
|
+
children: I("botlit.mcpServers.actions.add", "Add MCP Server")
|
|
177
|
+
})
|
|
163
178
|
})
|
|
164
179
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
180
|
+
/* @__PURE__ */ k(E, {
|
|
166
181
|
treatment: "glass",
|
|
167
182
|
glow: !0,
|
|
168
183
|
className: "p-6",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
184
|
+
children: [/* @__PURE__ */ k("div", {
|
|
170
185
|
className: "mb-4",
|
|
171
|
-
children: [/* @__PURE__ */
|
|
186
|
+
children: [/* @__PURE__ */ O("h2", {
|
|
172
187
|
className: "text-lg font-semibold tracking-tight text-text-primary",
|
|
173
|
-
children:
|
|
174
|
-
}), /* @__PURE__ */
|
|
188
|
+
children: I("botlit.mcpServers.presets.title", "Popular MCP Servers")
|
|
189
|
+
}), /* @__PURE__ */ O("p", {
|
|
175
190
|
className: "text-sm text-text-secondary",
|
|
176
|
-
children:
|
|
191
|
+
children: I("botlit.mcpServers.presets.description", "Quick-add common MCP servers")
|
|
177
192
|
})]
|
|
178
|
-
}), /* @__PURE__ */
|
|
193
|
+
}), /* @__PURE__ */ O("div", {
|
|
179
194
|
className: "grid grid-cols-1 md:grid-cols-3 gap-4",
|
|
180
195
|
children: [
|
|
181
196
|
{
|
|
182
|
-
name:
|
|
183
|
-
description:
|
|
197
|
+
name: I("botlit.mcpServers.presets.github", "GitHub"),
|
|
198
|
+
description: I("botlit.mcpServers.presets.githubDesc", "Repository management and code operations"),
|
|
184
199
|
baseUrl: "https://mcp.github.com"
|
|
185
200
|
},
|
|
186
201
|
{
|
|
187
|
-
name:
|
|
188
|
-
description:
|
|
202
|
+
name: I("botlit.mcpServers.presets.filesystem", "Filesystem"),
|
|
203
|
+
description: I("botlit.mcpServers.presets.filesystemDesc", "Local file system access"),
|
|
189
204
|
baseUrl: "http://localhost:3001"
|
|
190
205
|
},
|
|
191
206
|
{
|
|
192
|
-
name:
|
|
193
|
-
description:
|
|
207
|
+
name: I("botlit.mcpServers.presets.braveSearch", "Brave Search"),
|
|
208
|
+
description: I("botlit.mcpServers.presets.braveSearchDesc", "Web search capabilities"),
|
|
194
209
|
baseUrl: "https://mcp.search.brave.com"
|
|
195
210
|
},
|
|
196
211
|
{
|
|
197
|
-
name:
|
|
198
|
-
description:
|
|
212
|
+
name: I("botlit.mcpServers.presets.postgres", "PostgreSQL"),
|
|
213
|
+
description: I("botlit.mcpServers.presets.postgresDesc", "Database queries and management"),
|
|
199
214
|
baseUrl: "http://localhost:3002"
|
|
200
215
|
},
|
|
201
216
|
{
|
|
202
|
-
name:
|
|
203
|
-
description:
|
|
217
|
+
name: I("botlit.mcpServers.presets.slack", "Slack"),
|
|
218
|
+
description: I("botlit.mcpServers.presets.slackDesc", "Slack messaging integration"),
|
|
204
219
|
baseUrl: "https://mcp.slack.com"
|
|
205
220
|
},
|
|
206
221
|
{
|
|
207
|
-
name:
|
|
208
|
-
description:
|
|
222
|
+
name: I("botlit.mcpServers.presets.puppeteer", "Puppeteer"),
|
|
223
|
+
description: I("botlit.mcpServers.presets.puppeteerDesc", "Browser automation"),
|
|
209
224
|
baseUrl: "http://localhost:3003"
|
|
210
225
|
}
|
|
211
|
-
].map((e) => /* @__PURE__ */
|
|
226
|
+
].map((e) => /* @__PURE__ */ k("button", {
|
|
212
227
|
className: "p-4 text-left border border-border-subtle rounded-lg hover:bg-accent transition-colors",
|
|
213
228
|
onClick: () => {
|
|
214
|
-
|
|
229
|
+
Z({
|
|
215
230
|
name: e.name,
|
|
216
231
|
description: e.description,
|
|
217
232
|
transport: "HTTP_JSON",
|
|
218
233
|
baseUrl: e.baseUrl
|
|
219
|
-
}),
|
|
234
|
+
}), Y(!0);
|
|
220
235
|
},
|
|
221
|
-
children: [/* @__PURE__ */
|
|
236
|
+
children: [/* @__PURE__ */ O("p", {
|
|
222
237
|
className: "font-medium",
|
|
223
238
|
children: e.name
|
|
224
|
-
}), /* @__PURE__ */
|
|
239
|
+
}), /* @__PURE__ */ O("p", {
|
|
225
240
|
className: "text-sm text-text-secondary mt-1",
|
|
226
241
|
children: e.description
|
|
227
242
|
})]
|
|
228
243
|
}, e.name))
|
|
229
244
|
})]
|
|
230
245
|
}),
|
|
231
|
-
|
|
246
|
+
J && /* @__PURE__ */ O("div", {
|
|
232
247
|
className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50",
|
|
233
|
-
children: /* @__PURE__ */
|
|
248
|
+
children: /* @__PURE__ */ k(m, {
|
|
234
249
|
className: "w-full max-w-lg",
|
|
235
|
-
children: [/* @__PURE__ */
|
|
250
|
+
children: [/* @__PURE__ */ k(_, { children: [/* @__PURE__ */ O(v, { children: I("botlit.mcpServers.form.title", "Add MCP Server") }), /* @__PURE__ */ O(g, { children: I("botlit.mcpServers.form.description", "Connect a new MCP server") })] }), /* @__PURE__ */ k(h, {
|
|
236
251
|
className: "space-y-4",
|
|
237
252
|
children: [
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
label:
|
|
253
|
+
/* @__PURE__ */ O(S, {
|
|
254
|
+
label: I("botlit.mcpServers.form.nameLabel", "Server Name"),
|
|
240
255
|
required: !0,
|
|
241
|
-
children: /* @__PURE__ */
|
|
242
|
-
placeholder:
|
|
243
|
-
value:
|
|
244
|
-
onChange: (e) =>
|
|
245
|
-
...
|
|
256
|
+
children: /* @__PURE__ */ O(C, {
|
|
257
|
+
placeholder: I("botlit.mcpServers.form.namePlaceholder", "e.g., GitHub"),
|
|
258
|
+
value: X.name,
|
|
259
|
+
onChange: (e) => Z({
|
|
260
|
+
...X,
|
|
246
261
|
name: e.target.value
|
|
247
262
|
})
|
|
248
263
|
})
|
|
249
264
|
}),
|
|
250
|
-
/* @__PURE__ */
|
|
251
|
-
label:
|
|
252
|
-
children: /* @__PURE__ */
|
|
253
|
-
placeholder:
|
|
254
|
-
value:
|
|
255
|
-
onChange: (e) =>
|
|
256
|
-
...
|
|
265
|
+
/* @__PURE__ */ O(S, {
|
|
266
|
+
label: I("botlit.mcpServers.form.descriptionLabel", "Description"),
|
|
267
|
+
children: /* @__PURE__ */ O(C, {
|
|
268
|
+
placeholder: I("botlit.mcpServers.form.descriptionPlaceholder", "What does this server do?"),
|
|
269
|
+
value: X.description,
|
|
270
|
+
onChange: (e) => Z({
|
|
271
|
+
...X,
|
|
257
272
|
description: e.target.value
|
|
258
273
|
})
|
|
259
274
|
})
|
|
260
275
|
}),
|
|
261
|
-
/* @__PURE__ */
|
|
262
|
-
label:
|
|
263
|
-
children: /* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ O(S, {
|
|
277
|
+
label: I("botlit.mcpServers.form.transportLabel", "Transport"),
|
|
278
|
+
children: /* @__PURE__ */ k("select", {
|
|
264
279
|
className: "flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm",
|
|
265
|
-
value:
|
|
266
|
-
onChange: (e) =>
|
|
267
|
-
...
|
|
280
|
+
value: X.transport,
|
|
281
|
+
onChange: (e) => Z({
|
|
282
|
+
...X,
|
|
268
283
|
transport: e.target.value
|
|
269
284
|
}),
|
|
270
285
|
children: [
|
|
271
|
-
/* @__PURE__ */
|
|
286
|
+
/* @__PURE__ */ O("option", {
|
|
272
287
|
value: "HTTP_JSON",
|
|
273
288
|
children: "HTTP JSON"
|
|
274
289
|
}),
|
|
275
|
-
/* @__PURE__ */
|
|
290
|
+
/* @__PURE__ */ O("option", {
|
|
276
291
|
value: "JSON_RPC",
|
|
277
292
|
children: "JSON RPC"
|
|
278
293
|
}),
|
|
279
|
-
/* @__PURE__ */
|
|
294
|
+
/* @__PURE__ */ O("option", {
|
|
280
295
|
value: "SSE",
|
|
281
296
|
children: "Server-Sent Events"
|
|
282
297
|
}),
|
|
283
|
-
/* @__PURE__ */
|
|
298
|
+
/* @__PURE__ */ O("option", {
|
|
284
299
|
value: "CUSTOM",
|
|
285
300
|
children: "Custom"
|
|
286
301
|
})
|
|
287
302
|
]
|
|
288
303
|
})
|
|
289
304
|
}),
|
|
290
|
-
/* @__PURE__ */
|
|
291
|
-
label:
|
|
305
|
+
/* @__PURE__ */ O(S, {
|
|
306
|
+
label: I("botlit.mcpServers.form.baseUrlLabel", "Base URL"),
|
|
292
307
|
required: !0,
|
|
293
|
-
children: /* @__PURE__ */
|
|
294
|
-
placeholder:
|
|
295
|
-
value:
|
|
296
|
-
onChange: (e) =>
|
|
297
|
-
...
|
|
308
|
+
children: /* @__PURE__ */ O(C, {
|
|
309
|
+
placeholder: I("botlit.mcpServers.form.baseUrlPlaceholder", "e.g., https://mcp.example.com"),
|
|
310
|
+
value: X.baseUrl,
|
|
311
|
+
onChange: (e) => Z({
|
|
312
|
+
...X,
|
|
298
313
|
baseUrl: e.target.value
|
|
299
314
|
})
|
|
300
315
|
})
|
|
301
316
|
}),
|
|
302
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ k("div", {
|
|
303
318
|
className: "flex justify-end gap-2 pt-4",
|
|
304
|
-
children: [/* @__PURE__ */
|
|
319
|
+
children: [/* @__PURE__ */ O(p, {
|
|
305
320
|
variant: "outline",
|
|
306
|
-
onClick: () =>
|
|
307
|
-
children:
|
|
308
|
-
}), /* @__PURE__ */
|
|
309
|
-
onClick:
|
|
310
|
-
isLoading:
|
|
311
|
-
disabled: !
|
|
312
|
-
children:
|
|
321
|
+
onClick: () => Y(!1),
|
|
322
|
+
children: I("botlit.mcpServers.actions.cancel", "Cancel")
|
|
323
|
+
}), /* @__PURE__ */ O(p, {
|
|
324
|
+
onClick: Q,
|
|
325
|
+
isLoading: U.loading,
|
|
326
|
+
disabled: !X.name || !X.baseUrl,
|
|
327
|
+
children: I("botlit.mcpServers.actions.connect", "Connect")
|
|
313
328
|
})]
|
|
314
329
|
})
|
|
315
330
|
]
|
|
@@ -321,6 +336,6 @@ var P = () => {
|
|
|
321
336
|
});
|
|
322
337
|
};
|
|
323
338
|
//#endregion
|
|
324
|
-
export {
|
|
339
|
+
export { I as MCPServersPage };
|
|
325
340
|
|
|
326
341
|
//# sourceMappingURL=MCPServersPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPServersPage.js","names":[],"sources":["../../../src/botlit/pages/MCPServersPage.tsx"],"sourcesContent":["/**\n * MCP Servers Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Plus, Plug, PlugZap, Settings, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, FormField } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useMCPServers,\n useCreateMCPServer,\n useDeleteMCPServer,\n useTestMCPConnection,\n isMCPServerHealthy,\n mcpServerDescription,\n mcpServerEndpoint,\n type MCPServerRecord,\n} from '../hooks/useMCPServers';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { MCPTransport } from '../types';\n\nexport const MCPServersPage: FC = () => {\n const t = useTr();\n const { navigateTo } = useBotlit();\n const { data: servers, loading, error, refetch } = useMCPServers();\n const [connectServer, connectResult] = useCreateMCPServer();\n const [deleteServer, deleteResult] = useDeleteMCPServer();\n const [testConnection, testResult] = useTestMCPConnection();\n const [showAddModal, setShowAddModal] = useState(false);\n const [newServer, setNewServer] = useState({\n name: '',\n description: '',\n transport: 'HTTP_JSON' as MCPTransport,\n baseUrl: '',\n });\n\n const handleConnect = async () => {\n if (!newServer.name || !newServer.baseUrl) return;\n\n try {\n await connectServer({\n name: newServer.name,\n type: newServer.transport,\n config: {\n url: newServer.baseUrl,\n description: newServer.description,\n },\n });\n } catch (err) {\n // Keep the dialog open so the operator can correct and retry — closing it\n // here is what made failed writes look like successes.\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.connectError', 'Failed to connect MCP server')\n );\n return;\n }\n\n toast.success(\n t('botlit.mcpServers.toast.connectSuccess', 'Connected \"{{name}}\"', {\n name: newServer.name,\n })\n );\n void refetch();\n setNewServer({ name: '', description: '', transport: 'HTTP_JSON', baseUrl: '' });\n setShowAddModal(false);\n };\n\n const handleDisconnect = async (server: MCPServerRecord) => {\n try {\n await deleteServer(server.id);\n toast.success(\n t('botlit.mcpServers.toast.disconnectSuccess', 'Disconnected \"{{name}}\"', {\n name: server.name,\n })\n );\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.disconnectError', 'Failed to disconnect MCP server')\n );\n }\n };\n\n const handleTest = async (server: MCPServerRecord) => {\n try {\n const ok = await testConnection(server.id);\n if (ok) {\n toast.success(\n t('botlit.mcpServers.toast.reachable', '\"{{name}}\" is reachable', {\n name: server.name,\n })\n );\n } else {\n toast.error(\n t('botlit.mcpServers.toast.unreachable', '\"{{name}}\" did not respond', {\n name: server.name,\n })\n );\n }\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.testError', 'Failed to test MCP connection')\n );\n }\n };\n\n return (\n <PageLayout\n title={t('botlit.mcpServers.title', 'MCP Servers')}\n description={t(\n 'botlit.mcpServers.description',\n 'Connect Model Context Protocol servers to extend agent capabilities'\n )}\n actions={\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Plug size={18} />}>\n {t(\n 'botlit.mcpServers.purpose',\n 'MCP (Model Context Protocol) servers are how your agents reach the outside world — they expose real tools an agent can call, like searching the web, reading a GitHub repo, querying a database or posting to Slack. Connect a server here and its tools become available to your agents (gated by your tool policies), turning a chatbot into something that can take action.'\n )}\n </PagePurpose>\n\n {/* Server List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"MCP servers\" error={error} onRetry={() => void refetch()} />\n ) : servers.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {servers.map((server: MCPServerRecord) => (\n <Card key={server.id}>\n <CardHeader className=\"flex flex-row items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div\n className={`p-2 rounded-lg ${\n isMCPServerHealthy(server.status)\n ? 'bg-status-success-bg-subtle'\n : 'bg-bg-sunken'\n }`}\n >\n {isMCPServerHealthy(server.status) ? (\n <PlugZap className=\"h-5 w-5 text-status-success-text\" />\n ) : (\n <Plug className=\"h-5 w-5 text-text-secondary\" />\n )}\n </div>\n <div>\n <CardTitle className=\"text-base\">{server.name}</CardTitle>\n <CardDescription>{mcpServerDescription(server)}</CardDescription>\n </div>\n </div>\n <StatusBadge status={server.status} />\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {/* Transport Info */}\n <div className=\"flex flex-wrap items-center gap-4 text-sm\">\n <Badge variant=\"outline\" className=\"capitalize\">\n {server.type.toLowerCase().replace('_', ' ')}\n </Badge>\n {server.lastConnectedAt && (\n <span className=\"text-text-secondary\">\n {t('botlit.botsList.createdLabel', 'Created')}{' '}\n {formatRelativeTime(server.lastConnectedAt)}\n </span>\n )}\n </div>\n\n {/* Endpoint */}\n {mcpServerEndpoint(server) && (\n <p className=\"truncate text-sm text-text-secondary\">\n {mcpServerEndpoint(server)}\n </p>\n )}\n\n {server.errorMessage && (\n <p className=\"text-sm text-status-error-text\">{server.errorMessage}</p>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleTest(server)}\n isLoading={testResult.loading}\n >\n {t('botlit.mcpServers.actions.testConnection', 'Test connection')}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n leftIcon={<Settings size={14} />}\n onClick={() => navigateTo(`mcp/${server.id}`)}\n >\n {t('botlit.mcpServers.actions.configure', 'Configure')}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"ml-auto\"\n aria-label={`Disconnect ${server.name}`}\n onClick={() => void handleDisconnect(server)}\n isLoading={deleteResult.loading}\n >\n <Trash2 size={16} />\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={t('botlit.mcpServers.empty.title', 'No MCP servers connected')}\n description={t(\n 'botlit.mcpServers.empty.description',\n 'Connect MCP servers to give your agents access to external tools and resources.'\n )}\n action={\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n }\n />\n )}\n\n {/* Available MCP Servers */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.mcpServers.presets.title', 'Popular MCP Servers')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.mcpServers.presets.description', 'Quick-add common MCP servers')}\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {[\n {\n name: t('botlit.mcpServers.presets.github', 'GitHub'),\n description: t(\n 'botlit.mcpServers.presets.githubDesc',\n 'Repository management and code operations'\n ),\n baseUrl: 'https://mcp.github.com',\n },\n {\n name: t('botlit.mcpServers.presets.filesystem', 'Filesystem'),\n description: t(\n 'botlit.mcpServers.presets.filesystemDesc',\n 'Local file system access'\n ),\n baseUrl: 'http://localhost:3001',\n },\n {\n name: t('botlit.mcpServers.presets.braveSearch', 'Brave Search'),\n description: t(\n 'botlit.mcpServers.presets.braveSearchDesc',\n 'Web search capabilities'\n ),\n baseUrl: 'https://mcp.search.brave.com',\n },\n {\n name: t('botlit.mcpServers.presets.postgres', 'PostgreSQL'),\n description: t(\n 'botlit.mcpServers.presets.postgresDesc',\n 'Database queries and management'\n ),\n baseUrl: 'http://localhost:3002',\n },\n {\n name: t('botlit.mcpServers.presets.slack', 'Slack'),\n description: t(\n 'botlit.mcpServers.presets.slackDesc',\n 'Slack messaging integration'\n ),\n baseUrl: 'https://mcp.slack.com',\n },\n {\n name: t('botlit.mcpServers.presets.puppeteer', 'Puppeteer'),\n description: t('botlit.mcpServers.presets.puppeteerDesc', 'Browser automation'),\n baseUrl: 'http://localhost:3003',\n },\n ].map((preset) => (\n <button\n key={preset.name}\n className=\"p-4 text-left border border-border-subtle rounded-lg hover:bg-accent transition-colors\"\n onClick={() => {\n setNewServer({\n name: preset.name,\n description: preset.description,\n transport: 'HTTP_JSON',\n baseUrl: preset.baseUrl,\n });\n setShowAddModal(true);\n }}\n >\n <p className=\"font-medium\">{preset.name}</p>\n <p className=\"text-sm text-text-secondary mt-1\">{preset.description}</p>\n </button>\n ))}\n </div>\n </GlassCard>\n\n {/* Add Server Modal */}\n {showAddModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-lg\">\n <CardHeader>\n <CardTitle>{t('botlit.mcpServers.form.title', 'Add MCP Server')}</CardTitle>\n <CardDescription>\n {t('botlit.mcpServers.form.description', 'Connect a new MCP server')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label={t('botlit.mcpServers.form.nameLabel', 'Server Name')} required>\n <Input\n placeholder={t('botlit.mcpServers.form.namePlaceholder', 'e.g., GitHub')}\n value={newServer.name}\n onChange={(e) => setNewServer({ ...newServer, name: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.descriptionLabel', 'Description')}>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.descriptionPlaceholder',\n 'What does this server do?'\n )}\n value={newServer.description}\n onChange={(e) => setNewServer({ ...newServer, description: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.transportLabel', 'Transport')}>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={newServer.transport}\n onChange={(e) =>\n setNewServer({ ...newServer, transport: e.target.value as MCPTransport })\n }\n >\n <option value=\"HTTP_JSON\">HTTP JSON</option>\n <option value=\"JSON_RPC\">JSON RPC</option>\n <option value=\"SSE\">Server-Sent Events</option>\n <option value=\"CUSTOM\">Custom</option>\n </select>\n </FormField>\n <FormField label={t('botlit.mcpServers.form.baseUrlLabel', 'Base URL')} required>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.baseUrlPlaceholder',\n 'e.g., https://mcp.example.com'\n )}\n value={newServer.baseUrl}\n onChange={(e) => setNewServer({ ...newServer, baseUrl: e.target.value })}\n />\n </FormField>\n <div className=\"flex justify-end gap-2 pt-4\">\n <Button variant=\"outline\" onClick={() => setShowAddModal(false)}>\n {t('botlit.mcpServers.actions.cancel', 'Cancel')}\n </Button>\n <Button\n onClick={handleConnect}\n isLoading={connectResult.loading}\n disabled={!newServer.name || !newServer.baseUrl}\n >\n {t('botlit.mcpServers.actions.connect', 'Connect')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MCPServersPage.js","names":[],"sources":["../../../src/botlit/pages/MCPServersPage.tsx"],"sourcesContent":["/**\n * MCP Servers Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Plus, Plug, PlugZap, Settings, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, FormField } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useMCPServers,\n useCreateMCPServer,\n useDeleteMCPServer,\n useTestMCPConnection,\n isMCPServerHealthy,\n mcpServerDescription,\n mcpServerEndpoint,\n type MCPServerRecord,\n} from '../hooks/useMCPServers';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { MCPTransport } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nexport const MCPServersPage: FC = () => {\n const t = useTr();\n const { navigateTo } = useBotlit();\n const { data: servers, loading, error, refetch } = useMCPServers();\n const [connectServer, connectResult] = useCreateMCPServer();\n const [deleteServer, deleteResult] = useDeleteMCPServer();\n const [testConnection, testResult] = useTestMCPConnection();\n const [showAddModal, setShowAddModal] = useState(false);\n const [newServer, setNewServer] = useState({\n name: '',\n description: '',\n transport: 'HTTP_JSON' as MCPTransport,\n baseUrl: '',\n });\n\n const handleConnect = async () => {\n if (!newServer.name || !newServer.baseUrl) return;\n\n try {\n await connectServer({\n name: newServer.name,\n type: newServer.transport,\n config: {\n url: newServer.baseUrl,\n description: newServer.description,\n },\n });\n } catch (err) {\n // Keep the dialog open so the operator can correct and retry — closing it\n // here is what made failed writes look like successes.\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.connectError', 'Failed to connect MCP server')\n );\n return;\n }\n\n toast.success(\n t('botlit.mcpServers.toast.connectSuccess', 'Connected \"{{name}}\"', {\n name: newServer.name,\n })\n );\n void refetch();\n setNewServer({ name: '', description: '', transport: 'HTTP_JSON', baseUrl: '' });\n setShowAddModal(false);\n };\n\n const handleDisconnect = async (server: MCPServerRecord) => {\n try {\n await deleteServer(server.id);\n toast.success(\n t('botlit.mcpServers.toast.disconnectSuccess', 'Disconnected \"{{name}}\"', {\n name: server.name,\n })\n );\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.disconnectError', 'Failed to disconnect MCP server')\n );\n }\n };\n\n const handleTest = async (server: MCPServerRecord) => {\n try {\n const ok = await testConnection(server.id);\n if (ok) {\n toast.success(\n t('botlit.mcpServers.toast.reachable', '\"{{name}}\" is reachable', {\n name: server.name,\n })\n );\n } else {\n toast.error(\n t('botlit.mcpServers.toast.unreachable', '\"{{name}}\" did not respond', {\n name: server.name,\n })\n );\n }\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.testError', 'Failed to test MCP connection')\n );\n }\n };\n\n return (\n <PageLayout\n title={t('botlit.mcpServers.title', 'MCP Servers')}\n description={t(\n 'botlit.mcpServers.description',\n 'Connect Model Context Protocol servers to extend agent capabilities'\n )}\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Plug size={18} />}>\n {t(\n 'botlit.mcpServers.purpose',\n 'MCP (Model Context Protocol) servers are how your agents reach the outside world — they expose real tools an agent can call, like searching the web, reading a GitHub repo, querying a database or posting to Slack. Connect a server here and its tools become available to your agents (gated by your tool policies), turning a chatbot into something that can take action.'\n )}\n </PagePurpose>\n\n {/* Server List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"MCP servers\" error={error} onRetry={() => void refetch()} />\n ) : servers.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {servers.map((server: MCPServerRecord) => (\n <Card key={server.id}>\n <CardHeader className=\"flex flex-row items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div\n className={`p-2 rounded-lg ${\n isMCPServerHealthy(server.status)\n ? 'bg-status-success-bg-subtle'\n : 'bg-bg-sunken'\n }`}\n >\n {isMCPServerHealthy(server.status) ? (\n <PlugZap className=\"h-5 w-5 text-status-success-text\" />\n ) : (\n <Plug className=\"h-5 w-5 text-text-secondary\" />\n )}\n </div>\n <div>\n <CardTitle className=\"text-base\">{server.name}</CardTitle>\n <CardDescription>{mcpServerDescription(server)}</CardDescription>\n </div>\n </div>\n <StatusBadge status={server.status} />\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {/* Transport Info */}\n <div className=\"flex flex-wrap items-center gap-4 text-sm\">\n <Badge variant=\"outline\" className=\"capitalize\">\n {server.type.toLowerCase().replace('_', ' ')}\n </Badge>\n {server.lastConnectedAt && (\n <span className=\"text-text-secondary\">\n {t('botlit.botsList.createdLabel', 'Created')}{' '}\n {formatRelativeTime(server.lastConnectedAt)}\n </span>\n )}\n </div>\n\n {/* Endpoint */}\n {mcpServerEndpoint(server) && (\n <p className=\"truncate text-sm text-text-secondary\">\n {mcpServerEndpoint(server)}\n </p>\n )}\n\n {server.errorMessage && (\n <p className=\"text-sm text-status-error-text\">{server.errorMessage}</p>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_TEST}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleTest(server)}\n isLoading={testResult.loading}\n >\n {t('botlit.mcpServers.actions.testConnection', 'Test connection')}\n </Button>\n </BotmanorPermissionGate>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n leftIcon={<Settings size={14} />}\n onClick={() => navigateTo(`mcp/${server.id}`)}\n >\n {t('botlit.mcpServers.actions.configure', 'Configure')}\n </Button>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_DELETE}>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"ml-auto\"\n aria-label={`Disconnect ${server.name}`}\n onClick={() => void handleDisconnect(server)}\n isLoading={deleteResult.loading}\n >\n <Trash2 size={16} />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={t('botlit.mcpServers.empty.title', 'No MCP servers connected')}\n description={t(\n 'botlit.mcpServers.empty.description',\n 'Connect MCP servers to give your agents access to external tools and resources.'\n )}\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n\n {/* Available MCP Servers */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.mcpServers.presets.title', 'Popular MCP Servers')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.mcpServers.presets.description', 'Quick-add common MCP servers')}\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {[\n {\n name: t('botlit.mcpServers.presets.github', 'GitHub'),\n description: t(\n 'botlit.mcpServers.presets.githubDesc',\n 'Repository management and code operations'\n ),\n baseUrl: 'https://mcp.github.com',\n },\n {\n name: t('botlit.mcpServers.presets.filesystem', 'Filesystem'),\n description: t(\n 'botlit.mcpServers.presets.filesystemDesc',\n 'Local file system access'\n ),\n baseUrl: 'http://localhost:3001',\n },\n {\n name: t('botlit.mcpServers.presets.braveSearch', 'Brave Search'),\n description: t(\n 'botlit.mcpServers.presets.braveSearchDesc',\n 'Web search capabilities'\n ),\n baseUrl: 'https://mcp.search.brave.com',\n },\n {\n name: t('botlit.mcpServers.presets.postgres', 'PostgreSQL'),\n description: t(\n 'botlit.mcpServers.presets.postgresDesc',\n 'Database queries and management'\n ),\n baseUrl: 'http://localhost:3002',\n },\n {\n name: t('botlit.mcpServers.presets.slack', 'Slack'),\n description: t(\n 'botlit.mcpServers.presets.slackDesc',\n 'Slack messaging integration'\n ),\n baseUrl: 'https://mcp.slack.com',\n },\n {\n name: t('botlit.mcpServers.presets.puppeteer', 'Puppeteer'),\n description: t('botlit.mcpServers.presets.puppeteerDesc', 'Browser automation'),\n baseUrl: 'http://localhost:3003',\n },\n ].map((preset) => (\n <button\n key={preset.name}\n className=\"p-4 text-left border border-border-subtle rounded-lg hover:bg-accent transition-colors\"\n onClick={() => {\n setNewServer({\n name: preset.name,\n description: preset.description,\n transport: 'HTTP_JSON',\n baseUrl: preset.baseUrl,\n });\n setShowAddModal(true);\n }}\n >\n <p className=\"font-medium\">{preset.name}</p>\n <p className=\"text-sm text-text-secondary mt-1\">{preset.description}</p>\n </button>\n ))}\n </div>\n </GlassCard>\n\n {/* Add Server Modal */}\n {showAddModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-lg\">\n <CardHeader>\n <CardTitle>{t('botlit.mcpServers.form.title', 'Add MCP Server')}</CardTitle>\n <CardDescription>\n {t('botlit.mcpServers.form.description', 'Connect a new MCP server')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label={t('botlit.mcpServers.form.nameLabel', 'Server Name')} required>\n <Input\n placeholder={t('botlit.mcpServers.form.namePlaceholder', 'e.g., GitHub')}\n value={newServer.name}\n onChange={(e) => setNewServer({ ...newServer, name: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.descriptionLabel', 'Description')}>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.descriptionPlaceholder',\n 'What does this server do?'\n )}\n value={newServer.description}\n onChange={(e) => setNewServer({ ...newServer, description: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.transportLabel', 'Transport')}>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={newServer.transport}\n onChange={(e) =>\n setNewServer({ ...newServer, transport: e.target.value as MCPTransport })\n }\n >\n <option value=\"HTTP_JSON\">HTTP JSON</option>\n <option value=\"JSON_RPC\">JSON RPC</option>\n <option value=\"SSE\">Server-Sent Events</option>\n <option value=\"CUSTOM\">Custom</option>\n </select>\n </FormField>\n <FormField label={t('botlit.mcpServers.form.baseUrlLabel', 'Base URL')} required>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.baseUrlPlaceholder',\n 'e.g., https://mcp.example.com'\n )}\n value={newServer.baseUrl}\n onChange={(e) => setNewServer({ ...newServer, baseUrl: e.target.value })}\n />\n </FormField>\n <div className=\"flex justify-end gap-2 pt-4\">\n <Button variant=\"outline\" onClick={() => setShowAddModal(false)}>\n {t('botlit.mcpServers.actions.cancel', 'Cancel')}\n </Button>\n <Button\n onClick={handleConnect}\n isLoading={connectResult.loading}\n disabled={!newServer.name || !newServer.baseUrl}\n >\n {t('botlit.mcpServers.actions.connect', 'Connect')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|