@loop_ouroboros/mcp-hub-lite 1.2.2 → 1.2.4
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/CHANGELOG.md +552 -380
- package/dist/client/assets/{HomeView-V1fKvWQ8.js → HomeView-BnO4yIT9.js} +1 -1
- package/dist/client/assets/{ResourceDetailView-DHGHssrh.js → ResourceDetailView-BGBtmsyc.js} +1 -1
- package/dist/client/assets/{ResourcesView-B1bvkmQD.js → ResourcesView-B5Xg0ynh.js} +1 -1
- package/dist/client/assets/{ServerDashboard-CZCByd7y.js → ServerDashboard-DYAVrrUk.js} +1 -1
- package/dist/client/assets/{ServerDetail-CI5UD8gj.js → ServerDetail-q94ZFfjL.js} +1 -1
- package/dist/client/assets/ServerListView-C7kcd4GC.js +36 -0
- package/dist/client/assets/{ServerListView-B-bPljsO.css → ServerListView-DshgDGSc.css} +1 -1
- package/dist/client/assets/{SettingsView-C-ae0-zz.js → SettingsView-BM6P5yrT.js} +1 -1
- package/dist/client/assets/{ToolCallDialog-BudOyGvS.js → ToolCallDialog-BoAGxlB5.js} +1 -1
- package/dist/client/assets/{ToolsView-CbQkgTAu.js → ToolsView-lqFhr7Bk.js} +1 -1
- package/dist/client/assets/{_baseClone-e9R6V78L.js → _baseClone-kbJbcBJT.js} +1 -1
- package/dist/client/assets/{el-form-item-Dyx5MiWB.js → el-form-item-iQ0G8e97.js} +1 -1
- package/dist/client/assets/{el-input-CL9HPfdW.js → el-input-DkJq57wP.js} +1 -1
- package/dist/client/assets/{el-loading-2TW6JdfY.js → el-loading-C3v6a9xV.js} +1 -1
- package/dist/client/assets/{el-overlay-B5ZGCmXY.js → el-overlay-Cy5xg31y.js} +1 -1
- package/dist/client/assets/{el-radio-group-Cr2ScjjJ.js → el-radio-group-C9QUL5mm.js} +1 -1
- package/dist/client/assets/{el-skeleton-item-CdAfEgVR.js → el-skeleton-item-Bbmpc0Xz.js} +1 -1
- package/dist/client/assets/{el-switch-DnN1s0Wb.js → el-switch-KpjV93lm.js} +1 -1
- package/dist/client/assets/{el-tab-pane-BebZh0XF.js → el-tab-pane-YsYuBcem.js} +1 -1
- package/dist/client/assets/{el-table-column-CV2zp3yI.js → el-table-column-fofd_2n-.js} +1 -1
- package/dist/client/assets/{index-Ci5n5dA9.js → index-5tzIwwtS.js} +1 -1
- package/dist/client/assets/{index-DTZ9o3XO.js → index-MqHvQjDP.js} +2 -2
- package/dist/client/assets/{omit-DlmW8Yd6.js → omit-CB4hTeTH.js} +1 -1
- package/dist/client/assets/{raf-CeCd08aN.js → raf-MWAHt9ca.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/server/src/cli/commands/install.d.ts +25 -0
- package/dist/server/src/cli/commands/install.d.ts.map +1 -0
- package/dist/server/src/cli/commands/install.js +274 -0
- package/dist/server/src/cli/commands/use-guide.d.ts +11 -0
- package/dist/server/src/cli/commands/use-guide.d.ts.map +1 -0
- package/dist/server/src/cli/commands/use-guide.js +175 -0
- package/dist/server/src/cli/index.d.ts.map +1 -1
- package/dist/server/src/cli/index.js +4 -0
- package/dist/server/src/cli/server.d.ts +71 -0
- package/dist/server/src/cli/server.d.ts.map +1 -1
- package/dist/server/src/cli/server.js +138 -0
- package/dist/server/src/cli/use-guide.md +156 -0
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.js +12 -5
- package/dist/server/src/services/hub-tools.service.d.ts.map +1 -1
- package/dist/server/src/services/hub-tools.service.js +4 -0
- package/package.json +1 -5
- package/dist/client/assets/ServerListView-D8qv-xYg.js +0 -36
|
@@ -244,3 +244,141 @@ export async function listServers() {
|
|
|
244
244
|
instances: serverInstances[server.name] || []
|
|
245
245
|
}));
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Installs a new MCP server via the web API.
|
|
249
|
+
*
|
|
250
|
+
* This function sends a POST request to the /web/servers endpoint to add a new
|
|
251
|
+
* server configuration. If the instance selection strategy is not 'random', it
|
|
252
|
+
* sends an additional PUT request to update the strategy.
|
|
253
|
+
*
|
|
254
|
+
* @param options - Server installation options
|
|
255
|
+
* @param host - Server host address
|
|
256
|
+
* @param port - Server port number
|
|
257
|
+
* @returns Promise that resolves when installation completes
|
|
258
|
+
* @throws Error if the server already exists or the API request fails
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* await installServer({
|
|
263
|
+
* name: 'github-mcp',
|
|
264
|
+
* command: 'npx github-mcp',
|
|
265
|
+
* transport: 'stdio',
|
|
266
|
+
* env: { API_KEY: 'xxx' },
|
|
267
|
+
* timeout: 60,
|
|
268
|
+
* autoStart: true,
|
|
269
|
+
* instanceSelectionStrategy: 'random'
|
|
270
|
+
* }, 'localhost', 7788);
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
export async function installServer(options, host, port) {
|
|
274
|
+
// Build request payload
|
|
275
|
+
const payload = {
|
|
276
|
+
name: options.name,
|
|
277
|
+
config: {
|
|
278
|
+
type: options.transport,
|
|
279
|
+
command: options.command,
|
|
280
|
+
url: options.url,
|
|
281
|
+
args: options.args || [],
|
|
282
|
+
env: options.env || {},
|
|
283
|
+
headers: options.headers || {},
|
|
284
|
+
timeout: options.timeout * 1000,
|
|
285
|
+
enabled: options.autoStart,
|
|
286
|
+
description: options.description,
|
|
287
|
+
instanceSelectionStrategy: options.instanceSelectionStrategy !== 'random'
|
|
288
|
+
? options.instanceSelectionStrategy
|
|
289
|
+
: undefined
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
// Call POST /web/servers to install
|
|
293
|
+
const response = await fetch(`http://${host}:${port}/web/servers`, {
|
|
294
|
+
method: 'POST',
|
|
295
|
+
headers: { 'Content-Type': 'application/json' },
|
|
296
|
+
body: JSON.stringify(payload)
|
|
297
|
+
});
|
|
298
|
+
if (!response.ok) {
|
|
299
|
+
const errorData = (await response.json().catch(() => ({ message: response.statusText })));
|
|
300
|
+
const errorMessage = errorData.message || response.statusText;
|
|
301
|
+
if (errorMessage.includes('already exists')) {
|
|
302
|
+
throw new Error(`Server "${options.name}" already exists`);
|
|
303
|
+
}
|
|
304
|
+
throw new Error(`Failed to install server: ${errorMessage}`);
|
|
305
|
+
}
|
|
306
|
+
// If strategy is not random, update via PUT
|
|
307
|
+
if (options.instanceSelectionStrategy !== 'random') {
|
|
308
|
+
const putResponse = await fetch(`http://${host}:${port}/web/servers/${options.name}`, {
|
|
309
|
+
method: 'PUT',
|
|
310
|
+
headers: { 'Content-Type': 'application/json' },
|
|
311
|
+
body: JSON.stringify({ instanceSelectionStrategy: options.instanceSelectionStrategy })
|
|
312
|
+
});
|
|
313
|
+
if (!putResponse.ok) {
|
|
314
|
+
const errorData = (await putResponse
|
|
315
|
+
.json()
|
|
316
|
+
.catch(() => ({ message: putResponse.statusText })));
|
|
317
|
+
throw new Error(`Server installed but failed to set strategy: ${errorData.message || putResponse.statusText}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Parses environment variable flags into a key-value object.
|
|
323
|
+
*
|
|
324
|
+
* @param envFlags - Array of environment variables in KEY=VALUE format
|
|
325
|
+
* @returns Record of environment variable key-value pairs
|
|
326
|
+
* @throws Error if the format is invalid
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```typescript
|
|
330
|
+
* parseEnvVars(['API_KEY=xxx', 'DEBUG=true'])
|
|
331
|
+
* // Returns: { API_KEY: 'xxx', DEBUG: 'true' }
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
export function parseEnvVars(envFlags) {
|
|
335
|
+
const env = {};
|
|
336
|
+
for (const item of envFlags) {
|
|
337
|
+
const equalIndex = item.indexOf('=');
|
|
338
|
+
if (equalIndex === -1) {
|
|
339
|
+
throw new Error(`Invalid env format: ${item}, expected KEY=VALUE`);
|
|
340
|
+
}
|
|
341
|
+
const key = item.substring(0, equalIndex);
|
|
342
|
+
const value = item.substring(equalIndex + 1);
|
|
343
|
+
if (!key) {
|
|
344
|
+
throw new Error(`Invalid env format: ${item}, KEY cannot be empty`);
|
|
345
|
+
}
|
|
346
|
+
if (value === undefined) {
|
|
347
|
+
throw new Error(`Invalid env format: ${item}, VALUE cannot be empty`);
|
|
348
|
+
}
|
|
349
|
+
env[key] = value;
|
|
350
|
+
}
|
|
351
|
+
return env;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Parses HTTP header flags into a key-value object.
|
|
355
|
+
*
|
|
356
|
+
* @param headerFlags - Array of headers in "Key: Value" format
|
|
357
|
+
* @returns Record of header key-value pairs
|
|
358
|
+
* @throws Error if the format is invalid
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```typescript
|
|
362
|
+
* parseHeaders(['Authorization: Bearer xxx', 'Content-Type: application/json'])
|
|
363
|
+
* // Returns: { Authorization: 'Bearer xxx', 'Content-Type': 'application/json' }
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
export function parseHeaders(headerFlags) {
|
|
367
|
+
const headers = {};
|
|
368
|
+
for (const item of headerFlags) {
|
|
369
|
+
const colonIndex = item.indexOf(':');
|
|
370
|
+
if (colonIndex === -1) {
|
|
371
|
+
throw new Error(`Invalid header format: ${item}, expected "Key: Value"`);
|
|
372
|
+
}
|
|
373
|
+
const key = item.substring(0, colonIndex).trim();
|
|
374
|
+
const value = item.substring(colonIndex + 1).trim();
|
|
375
|
+
if (!key) {
|
|
376
|
+
throw new Error(`Invalid header format: ${item}, KEY cannot be empty`);
|
|
377
|
+
}
|
|
378
|
+
if (!value) {
|
|
379
|
+
throw new Error(`Invalid header format: ${item}, VALUE cannot be empty`);
|
|
380
|
+
}
|
|
381
|
+
headers[key] = value;
|
|
382
|
+
}
|
|
383
|
+
return headers;
|
|
384
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# MCP Hub Lite CLI Use Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
MCP Hub Lite CLI provides command-line interface for managing MCP servers. This guide covers CLI-specific usage only.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
### start
|
|
10
|
+
|
|
11
|
+
Start the MCP Hub Lite server.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Start in daemon mode (default)
|
|
15
|
+
mcp-hub-lite start
|
|
16
|
+
|
|
17
|
+
# Start in foreground mode
|
|
18
|
+
mcp-hub-lite start --foreground
|
|
19
|
+
|
|
20
|
+
# Start with custom port
|
|
21
|
+
mcp-hub-lite start --port 8080
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### stop
|
|
25
|
+
|
|
26
|
+
Stop the running MCP Hub Lite server.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
mcp-hub-lite stop
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### status
|
|
33
|
+
|
|
34
|
+
Display server status and connected MCP servers.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
mcp-hub-lite status
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### ui
|
|
41
|
+
|
|
42
|
+
Open the web UI in default browser.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mcp-hub-lite ui
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### list
|
|
49
|
+
|
|
50
|
+
List all configured MCP servers.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
mcp-hub-lite list
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### restart
|
|
57
|
+
|
|
58
|
+
Restart the MCP Hub Lite server.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
mcp-hub-lite restart
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### install
|
|
65
|
+
|
|
66
|
+
Add a new MCP server to MCP Hub Lite.
|
|
67
|
+
|
|
68
|
+
**Parametric Mode:**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# stdio server
|
|
72
|
+
mcp-hub-lite install github-mcp "npx github-mcp" --env API_KEY=xxx
|
|
73
|
+
|
|
74
|
+
# HTTP server
|
|
75
|
+
mcp-hub-lite install api-server https://api.example.com/mcp -t streamable-http -H "Authorization: Bearer xxx"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**JSON Mode:**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# stdio server
|
|
82
|
+
mcp-hub-lite install --json '{"name":"github-mcp","type":"stdio","command":"npx github-mcp","env":{"API_KEY":"xxx"}}'
|
|
83
|
+
|
|
84
|
+
# HTTP server
|
|
85
|
+
mcp-hub-lite install --json '{"name":"api-server","type":"streamable-http","url":"https://api.example.com/mcp","headers":{"Authorization":"Bearer xxx"}}'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Options:**
|
|
89
|
+
|
|
90
|
+
| Option | Description |
|
|
91
|
+
| -------------------------- | ------------------------------------------------------------ |
|
|
92
|
+
| `-t, --transport <type>` | Transport type: stdio, sse, streamable-http (default: stdio) |
|
|
93
|
+
| `-e, --env <env...>` | Environment variables (KEY=VALUE) |
|
|
94
|
+
| `-H, --header <header...>` | HTTP headers (Header-Key: Value) |
|
|
95
|
+
| `--timeout <seconds>` | Timeout in seconds (default: 60) |
|
|
96
|
+
| `--strategy <strategy>` | Instance selection: random, round-robin, tag-match-unique |
|
|
97
|
+
| `-a, --auto-start` | Auto-start server (default: true) |
|
|
98
|
+
| `--no-auto-start` | Disable auto-start |
|
|
99
|
+
| `-d, --description <desc>` | Server description |
|
|
100
|
+
|
|
101
|
+
**JSON Config Fields:**
|
|
102
|
+
|
|
103
|
+
| Field | Required | Description |
|
|
104
|
+
| --------------------------- | ----------- | ------------------------------- |
|
|
105
|
+
| `name` | Yes | Server name |
|
|
106
|
+
| `type` | No | Transport type (default: stdio) |
|
|
107
|
+
| `command` | Yes (stdio) | Command to execute |
|
|
108
|
+
| `url` | Yes (HTTP) | Server URL |
|
|
109
|
+
| `args` | No | Command arguments |
|
|
110
|
+
| `env` | No | Environment variables object |
|
|
111
|
+
| `headers` | No | HTTP headers object |
|
|
112
|
+
| `timeout` | No | Timeout in seconds |
|
|
113
|
+
| `enabled` | No | Auto-start enabled |
|
|
114
|
+
| `description` | No | Server description |
|
|
115
|
+
| `instanceSelectionStrategy` | No | Instance selection strategy |
|
|
116
|
+
|
|
117
|
+
### tool-use
|
|
118
|
+
|
|
119
|
+
Manage MCP server tools via API.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# List all connected servers
|
|
123
|
+
mcp-hub-lite tool-use list-servers
|
|
124
|
+
|
|
125
|
+
# List system tools
|
|
126
|
+
mcp-hub-lite tool-use list-tools
|
|
127
|
+
|
|
128
|
+
# List tools from specific server
|
|
129
|
+
mcp-hub-lite tool-use list-tools --server baidu-search
|
|
130
|
+
|
|
131
|
+
# Get tool schema
|
|
132
|
+
mcp-hub-lite tool-use get-tool --tool list_tools
|
|
133
|
+
|
|
134
|
+
# Call a tool
|
|
135
|
+
mcp-hub-lite tool-use call-tool --tool search --server baidu-search --args '{"query":"天气"}'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Options:**
|
|
139
|
+
|
|
140
|
+
| Option | Description |
|
|
141
|
+
| ----------------- | ------------------------------------------- |
|
|
142
|
+
| `--server <name>` | Server name (default: mcp-hub-lite) |
|
|
143
|
+
| `--tool <name>` | Tool name (required for get-tool/call-tool) |
|
|
144
|
+
| `--args <json>` | Tool arguments JSON |
|
|
145
|
+
| `--tags <json>` | Instance selection tags |
|
|
146
|
+
|
|
147
|
+
**JSON Merge Form:**
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# All parameters in one JSON
|
|
151
|
+
mcp-hub-lite tool-use call-tool --args '{"server":"baidu-search","tool":"search","query":"天气"}'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
_Last updated: 2026-04-20_
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/initialize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"initialize-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/initialize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqElE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { logger, LOG_MODULES } from '../../../utils/logger/index.js';
|
|
2
|
+
import { getGatewayDebugSetting } from '../../../utils/json-utils.js';
|
|
2
3
|
import { MCP_HUB_LITE_SERVER } from '../../../models/system-tools.constants.js';
|
|
3
4
|
import { getAppVersion, getProtocolVersion } from '../../../utils/version.js';
|
|
4
5
|
import { InitializedNotificationSchema, InitializeRequestSchema, PingRequestSchema } from './initialize.constants.js';
|
|
@@ -13,8 +14,10 @@ export function registerInitializeHandlers(server) {
|
|
|
13
14
|
const { name, version } = request.params.clientInfo;
|
|
14
15
|
const protocolVersion = request.params?.protocolVersion || getProtocolVersion();
|
|
15
16
|
const clientCapabilities = request.params?.capabilities;
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
if (getGatewayDebugSetting()) {
|
|
18
|
+
logger.debug(`Initialized client: Name=${name}, Version=${version}, ProtocolVersion=${protocolVersion}`, LOG_MODULES.GATEWAY);
|
|
19
|
+
}
|
|
20
|
+
if (getGatewayDebugSetting() && clientCapabilities?.roots) {
|
|
18
21
|
logger.debug(`Client ${name} supports roots capability`, LOG_MODULES.GATEWAY);
|
|
19
22
|
}
|
|
20
23
|
}
|
|
@@ -41,11 +44,15 @@ export function registerInitializeHandlers(server) {
|
|
|
41
44
|
return { pong: true };
|
|
42
45
|
});
|
|
43
46
|
server.server.setNotificationHandler(InitializedNotificationSchema, async (notification) => {
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (getGatewayDebugSetting()) {
|
|
48
|
+
logger.debug('Received initialized notification from client', LOG_MODULES.GATEWAY);
|
|
49
|
+
logger.debug(`Initialized notification details: ${JSON.stringify(notification)}`, LOG_MODULES.GATEWAY);
|
|
50
|
+
}
|
|
46
51
|
try {
|
|
47
52
|
// Process the notification
|
|
48
|
-
|
|
53
|
+
if (getGatewayDebugSetting()) {
|
|
54
|
+
logger.debug('Successfully processed initialized notification', LOG_MODULES.GATEWAY);
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
catch (error) {
|
|
51
58
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hub-tools.service.d.ts","sourceRoot":"","sources":["../../../../src/services/hub-tools.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAOjE,OAAO,EAEL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,8BAA8B,EAE/B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,aAAa,EACb,cAAc,EACd,6BAA6B,EAC9B,MAAM,mCAAmC,CAAC;AAW3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,OAAO,CAAC,uBAAuB,CAA2B;;IAyB1D;;;;;;;;;OASG;IACH,cAAc;IAId;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAyBpD;;;;;;;;;;;OAWG;IACG,iBAAiB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC;QAC9D,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,WAAW,EAAE,CAAC;KACtB,CAAC;IA4CF;;;;;;;;;;OAUG;IACG,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAyB7D;;;;;;;;;;OAUG;IACG,uBAAuB,CAAC,IAAI,EAAE,6BAA6B,GAAG,OAAO,CAAC;QAC1E,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;
|
|
1
|
+
{"version":3,"file":"hub-tools.service.d.ts","sourceRoot":"","sources":["../../../../src/services/hub-tools.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -215,6 +215,10 @@ export class HubToolsService {
|
|
|
215
215
|
async updateServerDescription(args) {
|
|
216
216
|
// Handle both direct call (UpdateServerDescriptionParams) and call_tool wrapper (CallToolParams with nested toolArgs)
|
|
217
217
|
const { serverName, description } = 'toolArgs' in args && args.toolArgs ? args.toolArgs : args;
|
|
218
|
+
// Check if trying to update the gateway itself
|
|
219
|
+
if (serverName === MCP_HUB_LITE_SERVER) {
|
|
220
|
+
throw new Error(`Gateway server "${MCP_HUB_LITE_SERVER}" is not a configurable server and cannot be updated`);
|
|
221
|
+
}
|
|
218
222
|
// Validate server exists
|
|
219
223
|
const existing = hubManager.getServerByName(serverName);
|
|
220
224
|
if (!existing) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loop_ouroboros/mcp-hub-lite",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "A lightweight MCP management platform designed for independent developers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "loop_ouroboros",
|
|
@@ -38,10 +38,6 @@
|
|
|
38
38
|
"start": "node dist/server/src/cli/index.js start",
|
|
39
39
|
"stop": "node dist/server/src/cli/index.js stop",
|
|
40
40
|
"restart": "node dist/server/src/cli/index.js restart",
|
|
41
|
-
"status": "node dist/server/src/cli/index.js status",
|
|
42
|
-
"list": "node dist/server/src/cli/index.js list",
|
|
43
|
-
"ui": "node dist/server/src/cli/index.js ui",
|
|
44
|
-
"tool-use": "node dist/server/src/cli/index.js tool-use",
|
|
45
41
|
"dev": "run-p dev:client dev:server",
|
|
46
42
|
"dev:client": "vite",
|
|
47
43
|
"dev:server": "tsx src/server/dev-server.ts",
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import{b as pe,d as ve,_ as fe,e as ge,f as ye,g as be,u as oe,h as re,j as Z,p as q,k as he,E as Se,l as $e,v as ke,r as _e,m as Ve,s as we,t as Ce,n as Ae}from"./index-DTZ9o3XO.js";import{E as xe,a as Ee}from"./el-input-CL9HPfdW.js";import{a as Ie,E as Ue}from"./el-skeleton-item-CdAfEgVR.js";import{t as le,x as d,A as y,J as O,u as p,v as ee,a9 as g,$ as n,V as I,C as s,K as De,a6 as se,c as Pe,r as C,h as Te,y as N,G as r,O as t,P as F,af as L,j as ze,a7 as je,I as R}from"./vue-vendor-CbgVSHIh.js";import{E as Me,a as Je,b as Be}from"./el-overlay-B5ZGCmXY.js";import{E as Fe,a as Oe}from"./el-form-item-Dyx5MiWB.js";import{E as Ne,a as He}from"./el-switch-DnN1s0Wb.js";import{E as h}from"./index-Ci5n5dA9.js";import{_ as Re}from"./ServerStatusTags.vue_vue_type_script_setup_true_lang-BHhwEuGe.js";import{_ as Le}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./typescript-Bp3YSIOJ.js";import"./event-BB_Ol6Sd.js";import"./_baseClone-e9R6V78L.js";const qe=pe({header:{type:String,default:""},footer:{type:String,default:""},bodyStyle:{type:ve([String,Object,Array]),default:""},headerClass:String,bodyClass:String,footerClass:String,shadow:{type:String,values:["always","hover","never"],default:void 0}}),Ge=le({name:"ElCard",__name:"card",props:qe,setup(Q){const S=ge("card"),x=ye("card");return(v,k)=>{var U;return d(),y("div",{class:O([p(x).b(),p(x).is(`${v.shadow||((U=p(S))==null?void 0:U.shadow)||"always"}-shadow`)])},[v.$slots.header||v.header?(d(),y("div",{key:0,class:O([p(x).e("header"),v.headerClass])},[ee(v.$slots,"header",{},()=>[g(n(v.header),1)])],2)):I("v-if",!0),s("div",{class:O([p(x).e("body"),v.bodyClass]),style:De(v.bodyStyle)},[ee(v.$slots,"default")],6),v.$slots.footer||v.footer?(d(),y("div",{key:1,class:O([p(x).e("footer"),v.footerClass])},[ee(v.$slots,"footer",{},()=>[g(n(v.footer),1)])],2)):I("v-if",!0)],2)}}});var Ke=fe(Ge,[["__file","/home/runner/work/element-plus/element-plus/packages/components/card/src/card.vue"]]);const Qe=be(Ke),We={class:"flex gap-4 w-full"},Xe={class:"text-xs text-gray-400"},Ye={class:"text-xs text-gray-400"},Ze={class:"text-xs text-gray-400"},el={class:"w-full flex flex-col gap-2",style:{display:"flex","flex-direction":"column",width:"100%"}},ll={class:"w-full flex flex-col gap-2",style:{display:"flex","flex-direction":"column",width:"100%"}},tl={class:"w-full flex flex-col gap-2",style:{display:"flex","flex-direction":"column",width:"100%"}},al={class:"dialog-footer flex justify-between w-full"},ol={class:"flex gap-2"},rl={key:0,class:"mb-4"},sl={class:"text-green-500 mb-2"},nl={class:"card-header"},il={class:"space-y-2"},dl={key:1,class:"mb-4"},ul={class:"text-red-500 mb-2"},cl={class:"card-header"},ml={class:"space-y-2"},pl={class:"font-bold"},vl={class:"text-sm text-gray-400"},ae=`{
|
|
2
|
-
"mcpServers": {
|
|
3
|
-
}
|
|
4
|
-
}`,fl=le({__name:"AddServerModal",props:{modelValue:{type:Boolean},initialMode:{}},emits:["update:modelValue"],setup(Q,{emit:S}){const x=Q,v=S,{t:k}=se(),U=oe(),j=Pe({get:()=>x.modelValue,set:l=>v("update:modelValue",l)}),_=C(!1),D=C(!1),E=C(!1);Te(j,l=>{l&&x.initialMode==="json"&&(_.value=!0)});const M=C(ae),J=C(`{
|
|
5
|
-
"mcpServers": {
|
|
6
|
-
"server1": {
|
|
7
|
-
"command": "npx @anthropic-ai/mcp",
|
|
8
|
-
"args": ["--model", "claude-3-opus-20250620"],
|
|
9
|
-
"enabled": true,
|
|
10
|
-
"description": "A sample MCP server using stdio transport"
|
|
11
|
-
},
|
|
12
|
-
"server2": {
|
|
13
|
-
"type": "streamable-http",
|
|
14
|
-
"url": "http://localhost:3000",
|
|
15
|
-
"headers": { "Authorization": "Bearer token" },
|
|
16
|
-
"enabled": true,
|
|
17
|
-
"description": "A sample MCP server using HTTP transport"
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}`),B=C({success:[],errors:[]}),a=C({transport:"stdio",name:"",description:"",command:"",args:[],url:"",timeout:60,autoStart:!0,instanceSelectionStrategy:"random"}),P=C([]),i=C([]);function f(){try{const l=JSON.parse(M.value);let e=l,c="";if(l.mcpServers){const m=Object.keys(l.mcpServers);m.length>0&&(c=m[0]||"",e=l.mcpServers[c])}c&&(a.value.name=c),e.command?(a.value.transport="stdio",a.value.command=e.command,a.value.args=e.args||[]):e.url&&(a.value.transport=e.type==="sse"?"sse":"streamable-http",a.value.url=e.url),e.timeout&&(a.value.timeout=e.timeout/1e3),e.enabled!==void 0&&(a.value.autoStart=e.enabled),e.env&&(P.value=Object.entries(e.env).map(([m,b])=>({key:m,value:String(b)}))),e.headers&&(i.value=Object.entries(e.headers).map(([m,b])=>({key:m,value:String(b)}))),e.description&&(a.value.description=e.description),_.value=!1,h.success(k("action.configImported"))}catch(l){l instanceof Error?h.error(k("error.invalidJsonConfig")+": "+l.message):h.error(k("error.invalidJsonConfig")+": "+String(l))}}async function A(){try{const l=JSON.parse(J.value);if(!l.mcpServers||typeof l.mcpServers!="object"){h.error('Invalid JSON format: missing "mcpServers" object');return}D.value=!1,G(),h.success(k("action.serverAdded")),U.importServersFromJson(l).catch(e=>{console.error("Import error:",e),e instanceof Error?h.error("Import failed: "+e.message):h.error("Import failed: "+String(e))})}catch(l){console.error("Import error:",l),l instanceof Error?h.error("Import failed: "+l.message):h.error("Import failed: "+String(l))}}function $(){a.value.args.push("")}function T(l){a.value.args.splice(l,1)}function W(){P.value.push({key:"",value:""})}function X(l){P.value.splice(l,1)}function u(){i.value.push({key:"",value:""})}function z(l){i.value.splice(l,1)}function G(){j.value=!1,ne()}function ne(){a.value={transport:"stdio",name:"",description:"",command:"",args:[],url:"",timeout:60,autoStart:!0,instanceSelectionStrategy:"random"},P.value=[],i.value=[],M.value=ae,J.value=`{
|
|
21
|
-
"mcpServers": {
|
|
22
|
-
"server1": {
|
|
23
|
-
"command": "npx @anthropic-ai/mcp",
|
|
24
|
-
"args": ["--model", "claude-3-opus-20250620"],
|
|
25
|
-
"enabled": true,
|
|
26
|
-
"description": "A sample MCP server using stdio transport"
|
|
27
|
-
},
|
|
28
|
-
"server2": {
|
|
29
|
-
"type": "streamable-http",
|
|
30
|
-
"url": "http://localhost:3000",
|
|
31
|
-
"headers": { "Authorization": "Bearer token" },
|
|
32
|
-
"enabled": true,
|
|
33
|
-
"description": "A sample MCP server using HTTP transport"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}`,B.value={success:[],errors:[]},_.value=!1,D.value=!1,E.value=!1}const H=C(!1);async function ie(){if(H.value)return;H.value=!0;const l=P.value.reduce((c,m)=>(m.key&&(c[m.key]=m.value),c),{}),e=i.value.reduce((c,m)=>(m.key&&(c[m.key]=m.value),c),{});try{await U.addServer({name:a.value.name||"Unnamed Server",status:"offline",type:a.value.transport==="stdio"?"local":"remote",config:{type:a.value.transport,command:a.value.command,args:a.value.args.filter(c=>c),url:a.value.url,timeout:a.value.timeout*1e3,enabled:a.value.autoStart,aggregatedTools:[],env:l,headers:Object.keys(e).length>0?e:void 0,description:a.value.description||void 0},logs:[]}),a.value.instanceSelectionStrategy!=="random"&&await he.put(`/web/servers/${a.value.name}`,{instanceSelectionStrategy:a.value.instanceSelectionStrategy}),h.success(k("action.serverAdded")),G()}catch(c){c instanceof Error?h.error(c.message||k("error.addServerFailed")):h.error(k("error.addServerFailed"))}finally{H.value=!1}}return(l,e)=>{const c=Fe,m=xe,b=re,de=Ne,ue=He,Y=Be,ce=Je,me=Oe,K=Me,te=Qe;return d(),N(K,{modelValue:j.value,"onUpdate:modelValue":e[20]||(e[20]=o=>j.value=o),title:l.$t("addServer.title"),width:"600px",class:"custom-dialog","before-close":G,"append-to-body":"","align-center":""},{footer:r(()=>[s("div",al,[s("div",ol,[t(b,{onClick:e[10]||(e[10]=o=>_.value=!0)},{default:r(()=>[g(n(l.$t("addServer.byJson")),1)]),_:1}),t(b,{onClick:e[11]||(e[11]=o=>D.value=!0)},{default:r(()=>[g(n(l.$t("addServer.importBatch")),1)]),_:1})]),s("div",null,[t(b,{onClick:G,disabled:H.value},{default:r(()=>[g(n(l.$t("action.cancel")),1)]),_:1},8,["disabled"]),t(b,{type:"primary",onClick:ie,loading:H.value},{default:r(()=>[g(n(l.$t("action.create")),1)]),_:1},8,["loading"])])])]),default:r(()=>[t(me,{model:a.value,"label-position":"top"},{default:r(()=>[t(c,{label:l.$t("addServer.transportType")},{default:r(()=>[s("div",We,[s("div",{class:O(["flex-1 p-4 border rounded-lg cursor-pointer text-center transition-all",a.value.transport==="stdio"?"border-blue-500 bg-blue-900/20":"border-gray-600 hover:border-gray-500"]),onClick:e[0]||(e[0]=o=>a.value.transport="stdio")},[e[21]||(e[21]=s("div",{class:"font-bold mb-1"},"stdio",-1)),s("div",Xe," ("+n(l.$t("serverDetail.config.transportStdio"))+") ",1)],2),s("div",{class:O(["flex-1 p-4 border rounded-lg cursor-pointer text-center transition-all",a.value.transport==="sse"?"border-blue-500 bg-blue-900/20":"border-gray-600 hover:border-gray-500"]),onClick:e[1]||(e[1]=o=>a.value.transport="sse")},[e[22]||(e[22]=s("div",{class:"font-bold mb-1"},"SSE",-1)),s("div",Ye,"("+n(l.$t("serverDetail.config.transportSse"))+")",1)],2),s("div",{class:O(["flex-1 p-4 border rounded-lg cursor-pointer text-center transition-all",a.value.transport==="streamable-http"?"border-blue-500 bg-blue-900/20":"border-gray-600 hover:border-gray-500"]),onClick:e[2]||(e[2]=o=>a.value.transport="streamable-http")},[e[23]||(e[23]=s("div",{class:"font-bold mb-1"},"Streamable HTTP",-1)),s("div",Ze,"("+n(l.$t("serverDetail.config.transportHttp"))+")",1)],2)])]),_:1},8,["label"]),t(c,{label:l.$t("common.name")},{default:r(()=>[t(m,{modelValue:a.value.name,"onUpdate:modelValue":e[3]||(e[3]=o=>a.value.name=o),placeholder:l.$t("addServer.namePlaceholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"]),t(c,{label:l.$t("common.description")},{default:r(()=>[t(m,{modelValue:a.value.description,"onUpdate:modelValue":e[4]||(e[4]=o=>a.value.description=o),type:"textarea",rows:2,placeholder:l.$t("addServer.descriptionPlaceholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"]),a.value.transport==="stdio"?(d(),y(F,{key:0},[t(c,{label:l.$t("serverDetail.config.executable")},{default:r(()=>[t(m,{modelValue:a.value.command,"onUpdate:modelValue":e[5]||(e[5]=o=>a.value.command=o),placeholder:l.$t("addServer.executablePlaceholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"]),t(c,{label:l.$t("serverDetail.config.args")},{default:r(()=>[s("div",el,[(d(!0),y(F,null,L(a.value.args,(o,V)=>(d(),y("div",{key:V,class:"flex gap-2 w-full"},[t(m,{modelValue:a.value.args[V],"onUpdate:modelValue":w=>a.value.args[V]=w,placeholder:l.$t("addServer.argPlaceholder")},null,8,["modelValue","onUpdate:modelValue","placeholder"]),t(b,{icon:p(Z),circle:"",plain:"",onClick:w=>T(V)},null,8,["icon","onClick"])]))),128)),s("div",null,[t(b,{icon:p(q),plain:"",size:"small",onClick:$},{default:r(()=>[g("+ "+n(l.$t("serverDetail.config.addArg")),1)]),_:1},8,["icon"])])])]),_:1},8,["label"])],64)):(d(),N(c,{key:1,label:l.$t("serverDetail.config.url")},{default:r(()=>[t(m,{modelValue:a.value.url,"onUpdate:modelValue":e[6]||(e[6]=o=>a.value.url=o),placeholder:l.$t("addServer.urlPlaceholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"])),t(c,{label:l.$t("serverDetail.config.timeout")},{default:r(()=>[t(de,{modelValue:a.value.timeout,"onUpdate:modelValue":e[7]||(e[7]=o=>a.value.timeout=o),min:0,step:10},null,8,["modelValue"])]),_:1},8,["label"]),t(c,{label:l.$t("serverDetail.config.autoStart")},{default:r(()=>[t(ue,{modelValue:a.value.autoStart,"onUpdate:modelValue":e[8]||(e[8]=o=>a.value.autoStart=o)},null,8,["modelValue"])]),_:1},8,["label"]),t(c,{label:l.$t("serverDetail.config.instanceSelectionStrategy")},{default:r(()=>[t(ce,{modelValue:a.value.instanceSelectionStrategy,"onUpdate:modelValue":e[9]||(e[9]=o=>a.value.instanceSelectionStrategy=o),placeholder:"随机(默认)"},{default:r(()=>[t(Y,{value:"random",label:l.$t("serverDetail.config.strategyRandom")},null,8,["label"]),t(Y,{value:"round-robin",label:l.$t("serverDetail.config.strategyRoundRobin")},null,8,["label"]),t(Y,{value:"tag-match-unique",label:l.$t("serverDetail.config.strategyTagMatchUnique")},null,8,["label"])]),_:1},8,["modelValue"])]),_:1},8,["label"]),t(c,{label:l.$t("serverDetail.config.env")},{default:r(()=>[s("div",ll,[(d(!0),y(F,null,L(P.value,(o,V)=>(d(),y("div",{key:V,class:"flex gap-2 w-full",style:{display:"flex",gap:"0.5rem",width:"100%"}},[t(m,{modelValue:o.key,"onUpdate:modelValue":w=>o.key=w,placeholder:l.$t("addServer.keyPlaceholder"),style:{width:"30%","min-width":"150px"}},null,8,["modelValue","onUpdate:modelValue","placeholder"]),t(m,{modelValue:o.value,"onUpdate:modelValue":w=>o.value=w,placeholder:l.$t("addServer.valuePlaceholder"),style:{flex:"1"}},null,8,["modelValue","onUpdate:modelValue","placeholder"]),t(b,{icon:p(Z),circle:"",plain:"",onClick:w=>X(V)},null,8,["icon","onClick"])]))),128)),s("div",null,[t(b,{icon:p(q),plain:"",size:"small",onClick:W},{default:r(()=>[g("+ "+n(l.$t("serverDetail.config.addEnv")),1)]),_:1},8,["icon"])])])]),_:1},8,["label"]),a.value.transport!=="stdio"?(d(),N(c,{key:2,label:l.$t("serverDetail.config.headers")},{default:r(()=>[s("div",tl,[(d(!0),y(F,null,L(i.value,(o,V)=>(d(),y("div",{key:V,class:"flex gap-2 w-full",style:{display:"flex",gap:"0.5rem",width:"100%"}},[t(m,{modelValue:o.key,"onUpdate:modelValue":w=>o.key=w,placeholder:l.$t("addServer.keyPlaceholder"),style:{width:"30%","min-width":"150px"}},null,8,["modelValue","onUpdate:modelValue","placeholder"]),t(m,{modelValue:o.value,"onUpdate:modelValue":w=>o.value=w,placeholder:l.$t("addServer.valuePlaceholder"),style:{flex:"1"}},null,8,["modelValue","onUpdate:modelValue","placeholder"]),t(b,{icon:p(Z),circle:"",plain:"",onClick:w=>z(V)},null,8,["icon","onClick"])]))),128)),s("div",null,[t(b,{icon:p(q),plain:"",size:"small",onClick:u},{default:r(()=>[g("+ "+n(l.$t("serverDetail.config.addHeader")),1)]),_:1},8,["icon"])])])]),_:1},8,["label"])):I("",!0)]),_:1},8,["model"]),t(K,{modelValue:_.value,"onUpdate:modelValue":e[14]||(e[14]=o=>_.value=o),title:l.$t("addServer.byJson"),width:"500px","append-to-body":"",class:"custom-dialog"},{footer:r(()=>[t(b,{onClick:e[13]||(e[13]=o=>_.value=!1)},{default:r(()=>[g(n(l.$t("action.cancel")),1)]),_:1}),t(b,{type:"primary",onClick:f},{default:r(()=>[g(n(l.$t("action.save")),1)]),_:1})]),default:r(()=>[t(m,{modelValue:M.value,"onUpdate:modelValue":e[12]||(e[12]=o=>M.value=o),type:"textarea",rows:10,placeholder:'{ "mcpServers": { "name": { "command": "...", ... } } }'},null,8,["modelValue"])]),_:1},8,["modelValue","title"]),t(K,{modelValue:D.value,"onUpdate:modelValue":e[17]||(e[17]=o=>D.value=o),title:l.$t("addServer.batchImportTitle"),width:"600px","append-to-body":"",class:"custom-dialog"},{footer:r(()=>[t(b,{onClick:e[16]||(e[16]=o=>D.value=!1)},{default:r(()=>[g(n(l.$t("action.cancel")),1)]),_:1}),t(b,{type:"primary",onClick:A,loading:H.value},{default:r(()=>[g(n(l.$t("addServer.importAll")),1)]),_:1},8,["loading"])]),default:r(()=>[t(m,{modelValue:J.value,"onUpdate:modelValue":e[15]||(e[15]=o=>J.value=o),type:"textarea",rows:12,placeholder:'{ "mcpServers": { "server1": { "command": "npx @anthropic-ai/mcp", "args": ["--model", "claude-3-opus-20250620"] }, "server2": { "url": "http://localhost:3000", "headers": { "Authorization": "Bearer token" } } } }'},null,8,["modelValue"])]),_:1},8,["modelValue","title"]),t(K,{modelValue:E.value,"onUpdate:modelValue":e[19]||(e[19]=o=>E.value=o),title:l.$t("addServer.batchImportTitle"),width:"600px","append-to-body":"",class:"custom-dialog"},{footer:r(()=>[t(b,{onClick:e[18]||(e[18]=o=>E.value=!1)},{default:r(()=>[...e[24]||(e[24]=[g("Close",-1)])]),_:1})]),default:r(()=>[B.value.success.length>0?(d(),y("div",rl,[s("h4",sl,n(l.$t("action.serverAdded")),1),t(te,{class:"mb-4"},{header:r(()=>[s("div",nl,[s("span",null,n(l.$t("action.serverAdded")),1)])]),default:r(()=>[s("div",il,[(d(!0),y(F,null,L(B.value.success,o=>(d(),y("div",{key:o.id,class:"p-2 bg-green-50 dark:bg-green-900/20 rounded"},n(o.name),1))),128))])]),_:1})])):I("",!0),B.value.errors.length>0?(d(),y("div",dl,[s("h4",ul,n(l.$t("error.addServerFailed")),1),t(te,{class:"mb-4"},{header:r(()=>[s("div",cl,[s("span",null,n(l.$t("error.addServerFailed")),1)])]),default:r(()=>[s("div",ml,[(d(!0),y(F,null,L(B.value.errors,(o,V)=>(d(),y("div",{key:V,class:"p-2 bg-red-50 dark:bg-red-900/20 rounded"},[s("div",pl,n(o.name),1),s("div",vl,n(o.error),1)]))),128))])]),_:1})])):I("",!0)]),_:1},8,["modelValue","title"])]),_:1},8,["modelValue","title"])}}}),gl={class:"server-list-view py-6 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto w-full h-full flex flex-col overflow-hidden bg-gray-50 dark:bg-[#0f172a] transition-colors duration-300"},yl={class:"flex items-center justify-between mb-6 shrink-0"},bl={class:"text-2xl font-semibold text-gray-900 dark:text-white"},hl={class:"flex gap-2"},Sl={key:0,class:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"},$l={class:"p-6 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#1e293b] h-48"},kl={class:"flex items-center gap-3 mb-4"},_l={class:"flex-1"},Vl={key:1,class:"flex flex-col items-center justify-center flex-1 text-gray-400 dark:text-gray-500"},wl={class:"text-xl font-medium mb-2"},Cl={key:2,class:"overflow-y-auto flex-1 custom-scrollbar"},Al={class:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 pb-6 pr-2"},xl=["onClick"],El={class:"flex flex-col gap-2 mb-4"},Il={class:"flex items-center justify-between"},Ul={class:"flex items-center gap-2 flex-1 min-w-0"},Dl=["title"],Pl={class:"mt-auto space-y-2"},Tl={class:"flex gap-2"},zl={class:"grid grid-cols-3 gap-2"},jl=le({__name:"ServerListView",setup(Q){const S=oe(),x=je(),{t:v}=se(),k=C(!1),U=C("form");ze(()=>{S.fetchServers()});function j(i){U.value=i,k.value=!0}function _(i,f){const A=S.servers.find(T=>T.id===i);if(!A)return;S.selectServer(i);const $=f==="tools"?"server-detail-tools":f==="resources"?"server-detail-resources":"server-detail-config";x.push({name:$,params:{name:A.name}})}function D(i){_(i.id,"config")}function E(i){const f=S.servers.find($=>$.name===i);return f?(f.instances||[]).filter($=>$.status==="online").length:0}function M(i){return J(i)-E(i)}function J(i){return S.servers.find(A=>A.name===i)?.instances?.length||0}async function B(i){try{await S.startAllServerInstances(i),h.success(v("action.started"))}catch(f){h.error(f.message||v("error.connectionFailed"))}}async function a(i){try{await S.stopAllServerInstances(i),h.success(v("action.stopped"))}catch(f){h.error(f.message||v("error.connectionFailed"))}}async function P(i){try{await S.restartAllServerInstances(i),h.success(v("action.restarted"))}catch(f){h.error(f.message||v("error.connectionFailed"))}}return(i,f)=>{const A=Se,$=re,T=Ue,W=Ie,X=Ee;return d(),y("div",gl,[s("div",yl,[s("h2",bl,n(i.$t("sidebar.servers")),1),s("div",hl,[t($,{type:"primary",onClick:f[0]||(f[0]=u=>j("form"))},{default:r(()=>[t(A,{class:"mr-2"},{default:r(()=>[t(p(q))]),_:1}),g(" "+n(i.$t("sidebar.addServer")),1)]),_:1})])]),p(S).loading&&p(S).servers.length===0?(d(),y("div",Sl,[t(W,{animated:"",count:3,class:"w-full h-full"},{template:r(()=>[s("div",$l,[s("div",kl,[t(T,{variant:"circle",style:{width:"40px",height:"40px"}}),s("div",_l,[t(T,{variant:"text",style:{width:"60%"},class:"mb-2"}),t(T,{variant:"text",style:{width:"30%"}})])]),t(T,{variant:"rect",style:{height:"60px"}})])]),_:1})])):p(S).servers.length===0?(d(),y("div",Vl,[t(A,{size:64,class:"mb-4 opacity-50"},{default:r(()=>[t(p($e))]),_:1}),s("h3",wl,n(i.$t("serverDetail.noServerSelected")),1),f[3]||(f[3]=s("p",{class:"mb-6"},'Click "Add New Server" to get started.',-1)),t($,{type:"primary",onClick:f[1]||(f[1]=u=>j("form"))},{default:r(()=>[t(A,{class:"mr-2"},{default:r(()=>[t(p(q))]),_:1}),g(" "+n(i.$t("sidebar.addServer")),1)]),_:1})])):(d(),y("div",Cl,[s("div",Al,[(d(!0),y(F,null,L(p(S).servers,u=>(d(),y("div",{key:u.id,class:"server-card bg-white dark:bg-[#1e293b] rounded-xl border border-gray-200 dark:border-gray-700 p-6 shadow-sm hover:shadow-md transition-all duration-300 flex flex-col h-full cursor-pointer",onClick:z=>D(u)},[s("div",El,[s("div",Il,[s("div",Ul,[s("h3",{class:"font-bold text-gray-900 dark:text-white truncate text-lg",title:u.name},n(u.name),9,Dl),u.version?(d(),N(X,{key:0,size:"small",class:"shrink-0"},{default:r(()=>[g(n(u.version),1)]),_:2},1024)):I("",!0)])]),t(Re,{server:u,"include-uptime":!1},null,8,["server"])]),s("div",Pl,[s("div",Tl,[M(u.name)>0?(d(),N($,{key:0,type:"success",plain:"",size:"small",icon:p(ke),onClick:R(z=>B(u.name),["stop"]),class:"flex-1 !ml-0",title:i.$t("action.startAll")},{default:r(()=>[g(n(i.$t("action.startAll"))+" ("+n(M(u.name))+") ",1)]),_:2},1032,["icon","onClick","title"])):I("",!0),E(u.name)>0?(d(),N($,{key:1,plain:"",size:"small",icon:p(_e),onClick:R(z=>P(u.name),["stop"]),class:"flex-1 !ml-0",title:i.$t("action.restartAll")},{default:r(()=>[g(n(i.$t("action.restartAll"))+" ("+n(J(u.name))+") ",1)]),_:2},1032,["icon","onClick","title"])):I("",!0),E(u.name)>0?(d(),N($,{key:2,type:"warning",plain:"",size:"small",icon:p(Ve),onClick:R(z=>a(u.name),["stop"]),class:"flex-1 !ml-0",title:i.$t("action.stopAll")},{default:r(()=>[g(n(i.$t("action.stopAll"))+" ("+n(E(u.name))+") ",1)]),_:2},1032,["icon","onClick","title"])):I("",!0)]),s("div",zl,[t($,{plain:"",size:"small",icon:p(we),onClick:R(z=>_(u.id,"config"),["stop"]),class:"!w-full !ml-0"},{default:r(()=>[g(n(i.$t("action.configure"))+" ("+n(u.rawV11Config?.instances?.length||0)+") ",1)]),_:2},1032,["icon","onClick"]),t($,{plain:"",size:"small",icon:p(Ce),onClick:R(z=>_(u.id,"tools"),["stop"]),class:"!w-full !ml-0"},{default:r(()=>[g(n(i.$t("common.tools"))+" ("+n(u.toolsCount||0)+") ",1)]),_:2},1032,["icon","onClick"]),t($,{plain:"",size:"small",icon:p(Ae),onClick:R(z=>_(u.id,"resources"),["stop"]),class:"!w-full !ml-0"},{default:r(()=>[g(n(i.$t("common.resources"))+" ("+n(u.resourcesCount||0)+") ",1)]),_:2},1032,["icon","onClick"])])])],8,xl))),128))])])),t(fl,{modelValue:k.value,"onUpdate:modelValue":f[2]||(f[2]=u=>k.value=u),"initial-mode":U.value},null,8,["modelValue","initial-mode"])])}}}),Wl=Le(jl,[["__scopeId","data-v-2c4f1bc4"]]);export{Wl as default};
|