apteva 0.4.32 → 0.4.44
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/ActivityPage.c48n83h2.js +3 -0
- package/dist/ApiDocsPage.yzcxx5ax.js +4 -0
- package/dist/App.09yb8t0b.js +1 -0
- package/dist/App.152mbs1r.js +4 -0
- package/dist/App.3a67nx9w.js +4 -0
- package/dist/App.9epx6785.js +4 -0
- package/dist/App.d8955awp.js +4 -0
- package/dist/App.drwb57jq.js +4 -0
- package/dist/App.gssbmajb.js +4 -0
- package/dist/App.qw70pc29.js +53 -0
- package/dist/App.qzbx5wtj.js +4 -0
- package/dist/App.r5serxkt.js +8 -0
- package/dist/App.tpmp9020.js +20 -0
- package/dist/App.v2wb4d7d.js +61 -0
- package/dist/App.vxmaaj0m.js +13 -0
- package/dist/App.w4p2tda9.js +4 -0
- package/dist/App.wv2ng55q.js +221 -0
- package/dist/App.yncnrn0f.js +4 -0
- package/dist/ConnectionsPage.k6cspyqq.js +3 -0
- package/dist/McpPage.cdxm48xj.js +3 -0
- package/dist/SettingsPage.evpv7c2y.js +3 -0
- package/dist/SkillsPage.pvzp6c1a.js +3 -0
- package/dist/TasksPage.6jnvbpsy.js +3 -0
- package/dist/TelemetryPage.t7vk24zc.js +3 -0
- package/dist/TestsPage.5x6658aa.js +3 -0
- package/dist/ThreadsPage.3fvhtevh.js +3 -0
- package/dist/apteva-kit.css +1 -1
- package/dist/index.html +1 -1
- package/dist/styles.css +1 -1
- package/package.json +10 -9
- package/src/crypto.ts +4 -3
- package/src/db.ts +171 -36
- package/src/integrations/agentdojo.ts +95 -12
- package/src/integrations/index.ts +7 -0
- package/src/mcp-platform.ts +870 -142
- package/src/openapi.ts +96 -0
- package/src/providers.ts +60 -34
- package/src/routes/api/agent-utils.ts +59 -47
- package/src/routes/api/agents.ts +71 -2
- package/src/routes/api/integrations.ts +11 -5
- package/src/routes/api/mcp.ts +5 -4
- package/src/routes/api/meta-agent.ts +37 -1
- package/src/routes/api/projects.ts +3 -3
- package/src/routes/api/providers.ts +121 -30
- package/src/routes/api/skills.ts +2 -3
- package/src/routes/api/system.ts +98 -14
- package/src/routes/api/telemetry.ts +19 -1
- package/src/routes/share.ts +85 -0
- package/src/server.ts +43 -32
- package/src/triggers/agentdojo.ts +2 -2
- package/src/web/App.tsx +107 -21
- package/src/web/components/activity/ActivityPage.tsx +242 -389
- package/src/web/components/agents/AgentCard.tsx +19 -27
- package/src/web/components/agents/AgentPanel.tsx +358 -198
- package/src/web/components/agents/AgentsView.tsx +4 -4
- package/src/web/components/agents/CreateAgentModal.tsx +21 -79
- package/src/web/components/api/ApiDocsPage.tsx +66 -66
- package/src/web/components/auth/CreateAccountStep.tsx +16 -16
- package/src/web/components/auth/LoginPage.tsx +10 -10
- package/src/web/components/common/Icons.tsx +8 -0
- package/src/web/components/common/LoadingSpinner.tsx +2 -2
- package/src/web/components/common/Modal.tsx +8 -8
- package/src/web/components/common/Select.tsx +11 -10
- package/src/web/components/connections/ConnectionsPage.tsx +4 -4
- package/src/web/components/connections/IntegrationsTab.tsx +18 -18
- package/src/web/components/connections/OverviewTab.tsx +13 -13
- package/src/web/components/connections/TriggersTab.tsx +99 -99
- package/src/web/components/dashboard/Dashboard.tsx +177 -52
- package/src/web/components/index.ts +1 -1
- package/src/web/components/layout/Header.tsx +50 -34
- package/src/web/components/layout/Sidebar.tsx +41 -16
- package/src/web/components/mcp/IntegrationsPanel.tsx +160 -69
- package/src/web/components/mcp/McpPage.tsx +218 -209
- package/src/web/components/meta-agent/MetaAgent.tsx +15 -11
- package/src/web/components/onboarding/OnboardingWizard.tsx +25 -25
- package/src/web/components/settings/SettingsPage.tsx +389 -221
- package/src/web/components/skills/SkillsPage.tsx +88 -88
- package/src/web/components/tasks/TasksPage.tsx +385 -68
- package/src/web/components/telemetry/TelemetryPage.tsx +294 -39
- package/src/web/components/tests/TestsPage.tsx +50 -50
- package/src/web/components/threads/ThreadsPage.tsx +315 -0
- package/src/web/context/AuthContext.tsx +3 -3
- package/src/web/context/ProjectContext.tsx +8 -3
- package/src/web/context/TelemetryContext.tsx +24 -6
- package/src/web/context/ThemeContext.tsx +69 -0
- package/src/web/context/index.ts +3 -1
- package/src/web/styles.css +25 -7
- package/src/web/themes.ts +99 -0
- package/src/web/types.ts +4 -7
- package/dist/ActivityPage.41nbye4r.js +0 -3
- package/dist/ApiDocsPage.4smnt8m3.js +0 -4
- package/dist/App.0sbax9et.js +0 -4
- package/dist/App.0ws427h8.js +0 -4
- package/dist/App.6q6bar8b.js +0 -4
- package/dist/App.80301vdb.js +0 -4
- package/dist/App.af2wg84v.js +0 -267
- package/dist/App.ca1rz1ph.js +0 -4
- package/dist/App.ensa6z0r.js +0 -4
- package/dist/App.f8g7tych.js +0 -13
- package/dist/App.mvtqv6qc.js +0 -20
- package/dist/App.ncgc9cxy.js +0 -4
- package/dist/App.p02f4ret.js +0 -1
- package/dist/App.p0fb1pds.js +0 -4
- package/dist/App.pmaq48sj.js +0 -4
- package/dist/App.yv87t9m5.js +0 -4
- package/dist/App.zjmfm8p6.js +0 -4
- package/dist/ConnectionsPage.anb3rv9a.js +0 -3
- package/dist/McpPage.y396h6fy.js +0 -3
- package/dist/SettingsPage.p1hc60gk.js +0 -3
- package/dist/SkillsPage.yj3xdsay.js +0 -3
- package/dist/TasksPage.sjv0khtv.js +0 -3
- package/dist/TelemetryPage.2qm4w16r.js +0 -3
- package/dist/TestsPage.zzs4qfj8.js +0 -3
|
@@ -141,14 +141,14 @@ export function McpPage() {
|
|
|
141
141
|
<div className="flex items-center justify-between mb-6">
|
|
142
142
|
<div>
|
|
143
143
|
<h1 className="text-2xl font-semibold mb-1">MCP Servers</h1>
|
|
144
|
-
<p className="text-[
|
|
144
|
+
<p className="text-[var(--color-text-muted)]">
|
|
145
145
|
Manage Model Context Protocol servers for tool integrations.
|
|
146
146
|
</p>
|
|
147
147
|
</div>
|
|
148
148
|
{activeTab === "servers" && (
|
|
149
149
|
<button
|
|
150
150
|
onClick={() => setShowAdd(true)}
|
|
151
|
-
className="bg-[
|
|
151
|
+
className="bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black px-4 py-2 rounded font-medium transition"
|
|
152
152
|
>
|
|
153
153
|
+ Add Server
|
|
154
154
|
</button>
|
|
@@ -156,13 +156,13 @@ export function McpPage() {
|
|
|
156
156
|
</div>
|
|
157
157
|
|
|
158
158
|
{/* Tabs */}
|
|
159
|
-
<div className="flex gap-1 mb-6 bg-[
|
|
159
|
+
<div className="flex gap-1 mb-6 bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-1 w-fit">
|
|
160
160
|
<button
|
|
161
161
|
onClick={() => setActiveTab("servers")}
|
|
162
162
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
163
163
|
activeTab === "servers"
|
|
164
|
-
? "bg-[
|
|
165
|
-
: "text-[
|
|
164
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
165
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
166
166
|
}`}
|
|
167
167
|
>
|
|
168
168
|
My Servers
|
|
@@ -171,8 +171,8 @@ export function McpPage() {
|
|
|
171
171
|
onClick={() => setActiveTab("hosted")}
|
|
172
172
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
173
173
|
activeTab === "hosted"
|
|
174
|
-
? "bg-[
|
|
175
|
-
: "text-[
|
|
174
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
175
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
176
176
|
}`}
|
|
177
177
|
>
|
|
178
178
|
Hosted Services
|
|
@@ -181,8 +181,8 @@ export function McpPage() {
|
|
|
181
181
|
onClick={() => setActiveTab("registry")}
|
|
182
182
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
183
183
|
activeTab === "registry"
|
|
184
|
-
? "bg-[
|
|
185
|
-
: "text-[
|
|
184
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
185
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
186
186
|
}`}
|
|
187
187
|
>
|
|
188
188
|
Browse Registry
|
|
@@ -194,28 +194,28 @@ export function McpPage() {
|
|
|
194
194
|
<>
|
|
195
195
|
{/* Loading */}
|
|
196
196
|
{loading && (
|
|
197
|
-
<div className="text-center py-8 text-[
|
|
197
|
+
<div className="text-center py-8 text-[var(--color-text-muted)]">Loading...</div>
|
|
198
198
|
)}
|
|
199
199
|
|
|
200
200
|
{/* Empty State */}
|
|
201
201
|
{!loading && filteredServers.length === 0 && servers.length === 0 && (
|
|
202
|
-
<div className="bg-[
|
|
203
|
-
<McpIcon className="w-12 h-12 text-[
|
|
202
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-8 text-center">
|
|
203
|
+
<McpIcon className="w-12 h-12 text-[var(--color-border-light)] mx-auto mb-4" />
|
|
204
204
|
<h3 className="text-lg font-medium mb-2">No MCP servers configured</h3>
|
|
205
|
-
<p className="text-[
|
|
205
|
+
<p className="text-[var(--color-text-muted)] mb-6 max-w-md mx-auto">
|
|
206
206
|
MCP servers extend your agents with tools like file access, web browsing,
|
|
207
207
|
database connections, and more.
|
|
208
208
|
</p>
|
|
209
209
|
<div className="flex gap-3 justify-center">
|
|
210
210
|
<button
|
|
211
211
|
onClick={() => setShowAdd(true)}
|
|
212
|
-
className="bg-[
|
|
212
|
+
className="bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black px-4 py-2 rounded font-medium transition"
|
|
213
213
|
>
|
|
214
214
|
Add Manually
|
|
215
215
|
</button>
|
|
216
216
|
<button
|
|
217
217
|
onClick={() => setActiveTab("registry")}
|
|
218
|
-
className="border border-[
|
|
218
|
+
className="border border-[var(--color-border-light)] hover:border-[var(--color-text-muted)] px-4 py-2 rounded font-medium transition"
|
|
219
219
|
>
|
|
220
220
|
Browse Registry
|
|
221
221
|
</button>
|
|
@@ -225,8 +225,8 @@ export function McpPage() {
|
|
|
225
225
|
|
|
226
226
|
{/* Empty filter state */}
|
|
227
227
|
{!loading && filteredServers.length === 0 && servers.length > 0 && (
|
|
228
|
-
<div className="bg-[
|
|
229
|
-
<p className="text-[
|
|
228
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-6 text-center">
|
|
229
|
+
<p className="text-[var(--color-text-muted)]">No servers match this filter.</p>
|
|
230
230
|
</div>
|
|
231
231
|
)}
|
|
232
232
|
|
|
@@ -251,7 +251,16 @@ export function McpPage() {
|
|
|
251
251
|
onStart={() => startServer(server.id)}
|
|
252
252
|
onStop={() => stopServer(server.id)}
|
|
253
253
|
onDelete={() => deleteServer(server.id)}
|
|
254
|
-
onEdit={() =>
|
|
254
|
+
onEdit={async () => {
|
|
255
|
+
// Fetch full server details (with decrypted env/headers) for editing
|
|
256
|
+
try {
|
|
257
|
+
const res = await authFetch(`/api/mcp/servers/${server.id}`);
|
|
258
|
+
const data = await res.json();
|
|
259
|
+
setEditingServer(data.server || server);
|
|
260
|
+
} catch {
|
|
261
|
+
setEditingServer(server);
|
|
262
|
+
}
|
|
263
|
+
}}
|
|
255
264
|
/>
|
|
256
265
|
);
|
|
257
266
|
})}
|
|
@@ -289,9 +298,9 @@ export function McpPage() {
|
|
|
289
298
|
|
|
290
299
|
{/* Info - only show on servers tab */}
|
|
291
300
|
{activeTab === "servers" && (
|
|
292
|
-
<div className="mt-8 p-4 bg-[
|
|
301
|
+
<div className="mt-8 p-4 bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg">
|
|
293
302
|
<h3 className="font-medium mb-2">Quick Start</h3>
|
|
294
|
-
<p className="text-sm text-[
|
|
303
|
+
<p className="text-sm text-[var(--color-text-muted)] mb-3">
|
|
295
304
|
Add an MCP server by providing its npm package name. For example:
|
|
296
305
|
</p>
|
|
297
306
|
<div className="flex flex-wrap gap-2">
|
|
@@ -300,7 +309,7 @@ export function McpPage() {
|
|
|
300
309
|
{ name: "fetch", pkg: "@modelcontextprotocol/server-fetch" },
|
|
301
310
|
{ name: "memory", pkg: "@modelcontextprotocol/server-memory" },
|
|
302
311
|
].map(s => (
|
|
303
|
-
<code key={s.name} className="text-xs bg-[
|
|
312
|
+
<code key={s.name} className="text-xs bg-[var(--color-bg)] px-2 py-1 rounded">
|
|
304
313
|
{s.pkg}
|
|
305
314
|
</code>
|
|
306
315
|
))}
|
|
@@ -387,7 +396,7 @@ function McpServerCard({
|
|
|
387
396
|
}
|
|
388
397
|
if (server.project_id === null) {
|
|
389
398
|
return (
|
|
390
|
-
<span className="text-xs text-[
|
|
399
|
+
<span className="text-xs text-[var(--color-text-muted)] bg-[var(--color-surface-raised)] px-1.5 py-0.5 rounded">
|
|
391
400
|
Global
|
|
392
401
|
</span>
|
|
393
402
|
);
|
|
@@ -397,28 +406,28 @@ function McpServerCard({
|
|
|
397
406
|
|
|
398
407
|
return (
|
|
399
408
|
<div
|
|
400
|
-
className={`bg-[
|
|
401
|
-
selected ? "border-[
|
|
409
|
+
className={`bg-[var(--color-surface)] border rounded-lg p-4 cursor-pointer transition ${
|
|
410
|
+
selected ? "border-[var(--color-accent)]" : "border-[var(--color-border)] hover:border-[var(--color-border-light)]"
|
|
402
411
|
}`}
|
|
403
412
|
onClick={isAvailable ? onSelect : undefined}
|
|
404
413
|
>
|
|
405
414
|
<div className="flex items-center justify-between">
|
|
406
415
|
<div className="flex items-center gap-3">
|
|
407
416
|
<div className={`w-2 h-2 rounded-full ${
|
|
408
|
-
isAvailable ? "bg-green-400" : "bg-[
|
|
417
|
+
isAvailable ? "bg-green-400" : "bg-[var(--color-scrollbar)]"
|
|
409
418
|
}`} />
|
|
410
419
|
<div>
|
|
411
420
|
<div className="flex items-center gap-2">
|
|
412
421
|
<h3 className="font-medium">{server.name}</h3>
|
|
413
422
|
{getScopeBadge()}
|
|
414
423
|
</div>
|
|
415
|
-
<p className="text-sm text-[
|
|
424
|
+
<p className="text-sm text-[var(--color-text-muted)]">{getServerInfo()}</p>
|
|
416
425
|
</div>
|
|
417
426
|
</div>
|
|
418
427
|
<div className="flex items-center gap-2">
|
|
419
428
|
<button
|
|
420
429
|
onClick={(e) => { e.stopPropagation(); onEdit(); }}
|
|
421
|
-
className="text-sm text-[
|
|
430
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] px-3 py-1 transition"
|
|
422
431
|
title="Edit server settings"
|
|
423
432
|
>
|
|
424
433
|
Edit
|
|
@@ -427,7 +436,7 @@ function McpServerCard({
|
|
|
427
436
|
// Remote servers: no start/stop, just delete
|
|
428
437
|
<button
|
|
429
438
|
onClick={(e) => { e.stopPropagation(); onDelete(); }}
|
|
430
|
-
className="text-sm text-[
|
|
439
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-red-400 px-3 py-1 transition"
|
|
431
440
|
>
|
|
432
441
|
Remove
|
|
433
442
|
</button>
|
|
@@ -436,19 +445,19 @@ function McpServerCard({
|
|
|
436
445
|
<>
|
|
437
446
|
<button
|
|
438
447
|
onClick={(e) => { e.stopPropagation(); onSelect(); }}
|
|
439
|
-
className="text-sm text-[
|
|
448
|
+
className="text-sm text-[var(--color-accent)] hover:text-[var(--color-accent-hover)] px-3 py-1 transition"
|
|
440
449
|
>
|
|
441
450
|
Tools
|
|
442
451
|
</button>
|
|
443
452
|
<button
|
|
444
453
|
onClick={(e) => { e.stopPropagation(); onStop(); }}
|
|
445
|
-
className="text-sm text-[
|
|
454
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-red-400 px-3 py-1 transition"
|
|
446
455
|
>
|
|
447
456
|
Stop
|
|
448
457
|
</button>
|
|
449
458
|
<button
|
|
450
459
|
onClick={(e) => { e.stopPropagation(); onDelete(); }}
|
|
451
|
-
className="text-sm text-[
|
|
460
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-red-400 px-3 py-1 transition"
|
|
452
461
|
>
|
|
453
462
|
Delete
|
|
454
463
|
</button>
|
|
@@ -458,13 +467,13 @@ function McpServerCard({
|
|
|
458
467
|
<>
|
|
459
468
|
<button
|
|
460
469
|
onClick={(e) => { e.stopPropagation(); onStart(); }}
|
|
461
|
-
className="text-sm text-[
|
|
470
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-green-400 px-3 py-1 transition"
|
|
462
471
|
>
|
|
463
472
|
Start
|
|
464
473
|
</button>
|
|
465
474
|
<button
|
|
466
475
|
onClick={(e) => { e.stopPropagation(); onDelete(); }}
|
|
467
|
-
className="text-sm text-[
|
|
476
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-red-400 px-3 py-1 transition"
|
|
468
477
|
>
|
|
469
478
|
Delete
|
|
470
479
|
</button>
|
|
@@ -514,20 +523,20 @@ function ToolsPanel({
|
|
|
514
523
|
}, [server.id, authFetch]);
|
|
515
524
|
|
|
516
525
|
return (
|
|
517
|
-
<div className="bg-[
|
|
526
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg overflow-hidden">
|
|
518
527
|
{/* Header */}
|
|
519
|
-
<div className="p-4 border-b border-[
|
|
528
|
+
<div className="p-4 border-b border-[var(--color-border)] flex items-center justify-between">
|
|
520
529
|
<div>
|
|
521
530
|
<h3 className="font-medium">{server.name} Tools</h3>
|
|
522
531
|
{serverInfo && (
|
|
523
|
-
<p className="text-xs text-[
|
|
532
|
+
<p className="text-xs text-[var(--color-text-muted)]">
|
|
524
533
|
{serverInfo.name} v{serverInfo.version}
|
|
525
534
|
</p>
|
|
526
535
|
)}
|
|
527
536
|
</div>
|
|
528
537
|
<button
|
|
529
538
|
onClick={onClose}
|
|
530
|
-
className="text-[
|
|
539
|
+
className="text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] text-xl leading-none"
|
|
531
540
|
>
|
|
532
541
|
×
|
|
533
542
|
</button>
|
|
@@ -535,7 +544,7 @@ function ToolsPanel({
|
|
|
535
544
|
|
|
536
545
|
{/* Content */}
|
|
537
546
|
<div className="p-4 max-h-[500px] overflow-auto">
|
|
538
|
-
{loading && <p className="text-[
|
|
547
|
+
{loading && <p className="text-[var(--color-text-muted)]">Loading tools...</p>}
|
|
539
548
|
|
|
540
549
|
{error && (
|
|
541
550
|
<div className="text-red-400 text-sm p-3 bg-red-500/10 rounded">
|
|
@@ -544,7 +553,7 @@ function ToolsPanel({
|
|
|
544
553
|
)}
|
|
545
554
|
|
|
546
555
|
{!loading && !error && tools.length === 0 && (
|
|
547
|
-
<p className="text-[
|
|
556
|
+
<p className="text-[var(--color-text-muted)]">No tools available from this server.</p>
|
|
548
557
|
)}
|
|
549
558
|
|
|
550
559
|
{!loading && !error && tools.length > 0 && !selectedTool && (
|
|
@@ -553,11 +562,11 @@ function ToolsPanel({
|
|
|
553
562
|
<button
|
|
554
563
|
key={tool.name}
|
|
555
564
|
onClick={() => setSelectedTool(tool)}
|
|
556
|
-
className="w-full text-left p-3 bg-[
|
|
565
|
+
className="w-full text-left p-3 bg-[var(--color-bg)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-border-light)] rounded transition"
|
|
557
566
|
>
|
|
558
567
|
<div className="font-medium text-sm">{tool.name}</div>
|
|
559
568
|
{tool.description && (
|
|
560
|
-
<div className="text-xs text-[
|
|
569
|
+
<div className="text-xs text-[var(--color-text-muted)] mt-1">{tool.description}</div>
|
|
561
570
|
)}
|
|
562
571
|
</button>
|
|
563
572
|
))}
|
|
@@ -649,25 +658,25 @@ function ToolTester({
|
|
|
649
658
|
<div className="flex items-center gap-2">
|
|
650
659
|
<button
|
|
651
660
|
onClick={onBack}
|
|
652
|
-
className="text-[
|
|
661
|
+
className="text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] text-sm"
|
|
653
662
|
>
|
|
654
663
|
← Back
|
|
655
664
|
</button>
|
|
656
|
-
<span className="text-[
|
|
665
|
+
<span className="text-[var(--color-text-faint)]">/</span>
|
|
657
666
|
<span className="font-medium">{tool.name}</span>
|
|
658
667
|
</div>
|
|
659
668
|
|
|
660
669
|
{/* Description */}
|
|
661
670
|
{tool.description && (
|
|
662
|
-
<p className="text-sm text-[
|
|
671
|
+
<p className="text-sm text-[var(--color-text-muted)]">{tool.description}</p>
|
|
663
672
|
)}
|
|
664
673
|
|
|
665
674
|
{/* Schema info */}
|
|
666
675
|
{tool.inputSchema && (
|
|
667
676
|
<div className="text-xs">
|
|
668
677
|
<details className="cursor-pointer">
|
|
669
|
-
<summary className="text-[
|
|
670
|
-
<pre className="mt-2 p-2 bg-[
|
|
678
|
+
<summary className="text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]">Input Schema</summary>
|
|
679
|
+
<pre className="mt-2 p-2 bg-[var(--color-bg)] rounded text-[var(--color-text-secondary)] overflow-auto max-h-32">
|
|
671
680
|
{JSON.stringify(tool.inputSchema, null, 2)}
|
|
672
681
|
</pre>
|
|
673
682
|
</details>
|
|
@@ -676,11 +685,11 @@ function ToolTester({
|
|
|
676
685
|
|
|
677
686
|
{/* Arguments input */}
|
|
678
687
|
<div>
|
|
679
|
-
<label className="block text-sm text-[
|
|
688
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Arguments (JSON)</label>
|
|
680
689
|
<textarea
|
|
681
690
|
value={args}
|
|
682
691
|
onChange={(e) => setArgs(e.target.value)}
|
|
683
|
-
className="w-full bg-[
|
|
692
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 h-32 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)] resize-none"
|
|
684
693
|
placeholder="{}"
|
|
685
694
|
/>
|
|
686
695
|
</div>
|
|
@@ -689,7 +698,7 @@ function ToolTester({
|
|
|
689
698
|
<button
|
|
690
699
|
onClick={callTool}
|
|
691
700
|
disabled={loading}
|
|
692
|
-
className="w-full bg-[
|
|
701
|
+
className="w-full bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-4 py-2 rounded font-medium transition"
|
|
693
702
|
>
|
|
694
703
|
{loading ? "Calling..." : "Call Tool"}
|
|
695
704
|
</button>
|
|
@@ -704,7 +713,7 @@ function ToolTester({
|
|
|
704
713
|
{/* Result */}
|
|
705
714
|
{result && (
|
|
706
715
|
<div className="space-y-2">
|
|
707
|
-
<div className="text-sm text-[
|
|
716
|
+
<div className="text-sm text-[var(--color-text-muted)]">
|
|
708
717
|
Result {result.isError && <span className="text-red-400">(error)</span>}
|
|
709
718
|
</div>
|
|
710
719
|
<div className={`p-3 rounded text-sm ${result.isError ? "bg-red-500/10" : "bg-green-500/10"}`}>
|
|
@@ -820,12 +829,12 @@ function RegistryBrowser({
|
|
|
820
829
|
value={search}
|
|
821
830
|
onChange={(e) => setSearch(e.target.value)}
|
|
822
831
|
placeholder="Search MCP servers (e.g., filesystem, github, slack...)"
|
|
823
|
-
className="flex-1 bg-[
|
|
832
|
+
className="flex-1 bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-lg px-4 py-3 focus:outline-none focus:border-[var(--color-accent)]"
|
|
824
833
|
/>
|
|
825
834
|
<button
|
|
826
835
|
type="submit"
|
|
827
836
|
disabled={loading}
|
|
828
|
-
className="bg-[
|
|
837
|
+
className="bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] disabled:opacity-50 text-black px-6 py-3 rounded-lg font-medium transition"
|
|
829
838
|
>
|
|
830
839
|
{loading ? "..." : "Search"}
|
|
831
840
|
</button>
|
|
@@ -840,7 +849,7 @@ function RegistryBrowser({
|
|
|
840
849
|
|
|
841
850
|
{/* Results */}
|
|
842
851
|
{!loading && searched && servers.length === 0 && (
|
|
843
|
-
<div className="text-center py-8 text-[
|
|
852
|
+
<div className="text-center py-8 text-[var(--color-text-muted)]">
|
|
844
853
|
No servers found. Try a different search term.
|
|
845
854
|
</div>
|
|
846
855
|
)}
|
|
@@ -850,15 +859,15 @@ function RegistryBrowser({
|
|
|
850
859
|
{servers.map((server) => (
|
|
851
860
|
<div
|
|
852
861
|
key={server.id}
|
|
853
|
-
className="bg-[
|
|
862
|
+
className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-4 hover:border-[var(--color-border-light)] transition"
|
|
854
863
|
>
|
|
855
864
|
<div className="flex items-start justify-between gap-3">
|
|
856
865
|
<div className="flex-1 min-w-0">
|
|
857
866
|
<h3 className="font-medium truncate">{server.name}</h3>
|
|
858
|
-
<p className="text-sm text-[
|
|
867
|
+
<p className="text-sm text-[var(--color-text-muted)] mt-1 line-clamp-2">
|
|
859
868
|
{server.description || "No description"}
|
|
860
869
|
</p>
|
|
861
|
-
<div className="flex items-center gap-2 mt-2 text-xs text-[
|
|
870
|
+
<div className="flex items-center gap-2 mt-2 text-xs text-[var(--color-text-faint)]">
|
|
862
871
|
{server.version && <span>v{server.version}</span>}
|
|
863
872
|
<span className={`px-1.5 py-0.5 rounded ${
|
|
864
873
|
server.npmPackage ? "bg-green-500/10 text-green-400" : "bg-blue-500/10 text-blue-400"
|
|
@@ -866,7 +875,7 @@ function RegistryBrowser({
|
|
|
866
875
|
{server.npmPackage ? "npm" : "remote"}
|
|
867
876
|
</span>
|
|
868
877
|
</div>
|
|
869
|
-
<code className="text-xs text-[
|
|
878
|
+
<code className="text-xs text-[var(--color-text-faint)] bg-[var(--color-bg)] px-2 py-0.5 rounded mt-2 inline-block truncate max-w-full">
|
|
870
879
|
{server.npmPackage || server.fullName}
|
|
871
880
|
</code>
|
|
872
881
|
</div>
|
|
@@ -875,7 +884,7 @@ function RegistryBrowser({
|
|
|
875
884
|
<button
|
|
876
885
|
onClick={() => installServer(server)}
|
|
877
886
|
disabled={installing === server.id}
|
|
878
|
-
className="text-sm bg-[
|
|
887
|
+
className="text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-3 py-1.5 rounded transition disabled:opacity-50"
|
|
879
888
|
>
|
|
880
889
|
{installing === server.id ? "Adding..." : "Add"}
|
|
881
890
|
</button>
|
|
@@ -884,7 +893,7 @@ function RegistryBrowser({
|
|
|
884
893
|
href={server.repository}
|
|
885
894
|
target="_blank"
|
|
886
895
|
rel="noopener noreferrer"
|
|
887
|
-
className="text-sm text-[
|
|
896
|
+
className="text-sm text-[var(--color-text-muted)] hover:text-[var(--color-accent)] transition"
|
|
888
897
|
>
|
|
889
898
|
View →
|
|
890
899
|
</a>
|
|
@@ -898,20 +907,20 @@ function RegistryBrowser({
|
|
|
898
907
|
|
|
899
908
|
{/* Loading */}
|
|
900
909
|
{loading && (
|
|
901
|
-
<div className="text-center py-8 text-[
|
|
910
|
+
<div className="text-center py-8 text-[var(--color-text-muted)]">
|
|
902
911
|
Searching registry...
|
|
903
912
|
</div>
|
|
904
913
|
)}
|
|
905
914
|
|
|
906
915
|
{/* Registry info */}
|
|
907
|
-
<div className="p-4 bg-[
|
|
916
|
+
<div className="p-4 bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg text-sm text-[var(--color-text-muted)]">
|
|
908
917
|
<p>
|
|
909
918
|
Servers are sourced from the{" "}
|
|
910
919
|
<a
|
|
911
920
|
href="https://github.com/modelcontextprotocol/servers"
|
|
912
921
|
target="_blank"
|
|
913
922
|
rel="noopener noreferrer"
|
|
914
|
-
className="text-[
|
|
923
|
+
className="text-[var(--color-accent)] hover:underline"
|
|
915
924
|
>
|
|
916
925
|
official MCP registry
|
|
917
926
|
</a>
|
|
@@ -1043,7 +1052,7 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1043
1052
|
}, [authFetch, projectId]);
|
|
1044
1053
|
|
|
1045
1054
|
if (loading) {
|
|
1046
|
-
return <div className="text-center py-8 text-[
|
|
1055
|
+
return <div className="text-center py-8 text-[var(--color-text-muted)]">Loading...</div>;
|
|
1047
1056
|
}
|
|
1048
1057
|
|
|
1049
1058
|
const hasAnyConnection = composioConnected || smitheryConnected || agentDojoConnected;
|
|
@@ -1051,14 +1060,14 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1051
1060
|
|
|
1052
1061
|
if (!hasAnyConnection) {
|
|
1053
1062
|
return (
|
|
1054
|
-
<div className="bg-[
|
|
1055
|
-
<p className="text-[
|
|
1056
|
-
<p className="text-sm text-[
|
|
1063
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-8 text-center">
|
|
1064
|
+
<p className="text-[var(--color-text-secondary)] mb-2">No hosted MCP services connected</p>
|
|
1065
|
+
<p className="text-sm text-[var(--color-text-muted)] mb-4">
|
|
1057
1066
|
Connect Composio, Smithery, or AgentDojo in Settings to access cloud-based MCP servers.
|
|
1058
1067
|
</p>
|
|
1059
1068
|
<a
|
|
1060
1069
|
href="/settings"
|
|
1061
|
-
className="inline-block bg-[
|
|
1070
|
+
className="inline-block bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] border border-[var(--color-border-light)] hover:border-[var(--color-accent)] px-4 py-2 rounded text-sm font-medium transition"
|
|
1062
1071
|
>
|
|
1063
1072
|
Go to Settings →
|
|
1064
1073
|
</a>
|
|
@@ -1072,14 +1081,14 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1072
1081
|
<div className="space-y-6">
|
|
1073
1082
|
{/* Provider Tabs - show when multiple providers are connected */}
|
|
1074
1083
|
{connectedCount > 1 && (
|
|
1075
|
-
<div className="flex gap-1 bg-[
|
|
1084
|
+
<div className="flex gap-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg p-1 w-fit">
|
|
1076
1085
|
{composioConnected && (
|
|
1077
1086
|
<button
|
|
1078
1087
|
onClick={() => { setActiveProvider("composio"); setSubTab("configs"); }}
|
|
1079
1088
|
className={`px-4 py-2 rounded text-sm font-medium transition flex items-center gap-2 ${
|
|
1080
1089
|
activeProvider === "composio"
|
|
1081
|
-
? "bg-[
|
|
1082
|
-
: "text-[
|
|
1090
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1091
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1083
1092
|
}`}
|
|
1084
1093
|
>
|
|
1085
1094
|
<span className="w-2 h-2 rounded-full bg-purple-500" />
|
|
@@ -1091,8 +1100,8 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1091
1100
|
onClick={() => setActiveProvider("smithery")}
|
|
1092
1101
|
className={`px-4 py-2 rounded text-sm font-medium transition flex items-center gap-2 ${
|
|
1093
1102
|
activeProvider === "smithery"
|
|
1094
|
-
? "bg-[
|
|
1095
|
-
: "text-[
|
|
1103
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1104
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1096
1105
|
}`}
|
|
1097
1106
|
>
|
|
1098
1107
|
<span className="w-2 h-2 rounded-full bg-blue-500" />
|
|
@@ -1104,8 +1113,8 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1104
1113
|
onClick={() => setActiveProvider("agentdojo")}
|
|
1105
1114
|
className={`px-4 py-2 rounded text-sm font-medium transition flex items-center gap-2 ${
|
|
1106
1115
|
activeProvider === "agentdojo"
|
|
1107
|
-
? "bg-[
|
|
1108
|
-
: "text-[
|
|
1116
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1117
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1109
1118
|
}`}
|
|
1110
1119
|
>
|
|
1111
1120
|
<span className="w-2 h-2 rounded-full bg-green-500" />
|
|
@@ -1120,13 +1129,13 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1120
1129
|
<>
|
|
1121
1130
|
{/* Sub-tabs for Composio */}
|
|
1122
1131
|
<div className="flex items-center justify-between">
|
|
1123
|
-
<div className="flex gap-1 bg-[
|
|
1132
|
+
<div className="flex gap-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg p-1">
|
|
1124
1133
|
<button
|
|
1125
1134
|
onClick={() => setSubTab("configs")}
|
|
1126
1135
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
1127
1136
|
subTab === "configs"
|
|
1128
|
-
? "bg-[
|
|
1129
|
-
: "text-[
|
|
1137
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1138
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1130
1139
|
}`}
|
|
1131
1140
|
>
|
|
1132
1141
|
MCP Configs
|
|
@@ -1135,15 +1144,15 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1135
1144
|
onClick={() => setSubTab("connect")}
|
|
1136
1145
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
1137
1146
|
subTab === "connect"
|
|
1138
|
-
? "bg-[
|
|
1139
|
-
: "text-[
|
|
1147
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1148
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1140
1149
|
}`}
|
|
1141
1150
|
>
|
|
1142
1151
|
Connect Apps
|
|
1143
1152
|
</button>
|
|
1144
1153
|
</div>
|
|
1145
1154
|
{connectedCount === 1 && (
|
|
1146
|
-
<div className="flex items-center gap-2 text-xs text-[
|
|
1155
|
+
<div className="flex items-center gap-2 text-xs text-[var(--color-text-muted)]">
|
|
1147
1156
|
<span className="w-2 h-2 rounded-full bg-purple-500" />
|
|
1148
1157
|
Composio
|
|
1149
1158
|
<span className="text-green-400">Connected</span>
|
|
@@ -1154,7 +1163,7 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1154
1163
|
{/* Connect Apps Tab */}
|
|
1155
1164
|
{subTab === "connect" && (
|
|
1156
1165
|
<div>
|
|
1157
|
-
<p className="text-sm text-[
|
|
1166
|
+
<p className="text-sm text-[var(--color-text-muted)] mb-4">
|
|
1158
1167
|
Connect your accounts to enable tools in MCP configs
|
|
1159
1168
|
</p>
|
|
1160
1169
|
<IntegrationsPanel
|
|
@@ -1172,14 +1181,14 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1172
1181
|
{subTab === "configs" && (
|
|
1173
1182
|
<div>
|
|
1174
1183
|
<div className="flex items-center justify-between mb-3">
|
|
1175
|
-
<p className="text-sm text-[
|
|
1184
|
+
<p className="text-sm text-[var(--color-text-muted)]">
|
|
1176
1185
|
Your MCP configs from Composio
|
|
1177
1186
|
</p>
|
|
1178
1187
|
<div className="flex items-center gap-3">
|
|
1179
1188
|
<button
|
|
1180
1189
|
onClick={fetchComposioConfigs}
|
|
1181
1190
|
disabled={loadingConfigs}
|
|
1182
|
-
className="text-xs text-[
|
|
1191
|
+
className="text-xs text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition"
|
|
1183
1192
|
>
|
|
1184
1193
|
{loadingConfigs ? "Loading..." : "Refresh"}
|
|
1185
1194
|
</button>
|
|
@@ -1187,7 +1196,7 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1187
1196
|
href="https://app.composio.dev/mcp_configs"
|
|
1188
1197
|
target="_blank"
|
|
1189
1198
|
rel="noopener noreferrer"
|
|
1190
|
-
className="text-xs text-[
|
|
1199
|
+
className="text-xs text-[var(--color-text-muted)] hover:text-[var(--color-accent)] transition"
|
|
1191
1200
|
>
|
|
1192
1201
|
Create Config →
|
|
1193
1202
|
</a>
|
|
@@ -1195,18 +1204,18 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1195
1204
|
</div>
|
|
1196
1205
|
|
|
1197
1206
|
{loadingConfigs ? (
|
|
1198
|
-
<div className="text-center py-6 text-[
|
|
1207
|
+
<div className="text-center py-6 text-[var(--color-text-muted)]">Loading configs...</div>
|
|
1199
1208
|
) : composioConfigs.length === 0 ? (
|
|
1200
|
-
<div className="bg-[
|
|
1201
|
-
<p className="text-sm text-[
|
|
1202
|
-
<p className="text-xs text-[
|
|
1203
|
-
First <button onClick={() => setSubTab("connect")} className="text-[
|
|
1209
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-4 text-center">
|
|
1210
|
+
<p className="text-sm text-[var(--color-text-muted)]">No MCP configs found</p>
|
|
1211
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-2">
|
|
1212
|
+
First <button onClick={() => setSubTab("connect")} className="text-[var(--color-accent)] hover:text-[var(--color-accent-hover)]">connect some apps</button>, then create a config.
|
|
1204
1213
|
</p>
|
|
1205
1214
|
<a
|
|
1206
1215
|
href="https://app.composio.dev/mcp_configs"
|
|
1207
1216
|
target="_blank"
|
|
1208
1217
|
rel="noopener noreferrer"
|
|
1209
|
-
className="text-xs text-[
|
|
1218
|
+
className="text-xs text-[var(--color-accent)] hover:text-[var(--color-accent-hover)] mt-2 inline-block"
|
|
1210
1219
|
>
|
|
1211
1220
|
Create in Composio →
|
|
1212
1221
|
</a>
|
|
@@ -1219,14 +1228,14 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1219
1228
|
return (
|
|
1220
1229
|
<div
|
|
1221
1230
|
key={config.id}
|
|
1222
|
-
className={`bg-[
|
|
1223
|
-
added ? "border-green-500/30" : "border-[
|
|
1231
|
+
className={`bg-[var(--color-surface)] border rounded-lg p-3 transition flex items-center justify-between ${
|
|
1232
|
+
added ? "border-green-500/30" : "border-[var(--color-border)] hover:border-[var(--color-border-light)]"
|
|
1224
1233
|
}`}
|
|
1225
1234
|
>
|
|
1226
1235
|
<div className="flex-1 min-w-0">
|
|
1227
1236
|
<div className="flex items-center gap-2">
|
|
1228
1237
|
<span className="font-medium text-sm">{config.name}</span>
|
|
1229
|
-
<span className="text-xs text-[
|
|
1238
|
+
<span className="text-xs text-[var(--color-text-faint)]">{config.toolsCount} tools</span>
|
|
1230
1239
|
{added && (
|
|
1231
1240
|
<span className="text-xs text-green-400">Added</span>
|
|
1232
1241
|
)}
|
|
@@ -1236,25 +1245,25 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1236
1245
|
{config.toolkits.slice(0, 4).map((toolkit) => (
|
|
1237
1246
|
<span
|
|
1238
1247
|
key={toolkit}
|
|
1239
|
-
className="text-xs bg-[
|
|
1248
|
+
className="text-xs bg-[var(--color-surface-raised)] text-[var(--color-text-muted)] px-1.5 py-0.5 rounded"
|
|
1240
1249
|
>
|
|
1241
1250
|
{toolkit}
|
|
1242
1251
|
</span>
|
|
1243
1252
|
))}
|
|
1244
1253
|
{config.toolkits.length > 4 && (
|
|
1245
|
-
<span className="text-xs text-[
|
|
1254
|
+
<span className="text-xs text-[var(--color-text-faint)]">+{config.toolkits.length - 4}</span>
|
|
1246
1255
|
)}
|
|
1247
1256
|
</div>
|
|
1248
1257
|
)}
|
|
1249
1258
|
</div>
|
|
1250
1259
|
<div className="flex items-center gap-2 ml-3">
|
|
1251
1260
|
{added ? (
|
|
1252
|
-
<span className="text-xs text-[
|
|
1261
|
+
<span className="text-xs text-[var(--color-text-faint)] px-2 py-1">In Servers</span>
|
|
1253
1262
|
) : (
|
|
1254
1263
|
<button
|
|
1255
1264
|
onClick={() => addComposioConfig(config.id)}
|
|
1256
1265
|
disabled={isAdding}
|
|
1257
|
-
className="text-xs bg-[
|
|
1266
|
+
className="text-xs bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black px-3 py-1 rounded font-medium transition disabled:opacity-50"
|
|
1258
1267
|
>
|
|
1259
1268
|
{isAdding ? "Adding..." : "Add"}
|
|
1260
1269
|
</button>
|
|
@@ -1263,7 +1272,7 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1263
1272
|
href={`https://app.composio.dev/mcp_configs/${config.id}`}
|
|
1264
1273
|
target="_blank"
|
|
1265
1274
|
rel="noopener noreferrer"
|
|
1266
|
-
className="text-xs text-[
|
|
1275
|
+
className="text-xs text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition"
|
|
1267
1276
|
>
|
|
1268
1277
|
Edit
|
|
1269
1278
|
</a>
|
|
@@ -1282,30 +1291,30 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1282
1291
|
{smitheryConnected && (connectedCount === 1 || activeProvider === "smithery") && (
|
|
1283
1292
|
<div>
|
|
1284
1293
|
{connectedCount === 1 && (
|
|
1285
|
-
<div className="flex items-center gap-2 text-xs text-[
|
|
1294
|
+
<div className="flex items-center gap-2 text-xs text-[var(--color-text-muted)] mb-4">
|
|
1286
1295
|
<span className="w-2 h-2 rounded-full bg-blue-500" />
|
|
1287
1296
|
Smithery
|
|
1288
1297
|
<span className="text-green-400">Connected</span>
|
|
1289
1298
|
</div>
|
|
1290
1299
|
)}
|
|
1291
1300
|
<div className="flex items-center justify-between mb-3">
|
|
1292
|
-
<p className="text-sm text-[
|
|
1301
|
+
<p className="text-sm text-[var(--color-text-muted)]">
|
|
1293
1302
|
Add MCP servers from the Smithery registry
|
|
1294
1303
|
</p>
|
|
1295
1304
|
<a
|
|
1296
1305
|
href="https://smithery.ai/servers"
|
|
1297
1306
|
target="_blank"
|
|
1298
1307
|
rel="noopener noreferrer"
|
|
1299
|
-
className="text-xs text-[
|
|
1308
|
+
className="text-xs text-[var(--color-text-muted)] hover:text-[var(--color-accent)] transition"
|
|
1300
1309
|
>
|
|
1301
1310
|
Browse Smithery →
|
|
1302
1311
|
</a>
|
|
1303
1312
|
</div>
|
|
1304
|
-
<div className="bg-[
|
|
1305
|
-
<p className="text-sm text-[
|
|
1313
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-4 text-center">
|
|
1314
|
+
<p className="text-sm text-[var(--color-text-muted)]">
|
|
1306
1315
|
Smithery servers can be added from the <strong>Browse Registry</strong> tab.
|
|
1307
1316
|
</p>
|
|
1308
|
-
<p className="text-xs text-[
|
|
1317
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-2">
|
|
1309
1318
|
Your API key will be used automatically when adding Smithery servers.
|
|
1310
1319
|
</p>
|
|
1311
1320
|
</div>
|
|
@@ -1321,10 +1330,10 @@ function HostedServices({ onServerAdded, projectId }: { onServerAdded?: () => vo
|
|
|
1321
1330
|
/>
|
|
1322
1331
|
)}
|
|
1323
1332
|
|
|
1324
|
-
<div className="p-3 bg-[
|
|
1325
|
-
<strong className="text-[
|
|
1333
|
+
<div className="p-3 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded text-xs text-[var(--color-text-muted)]">
|
|
1334
|
+
<strong className="text-[var(--color-text-secondary)]">Tip:</strong> Connect apps first, then add MCP configs to make tools available to your agents.
|
|
1326
1335
|
{" · "}
|
|
1327
|
-
<a href="/settings" className="text-[
|
|
1336
|
+
<a href="/settings" className="text-[var(--color-accent)] hover:text-[var(--color-accent-hover)]">Add more providers in Settings</a>
|
|
1328
1337
|
</div>
|
|
1329
1338
|
</div>
|
|
1330
1339
|
</>
|
|
@@ -1437,7 +1446,7 @@ function AgentDojoContent({
|
|
|
1437
1446
|
{AlertDialog}
|
|
1438
1447
|
<div>
|
|
1439
1448
|
{showProviderBadge && (
|
|
1440
|
-
<div className="flex items-center gap-2 text-xs text-[
|
|
1449
|
+
<div className="flex items-center gap-2 text-xs text-[var(--color-text-muted)] mb-4">
|
|
1441
1450
|
<span className="w-2 h-2 rounded-full bg-green-500" />
|
|
1442
1451
|
AgentDojo
|
|
1443
1452
|
<span className="text-green-400">Connected</span>
|
|
@@ -1446,13 +1455,13 @@ function AgentDojoContent({
|
|
|
1446
1455
|
|
|
1447
1456
|
{/* Sub-tabs */}
|
|
1448
1457
|
<div className="flex items-center justify-between mb-4">
|
|
1449
|
-
<div className="flex gap-1 bg-[
|
|
1458
|
+
<div className="flex gap-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg p-1">
|
|
1450
1459
|
<button
|
|
1451
1460
|
onClick={() => setSubTab("configs")}
|
|
1452
1461
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
1453
1462
|
subTab === "configs"
|
|
1454
|
-
? "bg-[
|
|
1455
|
-
: "text-[
|
|
1463
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1464
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1456
1465
|
}`}
|
|
1457
1466
|
>
|
|
1458
1467
|
MCP Servers
|
|
@@ -1461,8 +1470,8 @@ function AgentDojoContent({
|
|
|
1461
1470
|
onClick={() => setSubTab("toolkits")}
|
|
1462
1471
|
className={`px-4 py-2 rounded text-sm font-medium transition ${
|
|
1463
1472
|
subTab === "toolkits"
|
|
1464
|
-
? "bg-[
|
|
1465
|
-
: "text-[
|
|
1473
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1474
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1466
1475
|
}`}
|
|
1467
1476
|
>
|
|
1468
1477
|
Browse Toolkits
|
|
@@ -1474,25 +1483,25 @@ function AgentDojoContent({
|
|
|
1474
1483
|
{subTab === "configs" && (
|
|
1475
1484
|
<div>
|
|
1476
1485
|
<div className="flex items-center justify-between mb-3">
|
|
1477
|
-
<p className="text-sm text-[
|
|
1486
|
+
<p className="text-sm text-[var(--color-text-muted)]">
|
|
1478
1487
|
Your MCP servers from AgentDojo
|
|
1479
1488
|
</p>
|
|
1480
1489
|
<button
|
|
1481
1490
|
onClick={fetchConfigs}
|
|
1482
1491
|
disabled={loadingConfigs}
|
|
1483
|
-
className="text-xs text-[
|
|
1492
|
+
className="text-xs text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition"
|
|
1484
1493
|
>
|
|
1485
1494
|
{loadingConfigs ? "Loading..." : "Refresh"}
|
|
1486
1495
|
</button>
|
|
1487
1496
|
</div>
|
|
1488
1497
|
|
|
1489
1498
|
{loadingConfigs ? (
|
|
1490
|
-
<div className="text-center py-6 text-[
|
|
1499
|
+
<div className="text-center py-6 text-[var(--color-text-muted)]">Loading servers...</div>
|
|
1491
1500
|
) : configs.length === 0 ? (
|
|
1492
|
-
<div className="bg-[
|
|
1493
|
-
<p className="text-sm text-[
|
|
1494
|
-
<p className="text-xs text-[
|
|
1495
|
-
<button onClick={() => setSubTab("toolkits")} className="text-[
|
|
1501
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg p-4 text-center">
|
|
1502
|
+
<p className="text-sm text-[var(--color-text-muted)]">No MCP servers found</p>
|
|
1503
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-2">
|
|
1504
|
+
<button onClick={() => setSubTab("toolkits")} className="text-[var(--color-accent)] hover:text-[var(--color-accent-hover)]">
|
|
1496
1505
|
Browse toolkits
|
|
1497
1506
|
</button>
|
|
1498
1507
|
{" "}to create a new MCP server.
|
|
@@ -1506,37 +1515,37 @@ function AgentDojoContent({
|
|
|
1506
1515
|
return (
|
|
1507
1516
|
<div
|
|
1508
1517
|
key={config.id}
|
|
1509
|
-
className={`bg-[
|
|
1510
|
-
added ? "border-green-500/30" : "border-[
|
|
1518
|
+
className={`bg-[var(--color-surface)] border rounded-lg p-3 transition flex items-center justify-between ${
|
|
1519
|
+
added ? "border-green-500/30" : "border-[var(--color-border)] hover:border-[var(--color-border-light)]"
|
|
1511
1520
|
}`}
|
|
1512
1521
|
>
|
|
1513
1522
|
<div className="flex-1 min-w-0">
|
|
1514
1523
|
<div className="flex items-center gap-2">
|
|
1515
1524
|
<span className="font-medium text-sm">{config.name}</span>
|
|
1516
|
-
<span className="text-xs text-[
|
|
1525
|
+
<span className="text-xs text-[var(--color-text-faint)]">{config.toolsCount} tools</span>
|
|
1517
1526
|
{added && (
|
|
1518
1527
|
<span className="text-xs text-green-400">Added</span>
|
|
1519
1528
|
)}
|
|
1520
1529
|
</div>
|
|
1521
1530
|
{config.mcpUrl && (
|
|
1522
|
-
<code className="text-xs text-[
|
|
1531
|
+
<code className="text-xs text-[var(--color-text-faint)] mt-1 block truncate">
|
|
1523
1532
|
{config.mcpUrl}
|
|
1524
1533
|
</code>
|
|
1525
1534
|
)}
|
|
1526
1535
|
{!config.mcpUrl && config.slug && (
|
|
1527
|
-
<code className="text-xs text-[
|
|
1536
|
+
<code className="text-xs text-[var(--color-text-faint)] mt-1 block truncate">
|
|
1528
1537
|
{config.slug}
|
|
1529
1538
|
</code>
|
|
1530
1539
|
)}
|
|
1531
1540
|
</div>
|
|
1532
1541
|
<div className="flex items-center gap-2 ml-3">
|
|
1533
1542
|
{added ? (
|
|
1534
|
-
<span className="text-xs text-[
|
|
1543
|
+
<span className="text-xs text-[var(--color-text-faint)] px-2 py-1">In Servers</span>
|
|
1535
1544
|
) : (
|
|
1536
1545
|
<button
|
|
1537
1546
|
onClick={() => addConfig(config.id)}
|
|
1538
1547
|
disabled={isAdding}
|
|
1539
|
-
className="text-xs bg-[
|
|
1548
|
+
className="text-xs bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black px-3 py-1 rounded font-medium transition disabled:opacity-50"
|
|
1540
1549
|
>
|
|
1541
1550
|
{isAdding ? "Adding..." : "Add"}
|
|
1542
1551
|
</button>
|
|
@@ -1553,7 +1562,7 @@ function AgentDojoContent({
|
|
|
1553
1562
|
{/* Browse Toolkits Tab */}
|
|
1554
1563
|
{subTab === "toolkits" && (
|
|
1555
1564
|
<div>
|
|
1556
|
-
<p className="text-sm text-[
|
|
1565
|
+
<p className="text-sm text-[var(--color-text-muted)] mb-4">
|
|
1557
1566
|
Browse available toolkits and create MCP servers
|
|
1558
1567
|
</p>
|
|
1559
1568
|
<IntegrationsPanel
|
|
@@ -1836,10 +1845,10 @@ function AddServerModal({
|
|
|
1836
1845
|
|
|
1837
1846
|
return (
|
|
1838
1847
|
<div className="fixed inset-0 bg-black/50 backdrop-blur-[2px] z-50 flex items-center justify-center p-4">
|
|
1839
|
-
<div className="bg-[
|
|
1840
|
-
<div className="p-4 border-b border-[
|
|
1848
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg w-full max-w-lg max-h-[90vh] overflow-y-auto">
|
|
1849
|
+
<div className="p-4 border-b border-[var(--color-border)] flex items-center justify-between sticky top-0 bg-[var(--color-surface)]">
|
|
1841
1850
|
<h2 className="text-lg font-semibold">Add MCP Server</h2>
|
|
1842
|
-
<button onClick={onClose} className="text-[
|
|
1851
|
+
<button onClick={onClose} className="text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]">
|
|
1843
1852
|
✕
|
|
1844
1853
|
</button>
|
|
1845
1854
|
</div>
|
|
@@ -1847,7 +1856,7 @@ function AddServerModal({
|
|
|
1847
1856
|
<div className="p-4 space-y-4">
|
|
1848
1857
|
{/* Quick picks */}
|
|
1849
1858
|
<div>
|
|
1850
|
-
<p className="text-sm text-[
|
|
1859
|
+
<p className="text-sm text-[var(--color-text-muted)] mb-2">Quick add:</p>
|
|
1851
1860
|
<div className="flex flex-wrap gap-2">
|
|
1852
1861
|
{[
|
|
1853
1862
|
{ name: "filesystem", pkg: "@modelcontextprotocol/server-filesystem", type: "npm" as const },
|
|
@@ -1868,7 +1877,7 @@ function AddServerModal({
|
|
|
1868
1877
|
setPipModule("");
|
|
1869
1878
|
}
|
|
1870
1879
|
}}
|
|
1871
|
-
className="text-sm bg-[
|
|
1880
|
+
className="text-sm bg-[var(--color-surface-raised)] hover:bg-[var(--color-surface-raised)] px-3 py-1 rounded transition"
|
|
1872
1881
|
>
|
|
1873
1882
|
{s.name}
|
|
1874
1883
|
</button>
|
|
@@ -1877,13 +1886,13 @@ function AddServerModal({
|
|
|
1877
1886
|
</div>
|
|
1878
1887
|
|
|
1879
1888
|
{/* Mode toggle */}
|
|
1880
|
-
<div className="flex gap-1 bg-[
|
|
1889
|
+
<div className="flex gap-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded p-1">
|
|
1881
1890
|
<button
|
|
1882
1891
|
onClick={() => setMode("npm")}
|
|
1883
1892
|
className={`flex-1 px-2 py-1.5 rounded text-sm transition ${
|
|
1884
1893
|
mode === "npm"
|
|
1885
|
-
? "bg-[
|
|
1886
|
-
: "text-[
|
|
1894
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1895
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1887
1896
|
}`}
|
|
1888
1897
|
>
|
|
1889
1898
|
npm
|
|
@@ -1892,8 +1901,8 @@ function AddServerModal({
|
|
|
1892
1901
|
onClick={() => setMode("pip")}
|
|
1893
1902
|
className={`flex-1 px-2 py-1.5 rounded text-sm transition ${
|
|
1894
1903
|
mode === "pip"
|
|
1895
|
-
? "bg-[
|
|
1896
|
-
: "text-[
|
|
1904
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1905
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1897
1906
|
}`}
|
|
1898
1907
|
>
|
|
1899
1908
|
pip
|
|
@@ -1902,8 +1911,8 @@ function AddServerModal({
|
|
|
1902
1911
|
onClick={() => setMode("command")}
|
|
1903
1912
|
className={`flex-1 px-2 py-1.5 rounded text-sm transition ${
|
|
1904
1913
|
mode === "command"
|
|
1905
|
-
? "bg-[
|
|
1906
|
-
: "text-[
|
|
1914
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1915
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1907
1916
|
}`}
|
|
1908
1917
|
>
|
|
1909
1918
|
Command
|
|
@@ -1912,8 +1921,8 @@ function AddServerModal({
|
|
|
1912
1921
|
onClick={() => setMode("http")}
|
|
1913
1922
|
className={`flex-1 px-2 py-1.5 rounded text-sm transition ${
|
|
1914
1923
|
mode === "http"
|
|
1915
|
-
? "bg-[
|
|
1916
|
-
: "text-[
|
|
1924
|
+
? "bg-[var(--color-surface-raised)] text-white"
|
|
1925
|
+
: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
|
|
1917
1926
|
}`}
|
|
1918
1927
|
>
|
|
1919
1928
|
HTTP
|
|
@@ -1922,20 +1931,20 @@ function AddServerModal({
|
|
|
1922
1931
|
|
|
1923
1932
|
{/* Name */}
|
|
1924
1933
|
<div>
|
|
1925
|
-
<label className="block text-sm text-[
|
|
1934
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Name</label>
|
|
1926
1935
|
<input
|
|
1927
1936
|
type="text"
|
|
1928
1937
|
value={name}
|
|
1929
1938
|
onChange={e => setName(e.target.value)}
|
|
1930
1939
|
placeholder="e.g., pushover"
|
|
1931
|
-
className="w-full bg-[
|
|
1940
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)]"
|
|
1932
1941
|
/>
|
|
1933
1942
|
</div>
|
|
1934
1943
|
|
|
1935
1944
|
{/* Project Scope - only show when projects exist */}
|
|
1936
1945
|
{hasProjects && (
|
|
1937
1946
|
<div>
|
|
1938
|
-
<label className="block text-sm text-[
|
|
1947
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Scope</label>
|
|
1939
1948
|
<Select
|
|
1940
1949
|
value={projectId || ""}
|
|
1941
1950
|
onChange={(value) => setProjectId(value || null)}
|
|
@@ -1945,7 +1954,7 @@ function AddServerModal({
|
|
|
1945
1954
|
]}
|
|
1946
1955
|
placeholder="Select scope..."
|
|
1947
1956
|
/>
|
|
1948
|
-
<p className="text-xs text-[
|
|
1957
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-1">
|
|
1949
1958
|
Global servers are available to all agents. Project-scoped servers are only available to agents in that project.
|
|
1950
1959
|
</p>
|
|
1951
1960
|
</div>
|
|
@@ -1954,15 +1963,15 @@ function AddServerModal({
|
|
|
1954
1963
|
{/* npm Package */}
|
|
1955
1964
|
{mode === "npm" && (
|
|
1956
1965
|
<div>
|
|
1957
|
-
<label className="block text-sm text-[
|
|
1966
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">npm Package</label>
|
|
1958
1967
|
<input
|
|
1959
1968
|
type="text"
|
|
1960
1969
|
value={pkg}
|
|
1961
1970
|
onChange={e => handlePackageChange(e.target.value)}
|
|
1962
1971
|
placeholder="e.g., @modelcontextprotocol/server-filesystem or paste full command"
|
|
1963
|
-
className="w-full bg-[
|
|
1972
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)]"
|
|
1964
1973
|
/>
|
|
1965
|
-
<p className="text-xs text-[
|
|
1974
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-1">
|
|
1966
1975
|
Package name or paste a full npx command with credentials
|
|
1967
1976
|
</p>
|
|
1968
1977
|
</div>
|
|
@@ -1972,7 +1981,7 @@ function AddServerModal({
|
|
|
1972
1981
|
{mode === "pip" && (
|
|
1973
1982
|
<div className="space-y-4">
|
|
1974
1983
|
<div>
|
|
1975
|
-
<label className="block text-sm text-[
|
|
1984
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">pip Package</label>
|
|
1976
1985
|
<input
|
|
1977
1986
|
type="text"
|
|
1978
1987
|
value={pkg}
|
|
@@ -1985,22 +1994,22 @@ function AddServerModal({
|
|
|
1985
1994
|
}
|
|
1986
1995
|
}}
|
|
1987
1996
|
placeholder="e.g., late-sdk[mcp]"
|
|
1988
|
-
className="w-full bg-[
|
|
1997
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)]"
|
|
1989
1998
|
/>
|
|
1990
|
-
<p className="text-xs text-[
|
|
1999
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-1">
|
|
1991
2000
|
Python package with extras, e.g., late-sdk[mcp] or mcp-server-time
|
|
1992
2001
|
</p>
|
|
1993
2002
|
</div>
|
|
1994
2003
|
<div>
|
|
1995
|
-
<label className="block text-sm text-[
|
|
2004
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Module (optional)</label>
|
|
1996
2005
|
<input
|
|
1997
2006
|
type="text"
|
|
1998
2007
|
value={pipModule}
|
|
1999
2008
|
onChange={e => setPipModule(e.target.value)}
|
|
2000
2009
|
placeholder="e.g., late.mcp"
|
|
2001
|
-
className="w-full bg-[
|
|
2010
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2002
2011
|
/>
|
|
2003
|
-
<p className="text-xs text-[
|
|
2012
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-1">
|
|
2004
2013
|
Python module to run with -m. Auto-detected from package name if not specified.
|
|
2005
2014
|
</p>
|
|
2006
2015
|
</div>
|
|
@@ -2010,15 +2019,15 @@ function AddServerModal({
|
|
|
2010
2019
|
{/* Custom Command */}
|
|
2011
2020
|
{mode === "command" && (
|
|
2012
2021
|
<div>
|
|
2013
|
-
<label className="block text-sm text-[
|
|
2022
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Command</label>
|
|
2014
2023
|
<input
|
|
2015
2024
|
type="text"
|
|
2016
2025
|
value={command}
|
|
2017
2026
|
onChange={e => handleCommandChange(e.target.value)}
|
|
2018
2027
|
placeholder="e.g., npx -y pushover-mcp@latest start --token YOUR_TOKEN"
|
|
2019
|
-
className="w-full bg-[
|
|
2028
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2020
2029
|
/>
|
|
2021
|
-
<p className="text-xs text-[
|
|
2030
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-1">
|
|
2022
2031
|
Paste the full command - credentials like YOUR_TOKEN will be auto-extracted
|
|
2023
2032
|
</p>
|
|
2024
2033
|
</div>
|
|
@@ -2028,38 +2037,38 @@ function AddServerModal({
|
|
|
2028
2037
|
{mode === "http" && (
|
|
2029
2038
|
<div className="space-y-4">
|
|
2030
2039
|
<div>
|
|
2031
|
-
<label className="block text-sm text-[
|
|
2040
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">URL</label>
|
|
2032
2041
|
<input
|
|
2033
2042
|
type="text"
|
|
2034
2043
|
value={url}
|
|
2035
2044
|
onChange={e => setUrl(e.target.value)}
|
|
2036
2045
|
placeholder="e.g., https://example.com/wp-json/mcp/v1/messages"
|
|
2037
|
-
className="w-full bg-[
|
|
2046
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2038
2047
|
/>
|
|
2039
2048
|
</div>
|
|
2040
|
-
<div className="p-3 bg-[
|
|
2041
|
-
<p className="text-xs text-[
|
|
2049
|
+
<div className="p-3 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded">
|
|
2050
|
+
<p className="text-xs text-[var(--color-text-muted)] mb-3">
|
|
2042
2051
|
Optional: Basic Auth credentials (will be encoded and stored securely)
|
|
2043
2052
|
</p>
|
|
2044
2053
|
<div className="grid grid-cols-2 gap-3">
|
|
2045
2054
|
<div>
|
|
2046
|
-
<label className="block text-xs text-[
|
|
2055
|
+
<label className="block text-xs text-[var(--color-text-faint)] mb-1">Username</label>
|
|
2047
2056
|
<input
|
|
2048
2057
|
type="text"
|
|
2049
2058
|
value={username}
|
|
2050
2059
|
onChange={e => setUsername(e.target.value)}
|
|
2051
2060
|
placeholder="username"
|
|
2052
|
-
className="w-full bg-[
|
|
2061
|
+
className="w-full bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded px-3 py-2 text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2053
2062
|
/>
|
|
2054
2063
|
</div>
|
|
2055
2064
|
<div>
|
|
2056
|
-
<label className="block text-xs text-[
|
|
2065
|
+
<label className="block text-xs text-[var(--color-text-faint)] mb-1">Password</label>
|
|
2057
2066
|
<input
|
|
2058
2067
|
type="password"
|
|
2059
2068
|
value={password}
|
|
2060
2069
|
onChange={e => setPassword(e.target.value)}
|
|
2061
2070
|
placeholder="password or app key"
|
|
2062
|
-
className="w-full bg-[
|
|
2071
|
+
className="w-full bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded px-3 py-2 text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2063
2072
|
/>
|
|
2064
2073
|
</div>
|
|
2065
2074
|
</div>
|
|
@@ -2070,19 +2079,19 @@ function AddServerModal({
|
|
|
2070
2079
|
{/* Environment Variables / Credentials */}
|
|
2071
2080
|
<div>
|
|
2072
2081
|
<div className="flex items-center justify-between mb-2">
|
|
2073
|
-
<label className="text-sm text-[
|
|
2082
|
+
<label className="text-sm text-[var(--color-text-muted)]">
|
|
2074
2083
|
Environment Variables / Credentials
|
|
2075
2084
|
</label>
|
|
2076
2085
|
<button
|
|
2077
2086
|
onClick={addEnvVar}
|
|
2078
|
-
className="text-xs text-[
|
|
2087
|
+
className="text-xs text-[var(--color-accent)] hover:text-[var(--color-accent-hover)] transition"
|
|
2079
2088
|
>
|
|
2080
2089
|
+ Add Variable
|
|
2081
2090
|
</button>
|
|
2082
2091
|
</div>
|
|
2083
2092
|
|
|
2084
2093
|
{envVars.length === 0 && (
|
|
2085
|
-
<p className="text-xs text-[
|
|
2094
|
+
<p className="text-xs text-[var(--color-text-faint)] bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded p-3">
|
|
2086
2095
|
Add environment variables for API tokens and credentials.
|
|
2087
2096
|
These are stored encrypted and passed to the server at startup.
|
|
2088
2097
|
</p>
|
|
@@ -2097,18 +2106,18 @@ function AddServerModal({
|
|
|
2097
2106
|
value={env.key}
|
|
2098
2107
|
onChange={e => updateEnvVar(index, "key", e.target.value)}
|
|
2099
2108
|
placeholder="KEY"
|
|
2100
|
-
className="w-1/3 bg-[
|
|
2109
|
+
className="w-1/3 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-2 py-1.5 text-sm font-mono focus:outline-none focus:border-[var(--color-accent)]"
|
|
2101
2110
|
/>
|
|
2102
2111
|
<input
|
|
2103
2112
|
type="password"
|
|
2104
2113
|
value={env.value}
|
|
2105
2114
|
onChange={e => updateEnvVar(index, "value", e.target.value)}
|
|
2106
2115
|
placeholder="value"
|
|
2107
|
-
className="flex-1 bg-[
|
|
2116
|
+
className="flex-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-2 py-1.5 text-sm font-mono focus:outline-none focus:border-[var(--color-accent)]"
|
|
2108
2117
|
/>
|
|
2109
2118
|
<button
|
|
2110
2119
|
onClick={() => removeEnvVar(index)}
|
|
2111
|
-
className="text-[
|
|
2120
|
+
className="text-[var(--color-text-muted)] hover:text-red-400 px-2 transition"
|
|
2112
2121
|
>
|
|
2113
2122
|
✕
|
|
2114
2123
|
</button>
|
|
@@ -2121,17 +2130,17 @@ function AddServerModal({
|
|
|
2121
2130
|
{error && <p className="text-red-400 text-sm">{error}</p>}
|
|
2122
2131
|
</div>
|
|
2123
2132
|
|
|
2124
|
-
<div className="p-4 border-t border-[
|
|
2133
|
+
<div className="p-4 border-t border-[var(--color-border)] flex justify-end gap-2 sticky bottom-0 bg-[var(--color-surface)]">
|
|
2125
2134
|
<button
|
|
2126
2135
|
onClick={onClose}
|
|
2127
|
-
className="px-4 py-2 border border-[
|
|
2136
|
+
className="px-4 py-2 border border-[var(--color-border-light)] hover:border-[var(--color-text-muted)] rounded transition"
|
|
2128
2137
|
>
|
|
2129
2138
|
Cancel
|
|
2130
2139
|
</button>
|
|
2131
2140
|
<button
|
|
2132
2141
|
onClick={handleAdd}
|
|
2133
2142
|
disabled={saving || !name || (mode === "npm" ? !pkg : mode === "pip" ? !pkg : mode === "http" ? !url : !command)}
|
|
2134
|
-
className="px-4 py-2 bg-[
|
|
2143
|
+
className="px-4 py-2 bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black rounded font-medium transition disabled:opacity-50"
|
|
2135
2144
|
>
|
|
2136
2145
|
{saving ? "Adding..." : "Add Server"}
|
|
2137
2146
|
</button>
|
|
@@ -2294,37 +2303,37 @@ function EditServerModal({
|
|
|
2294
2303
|
|
|
2295
2304
|
return (
|
|
2296
2305
|
<div className="fixed inset-0 bg-black/50 backdrop-blur-[2px] z-50 flex items-center justify-center p-4">
|
|
2297
|
-
<div className="bg-[
|
|
2298
|
-
<div className="p-4 border-b border-[
|
|
2306
|
+
<div className="bg-[var(--color-surface)] border border-[var(--color-border)] rounded-lg w-full max-w-lg max-h-[90vh] overflow-y-auto">
|
|
2307
|
+
<div className="p-4 border-b border-[var(--color-border)] flex items-center justify-between sticky top-0 bg-[var(--color-surface)]">
|
|
2299
2308
|
<h2 className="text-lg font-semibold">Edit MCP Server</h2>
|
|
2300
|
-
<button onClick={onClose} className="text-[
|
|
2309
|
+
<button onClick={onClose} className="text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]">
|
|
2301
2310
|
✕
|
|
2302
2311
|
</button>
|
|
2303
2312
|
</div>
|
|
2304
2313
|
|
|
2305
2314
|
<div className="p-4 space-y-4">
|
|
2306
2315
|
{/* Server Type Info */}
|
|
2307
|
-
<div className="text-sm text-[
|
|
2308
|
-
Type: <span className="text-[
|
|
2309
|
-
{server.package && <> • Package: <span className="text-[
|
|
2310
|
-
{server.command && <> • Command: <span className="text-[
|
|
2316
|
+
<div className="text-sm text-[var(--color-text-muted)] bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded p-3">
|
|
2317
|
+
Type: <span className="text-[var(--color-text-secondary)]">{server.type}</span>
|
|
2318
|
+
{server.package && <> • Package: <span className="text-[var(--color-text-secondary)] font-mono">{server.package}</span></>}
|
|
2319
|
+
{server.command && <> • Command: <span className="text-[var(--color-text-secondary)] font-mono">{server.command}</span></>}
|
|
2311
2320
|
</div>
|
|
2312
2321
|
|
|
2313
2322
|
{/* Name */}
|
|
2314
2323
|
<div>
|
|
2315
|
-
<label className="block text-sm text-[
|
|
2324
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Name</label>
|
|
2316
2325
|
<input
|
|
2317
2326
|
type="text"
|
|
2318
2327
|
value={name}
|
|
2319
2328
|
onChange={e => setName(e.target.value)}
|
|
2320
|
-
className="w-full bg-[
|
|
2329
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 focus:outline-none focus:border-[var(--color-accent)]"
|
|
2321
2330
|
/>
|
|
2322
2331
|
</div>
|
|
2323
2332
|
|
|
2324
2333
|
{/* Project Scope */}
|
|
2325
2334
|
{hasProjects && (
|
|
2326
2335
|
<div>
|
|
2327
|
-
<label className="block text-sm text-[
|
|
2336
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Scope</label>
|
|
2328
2337
|
<Select
|
|
2329
2338
|
value={projectId || ""}
|
|
2330
2339
|
onChange={(value) => setProjectId(value || null)}
|
|
@@ -2340,12 +2349,12 @@ function EditServerModal({
|
|
|
2340
2349
|
{/* Package (for npm type) */}
|
|
2341
2350
|
{server.type === "npm" && (
|
|
2342
2351
|
<div>
|
|
2343
|
-
<label className="block text-sm text-[
|
|
2352
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">npm Package</label>
|
|
2344
2353
|
<input
|
|
2345
2354
|
type="text"
|
|
2346
2355
|
value={pkg}
|
|
2347
2356
|
onChange={e => setPkg(e.target.value)}
|
|
2348
|
-
className="w-full bg-[
|
|
2357
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2349
2358
|
/>
|
|
2350
2359
|
</div>
|
|
2351
2360
|
)}
|
|
@@ -2353,12 +2362,12 @@ function EditServerModal({
|
|
|
2353
2362
|
{/* Package (for pip type) */}
|
|
2354
2363
|
{server.type === "pip" && (
|
|
2355
2364
|
<div>
|
|
2356
|
-
<label className="block text-sm text-[
|
|
2365
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">pip Package</label>
|
|
2357
2366
|
<input
|
|
2358
2367
|
type="text"
|
|
2359
2368
|
value={pkg}
|
|
2360
2369
|
onChange={e => setPkg(e.target.value)}
|
|
2361
|
-
className="w-full bg-[
|
|
2370
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2362
2371
|
/>
|
|
2363
2372
|
</div>
|
|
2364
2373
|
)}
|
|
@@ -2367,34 +2376,34 @@ function EditServerModal({
|
|
|
2367
2376
|
{isRemote && (
|
|
2368
2377
|
<>
|
|
2369
2378
|
<div>
|
|
2370
|
-
<label className="block text-sm text-[
|
|
2379
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Server URL</label>
|
|
2371
2380
|
<input
|
|
2372
2381
|
type="text"
|
|
2373
2382
|
value={url}
|
|
2374
2383
|
onChange={e => setUrl(e.target.value)}
|
|
2375
2384
|
placeholder="https://example.com/mcp"
|
|
2376
|
-
className="w-full bg-[
|
|
2385
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2377
2386
|
/>
|
|
2378
2387
|
</div>
|
|
2379
2388
|
<div>
|
|
2380
|
-
<label className="block text-sm text-[
|
|
2389
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Authentication (Basic Auth)</label>
|
|
2381
2390
|
<div className="flex gap-2">
|
|
2382
2391
|
<input
|
|
2383
2392
|
type="text"
|
|
2384
2393
|
value={username}
|
|
2385
2394
|
onChange={e => setUsername(e.target.value)}
|
|
2386
2395
|
placeholder="Username"
|
|
2387
|
-
className="flex-1 bg-[
|
|
2396
|
+
className="flex-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2388
2397
|
/>
|
|
2389
2398
|
<input
|
|
2390
2399
|
type="password"
|
|
2391
2400
|
value={password}
|
|
2392
2401
|
onChange={e => setPassword(e.target.value)}
|
|
2393
2402
|
placeholder="Password / App Password"
|
|
2394
|
-
className="flex-1 bg-[
|
|
2403
|
+
className="flex-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2395
2404
|
/>
|
|
2396
2405
|
</div>
|
|
2397
|
-
<p className="text-xs text-[
|
|
2406
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-1">
|
|
2398
2407
|
Leave empty if no authentication required
|
|
2399
2408
|
</p>
|
|
2400
2409
|
</div>
|
|
@@ -2405,22 +2414,22 @@ function EditServerModal({
|
|
|
2405
2414
|
{server.type === "custom" && (
|
|
2406
2415
|
<>
|
|
2407
2416
|
<div>
|
|
2408
|
-
<label className="block text-sm text-[
|
|
2417
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Command</label>
|
|
2409
2418
|
<input
|
|
2410
2419
|
type="text"
|
|
2411
2420
|
value={command}
|
|
2412
2421
|
onChange={e => setCommand(e.target.value)}
|
|
2413
|
-
className="w-full bg-[
|
|
2422
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2414
2423
|
/>
|
|
2415
2424
|
</div>
|
|
2416
2425
|
<div>
|
|
2417
|
-
<label className="block text-sm text-[
|
|
2426
|
+
<label className="block text-sm text-[var(--color-text-muted)] mb-1">Arguments</label>
|
|
2418
2427
|
<input
|
|
2419
2428
|
type="text"
|
|
2420
2429
|
value={args}
|
|
2421
2430
|
onChange={e => setArgs(e.target.value)}
|
|
2422
2431
|
placeholder="e.g., --token $TOKEN --verbose"
|
|
2423
|
-
className="w-full bg-[
|
|
2432
|
+
className="w-full bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-3 py-2 font-mono text-sm focus:outline-none focus:border-[var(--color-accent)]"
|
|
2424
2433
|
/>
|
|
2425
2434
|
</div>
|
|
2426
2435
|
</>
|
|
@@ -2430,19 +2439,19 @@ function EditServerModal({
|
|
|
2430
2439
|
{!isRemote && (
|
|
2431
2440
|
<div>
|
|
2432
2441
|
<div className="flex items-center justify-between mb-2">
|
|
2433
|
-
<label className="text-sm text-[
|
|
2442
|
+
<label className="text-sm text-[var(--color-text-muted)]">
|
|
2434
2443
|
Environment Variables / Credentials
|
|
2435
2444
|
</label>
|
|
2436
2445
|
<button
|
|
2437
2446
|
onClick={addEnvVar}
|
|
2438
|
-
className="text-xs text-[
|
|
2447
|
+
className="text-xs text-[var(--color-accent)] hover:text-[var(--color-accent-hover)] transition"
|
|
2439
2448
|
>
|
|
2440
2449
|
+ Add Variable
|
|
2441
2450
|
</button>
|
|
2442
2451
|
</div>
|
|
2443
2452
|
|
|
2444
2453
|
{envVars.length === 0 && (
|
|
2445
|
-
<p className="text-xs text-[
|
|
2454
|
+
<p className="text-xs text-[var(--color-text-faint)] bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded p-3">
|
|
2446
2455
|
No environment variables configured.
|
|
2447
2456
|
</p>
|
|
2448
2457
|
)}
|
|
@@ -2456,18 +2465,18 @@ function EditServerModal({
|
|
|
2456
2465
|
value={env.key}
|
|
2457
2466
|
onChange={e => updateEnvVar(index, "key", e.target.value)}
|
|
2458
2467
|
placeholder="KEY"
|
|
2459
|
-
className="w-1/3 bg-[
|
|
2468
|
+
className="w-1/3 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-2 py-1.5 text-sm font-mono focus:outline-none focus:border-[var(--color-accent)]"
|
|
2460
2469
|
/>
|
|
2461
2470
|
<input
|
|
2462
2471
|
type="password"
|
|
2463
2472
|
value={env.value}
|
|
2464
2473
|
onChange={e => updateEnvVar(index, "value", e.target.value)}
|
|
2465
2474
|
placeholder="value"
|
|
2466
|
-
className="flex-1 bg-[
|
|
2475
|
+
className="flex-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded px-2 py-1.5 text-sm font-mono focus:outline-none focus:border-[var(--color-accent)]"
|
|
2467
2476
|
/>
|
|
2468
2477
|
<button
|
|
2469
2478
|
onClick={() => removeEnvVar(index)}
|
|
2470
|
-
className="text-[
|
|
2479
|
+
className="text-[var(--color-text-muted)] hover:text-red-400 px-2 transition"
|
|
2471
2480
|
>
|
|
2472
2481
|
✕
|
|
2473
2482
|
</button>
|
|
@@ -2476,7 +2485,7 @@ function EditServerModal({
|
|
|
2476
2485
|
</div>
|
|
2477
2486
|
)}
|
|
2478
2487
|
|
|
2479
|
-
<p className="text-xs text-[
|
|
2488
|
+
<p className="text-xs text-[var(--color-text-faint)] mt-2">
|
|
2480
2489
|
{server.status === "running" ? "Server will be automatically restarted to apply changes." : "Changes will take effect when the server is started."}
|
|
2481
2490
|
</p>
|
|
2482
2491
|
</div>
|
|
@@ -2485,17 +2494,17 @@ function EditServerModal({
|
|
|
2485
2494
|
{error && <p className="text-red-400 text-sm">{error}</p>}
|
|
2486
2495
|
</div>
|
|
2487
2496
|
|
|
2488
|
-
<div className="p-4 border-t border-[
|
|
2497
|
+
<div className="p-4 border-t border-[var(--color-border)] flex justify-end gap-2 sticky bottom-0 bg-[var(--color-surface)]">
|
|
2489
2498
|
<button
|
|
2490
2499
|
onClick={onClose}
|
|
2491
|
-
className="px-4 py-2 border border-[
|
|
2500
|
+
className="px-4 py-2 border border-[var(--color-border-light)] hover:border-[var(--color-text-muted)] rounded transition"
|
|
2492
2501
|
>
|
|
2493
2502
|
Cancel
|
|
2494
2503
|
</button>
|
|
2495
2504
|
<button
|
|
2496
2505
|
onClick={handleSave}
|
|
2497
2506
|
disabled={saving || !name.trim()}
|
|
2498
|
-
className="px-4 py-2 bg-[
|
|
2507
|
+
className="px-4 py-2 bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] text-black rounded font-medium transition disabled:opacity-50"
|
|
2499
2508
|
>
|
|
2500
2509
|
{saving ? "Saving..." : "Save Changes"}
|
|
2501
2510
|
</button>
|