@samanhappy/mcphub 0.12.17 → 1.0.1
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/README.fr.md +7 -5
- package/README.md +24 -4
- package/README.zh.md +25 -4
- package/bin/cli.js +64 -50
- package/dist/cli/call-arguments.js +81 -0
- package/dist/cli/call-arguments.js.map +1 -0
- package/dist/cli/commands/call.js +75 -0
- package/dist/cli/commands/call.js.map +1 -0
- package/dist/cli/commands/config.js +132 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/discover.js +127 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/export.js +20 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/groups.js +107 -0
- package/dist/cli/commands/groups.js.map +1 -0
- package/dist/cli/commands/install.js +173 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/keys.js +91 -0
- package/dist/cli/commands/keys.js.map +1 -0
- package/dist/cli/commands/login.js +70 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/servers.js +142 -0
- package/dist/cli/commands/servers.js.map +1 -0
- package/dist/cli/commands/tools.js +162 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/context.js +44 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/errors.js +19 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/help.js +157 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/http.js +93 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/main.js +81 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.js +47 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parse-args.js +103 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/profile.js +109 -0
- package/dist/cli/profile.js.map +1 -0
- package/dist/cli/prompts.js +56 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/controllers/oauthServerController.js +37 -1
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/dao/ServerDaoDbImpl.js +3 -0
- package/dist/dao/ServerDaoDbImpl.js.map +1 -1
- package/dist/db/connection.js +48 -4
- package/dist/db/connection.js.map +1 -1
- package/dist/db/entities/Server.js +4 -0
- package/dist/db/entities/Server.js.map +1 -1
- package/dist/db/entities/VectorEmbedding.js +2 -5
- package/dist/db/entities/VectorEmbedding.js.map +1 -1
- package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
- package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
- package/dist/services/dataService.js +10 -1
- package/dist/services/dataService.js.map +1 -1
- package/dist/services/mcpService.js +47 -10
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/sseService.js +5 -3
- package/dist/services/sseService.js.map +1 -1
- package/dist/services/vectorSearchService.js +16 -3
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/migration.js +1 -0
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/serverConfigPersistence.js +5 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/frontend/dist/assets/ActivityPage-DwzGiMh_.js +2 -0
- package/frontend/dist/assets/ActivityPage-DwzGiMh_.js.map +1 -0
- package/frontend/dist/assets/ConfirmDialog-CxlizGia.js +2 -0
- package/frontend/dist/assets/ConfirmDialog-CxlizGia.js.map +1 -0
- package/frontend/dist/assets/Dashboard-BUCJcvk-.js +2 -0
- package/frontend/dist/assets/Dashboard-BUCJcvk-.js.map +1 -0
- package/frontend/dist/assets/DeleteDialog-DRbWonMu.js +2 -0
- package/frontend/dist/assets/DeleteDialog-DRbWonMu.js.map +1 -0
- package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js +2 -0
- package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js.map +1 -0
- package/frontend/dist/assets/GroupsPage-DfLlww4U.js +33 -0
- package/frontend/dist/assets/GroupsPage-DfLlww4U.js.map +1 -0
- package/frontend/dist/assets/LoginPage-DCjqYw_8.js +2 -0
- package/frontend/dist/assets/LoginPage-DCjqYw_8.js.map +1 -0
- package/frontend/dist/assets/LogsPage-CTa8kuDf.js +2 -0
- package/frontend/dist/assets/LogsPage-CTa8kuDf.js.map +1 -0
- package/frontend/dist/assets/MarketPage-C2Rh4WJB.js +3 -0
- package/frontend/dist/assets/MarketPage-C2Rh4WJB.js.map +1 -0
- package/frontend/dist/assets/{Pagination-y-gVO8ms.js → Pagination-BFi-X7qY.js} +2 -2
- package/frontend/dist/assets/{Pagination-y-gVO8ms.js.map → Pagination-BFi-X7qY.js.map} +1 -1
- package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js +2 -0
- package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js.map +1 -0
- package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js +2 -0
- package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js.map +1 -0
- package/frontend/dist/assets/ServersPage-hgCbCglG.js +37 -0
- package/frontend/dist/assets/ServersPage-hgCbCglG.js.map +1 -0
- package/frontend/dist/assets/SettingsPage-BzNX8mXv.js +12 -0
- package/frontend/dist/assets/SettingsPage-BzNX8mXv.js.map +1 -0
- package/frontend/dist/assets/StatusDot-CQzailBQ.js +2 -0
- package/frontend/dist/assets/StatusDot-CQzailBQ.js.map +1 -0
- package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js → ToggleGroup-CNBBvo3C.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js.map → ToggleGroup-CNBBvo3C.js.map} +1 -1
- package/frontend/dist/assets/UsersPage-C33b7LCM.js +2 -0
- package/frontend/dist/assets/UsersPage-C33b7LCM.js.map +1 -0
- package/frontend/dist/assets/{framework-vendor-_OBebcuv.js → framework-vendor-BUhDPOUZ.js} +2 -2
- package/frontend/dist/assets/{framework-vendor-_OBebcuv.js.map → framework-vendor-BUhDPOUZ.js.map} +1 -1
- package/frontend/dist/assets/{i18n-vendor-MQ921plD.js → i18n-vendor-Kbr87Ofu.js} +2 -2
- package/frontend/dist/assets/{i18n-vendor-MQ921plD.js.map → i18n-vendor-Kbr87Ofu.js.map} +1 -1
- package/frontend/dist/assets/icons-vendor-CKgJB3SC.js +292 -0
- package/frontend/dist/assets/icons-vendor-CKgJB3SC.js.map +1 -0
- package/frontend/dist/assets/index-BGiKkKzj.js +3 -0
- package/frontend/dist/assets/index-BGiKkKzj.js.map +1 -0
- package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
- package/frontend/dist/assets/{resourceService-BfCTSBsr.js → resourceService-C6umWRgq.js} +2 -2
- package/frontend/dist/assets/{resourceService-BfCTSBsr.js.map → resourceService-C6umWRgq.js.map} +1 -1
- package/frontend/dist/assets/useServerData-P5In98R4.js +2 -0
- package/frontend/dist/assets/{useServerData-QZqQTYcv.js.map → useServerData-P5In98R4.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-Cz7vKGLE.js +2 -0
- package/frontend/dist/assets/{useSettingsData-D3VROqS7.js.map → useSettingsData-Cz7vKGLE.js.map} +1 -1
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js +16 -0
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
- package/frontend/dist/index.html +5 -5
- package/package.json +2 -1
- package/frontend/dist/assets/ActivityPage-ClgKeihP.js +0 -2
- package/frontend/dist/assets/ActivityPage-ClgKeihP.js.map +0 -1
- package/frontend/dist/assets/Badge-Ck2fhRdl.js +0 -2
- package/frontend/dist/assets/Badge-Ck2fhRdl.js.map +0 -1
- package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js +0 -2
- package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js.map +0 -1
- package/frontend/dist/assets/Dashboard-BIXrLobn.js +0 -2
- package/frontend/dist/assets/Dashboard-BIXrLobn.js.map +0 -1
- package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js +0 -2
- package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js.map +0 -1
- package/frontend/dist/assets/GroupsPage-BjrvyHwu.js +0 -33
- package/frontend/dist/assets/GroupsPage-BjrvyHwu.js.map +0 -1
- package/frontend/dist/assets/LoginPage-BBHt_TfF.js +0 -2
- package/frontend/dist/assets/LoginPage-BBHt_TfF.js.map +0 -1
- package/frontend/dist/assets/LogsPage-D8Znq5NB.js +0 -2
- package/frontend/dist/assets/LogsPage-D8Znq5NB.js.map +0 -1
- package/frontend/dist/assets/MarketPage-haRuzjCw.js +0 -3
- package/frontend/dist/assets/MarketPage-haRuzjCw.js.map +0 -1
- package/frontend/dist/assets/PromptsPage-ByHWPyGe.js +0 -2
- package/frontend/dist/assets/PromptsPage-ByHWPyGe.js.map +0 -1
- package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js +0 -2
- package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js.map +0 -1
- package/frontend/dist/assets/ServersPage-CtS1I4yS.js +0 -37
- package/frontend/dist/assets/ServersPage-CtS1I4yS.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-DxVigf7p.js +0 -12
- package/frontend/dist/assets/SettingsPage-DxVigf7p.js.map +0 -1
- package/frontend/dist/assets/UsersPage-Bipw33cS.js +0 -2
- package/frontend/dist/assets/UsersPage-Bipw33cS.js.map +0 -1
- package/frontend/dist/assets/icons-vendor-B67NtVuR.js +0 -172
- package/frontend/dist/assets/icons-vendor-B67NtVuR.js.map +0 -1
- package/frontend/dist/assets/index-CmnA4an8.js +0 -5
- package/frontend/dist/assets/index-CmnA4an8.js.map +0 -1
- package/frontend/dist/assets/index-DfFHVARX.css +0 -1
- package/frontend/dist/assets/useGroupData-DLhbP6zd.js +0 -2
- package/frontend/dist/assets/useGroupData-DLhbP6zd.js.map +0 -1
- package/frontend/dist/assets/useServerData-QZqQTYcv.js +0 -2
- package/frontend/dist/assets/useSettingsData-D3VROqS7.js +0 -2
- package/frontend/dist/assets/variableDetection-C3Xi21av.js +0 -16
- package/frontend/dist/assets/variableDetection-C3Xi21av.js.map +0 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { CliUsageError } from '../errors.js';
|
|
3
|
+
import { buildClient, resolveTarget } from '../context.js';
|
|
4
|
+
import { extractFlags } from '../parse-args.js';
|
|
5
|
+
import { green, printJson, printLine, printTable } from '../output.js';
|
|
6
|
+
export async function run(args, globals, deps = {}) {
|
|
7
|
+
const sub = args.shift();
|
|
8
|
+
const client = deps.client ?? buildClient(resolveTarget(globals));
|
|
9
|
+
switch (sub) {
|
|
10
|
+
case undefined:
|
|
11
|
+
case 'list':
|
|
12
|
+
return list(client, globals);
|
|
13
|
+
case 'get':
|
|
14
|
+
return get(client, args, globals);
|
|
15
|
+
case 'add':
|
|
16
|
+
return add(client, args, globals, deps);
|
|
17
|
+
case 'remove':
|
|
18
|
+
return remove(client, args);
|
|
19
|
+
case 'toggle':
|
|
20
|
+
return toggle(client, args);
|
|
21
|
+
case 'reload':
|
|
22
|
+
return reload(client, args);
|
|
23
|
+
default:
|
|
24
|
+
throw new CliUsageError(`Unknown servers subcommand: ${sub}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function list(client, globals) {
|
|
28
|
+
const res = await client.get('/api/servers');
|
|
29
|
+
const servers = res.data ?? [];
|
|
30
|
+
if (globals.json) {
|
|
31
|
+
printJson(servers);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
printTable(servers.map((s) => ({
|
|
35
|
+
name: s.name,
|
|
36
|
+
status: s.status,
|
|
37
|
+
tools: s.tools?.length ?? 0,
|
|
38
|
+
owner: s.owner ?? '',
|
|
39
|
+
error: s.error ?? '',
|
|
40
|
+
})), ['name', 'status', 'tools', 'owner', 'error']);
|
|
41
|
+
}
|
|
42
|
+
async function get(client, args, globals) {
|
|
43
|
+
const name = args[0];
|
|
44
|
+
if (!name)
|
|
45
|
+
throw new CliUsageError('Usage: mcphub servers get <name>');
|
|
46
|
+
const res = await client.get(`/api/servers/${encodeURIComponent(name)}`);
|
|
47
|
+
if (globals.json) {
|
|
48
|
+
printJson(res.data);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
printLine(JSON.stringify(res.data, null, 2));
|
|
52
|
+
}
|
|
53
|
+
async function add(client, args, globals, deps) {
|
|
54
|
+
const { positional, flags } = extractFlags(args, {
|
|
55
|
+
valued: ['--from-file', '--type', '--command', '--url', '--description'],
|
|
56
|
+
boolean: ['--enabled', '--disabled'],
|
|
57
|
+
});
|
|
58
|
+
const name = positional[0];
|
|
59
|
+
if (!name) {
|
|
60
|
+
throw new CliUsageError('Usage: mcphub servers add <name> --from-file <path>\n' +
|
|
61
|
+
' or mcphub servers add <name> --type <stdio|sse|streamable-http|openapi> [--command ...] [--arg ...] [--env K=V ...]');
|
|
62
|
+
}
|
|
63
|
+
let config;
|
|
64
|
+
if (flags['--from-file']) {
|
|
65
|
+
const path = flags['--from-file'];
|
|
66
|
+
const raw = (deps.fs ?? fs).readFileSync(path, 'utf8');
|
|
67
|
+
config = JSON.parse(raw);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const argArgs = collectRepeated(args, '--arg');
|
|
71
|
+
const envEntries = collectRepeated(args, '--env').map((kv) => {
|
|
72
|
+
const idx = kv.indexOf('=');
|
|
73
|
+
if (idx < 0)
|
|
74
|
+
throw new CliUsageError(`--env expects KEY=VALUE, got: ${kv}`);
|
|
75
|
+
return [kv.slice(0, idx), kv.slice(idx + 1)];
|
|
76
|
+
});
|
|
77
|
+
config = {
|
|
78
|
+
type: flags['--type'] || 'stdio',
|
|
79
|
+
description: flags['--description'],
|
|
80
|
+
command: flags['--command'],
|
|
81
|
+
args: argArgs.length > 0 ? argArgs : undefined,
|
|
82
|
+
env: envEntries.length > 0 ? Object.fromEntries(envEntries) : undefined,
|
|
83
|
+
url: flags['--url'],
|
|
84
|
+
enabled: flags['--disabled'] ? false : true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const res = await client.post('/api/servers', { name, config });
|
|
88
|
+
if (globals.json) {
|
|
89
|
+
printJson(res);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
printLine(green(`Added server "${name}".`));
|
|
93
|
+
}
|
|
94
|
+
async function remove(client, args) {
|
|
95
|
+
const name = args[0];
|
|
96
|
+
if (!name)
|
|
97
|
+
throw new CliUsageError('Usage: mcphub servers remove <name>');
|
|
98
|
+
await client.delete(`/api/servers/${encodeURIComponent(name)}`);
|
|
99
|
+
printLine(green(`Removed server "${name}".`));
|
|
100
|
+
}
|
|
101
|
+
async function toggle(client, args) {
|
|
102
|
+
const { positional, flags } = extractFlags(args, { boolean: ['--on', '--off'] });
|
|
103
|
+
const name = positional[0];
|
|
104
|
+
if (!name)
|
|
105
|
+
throw new CliUsageError('Usage: mcphub servers toggle <name> [--on|--off]');
|
|
106
|
+
const body = {};
|
|
107
|
+
if (flags['--on'])
|
|
108
|
+
body.enabled = true;
|
|
109
|
+
if (flags['--off'])
|
|
110
|
+
body.enabled = false;
|
|
111
|
+
await client.post(`/api/servers/${encodeURIComponent(name)}/toggle`, body);
|
|
112
|
+
printLine(green(`Toggled server "${name}".`));
|
|
113
|
+
}
|
|
114
|
+
async function reload(client, args) {
|
|
115
|
+
const name = args[0];
|
|
116
|
+
if (!name)
|
|
117
|
+
throw new CliUsageError('Usage: mcphub servers reload <name>');
|
|
118
|
+
await client.post(`/api/servers/${encodeURIComponent(name)}/reload`, {});
|
|
119
|
+
printLine(green(`Reloaded server "${name}".`));
|
|
120
|
+
}
|
|
121
|
+
// Helper: pull every occurrence of `--flag <value>` out of argv. extractFlags
|
|
122
|
+
// only captures the last occurrence, so repeated flags need this scan. Values
|
|
123
|
+
// may legitimately start with `--` (e.g. `--arg --version` for a wrapped CLI);
|
|
124
|
+
// we consume them unconditionally and skip the next index so we don't re-scan
|
|
125
|
+
// the value as another flag boundary.
|
|
126
|
+
function collectRepeated(argv, flag) {
|
|
127
|
+
const out = [];
|
|
128
|
+
for (let i = 0; i < argv.length; i++) {
|
|
129
|
+
if (argv[i] === flag) {
|
|
130
|
+
const v = argv[i + 1];
|
|
131
|
+
if (v !== undefined) {
|
|
132
|
+
out.push(v);
|
|
133
|
+
i++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (argv[i].startsWith(`${flag}=`)) {
|
|
137
|
+
out.push(argv[i].slice(flag.length + 1));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/cli/commands/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { CliUsageError } from '../errors.js';
|
|
2
|
+
import { buildClient, resolveTarget } from '../context.js';
|
|
3
|
+
import { extractFlags } from '../parse-args.js';
|
|
4
|
+
import { bold, dim, printJson, printLine, printTable } from '../output.js';
|
|
5
|
+
// `tools` is the agent-friendly index for `call`: it answers "what can I call,
|
|
6
|
+
// what params does it take, where does it live" in one place, without making
|
|
7
|
+
// callers post-process `servers list` responses.
|
|
8
|
+
export async function run(args, globals, deps = {}) {
|
|
9
|
+
const sub = args.shift();
|
|
10
|
+
const client = deps.client ?? buildClient(resolveTarget(globals));
|
|
11
|
+
switch (sub) {
|
|
12
|
+
case undefined:
|
|
13
|
+
case 'list':
|
|
14
|
+
return list(client, args, globals);
|
|
15
|
+
case 'get':
|
|
16
|
+
case 'schema':
|
|
17
|
+
return get(client, args, globals);
|
|
18
|
+
default:
|
|
19
|
+
throw new CliUsageError(`Unknown tools subcommand: ${sub}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function fetchFlatTools(client) {
|
|
23
|
+
const res = await client.get('/api/servers');
|
|
24
|
+
const servers = res.data ?? [];
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const s of servers) {
|
|
27
|
+
for (const t of (s.tools ?? [])) {
|
|
28
|
+
out.push({
|
|
29
|
+
server: s.name,
|
|
30
|
+
serverStatus: s.status,
|
|
31
|
+
name: t.name,
|
|
32
|
+
description: t.description,
|
|
33
|
+
enabled: t.enabled,
|
|
34
|
+
inputSchema: t.inputSchema,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
async function list(client, args, globals) {
|
|
41
|
+
const { flags } = extractFlags(args, {
|
|
42
|
+
valued: ['--server'],
|
|
43
|
+
boolean: ['--schema', '--enabled-only'],
|
|
44
|
+
});
|
|
45
|
+
let tools = await fetchFlatTools(client);
|
|
46
|
+
if (flags['--server']) {
|
|
47
|
+
const wanted = String(flags['--server']);
|
|
48
|
+
tools = tools.filter((t) => t.server === wanted);
|
|
49
|
+
}
|
|
50
|
+
if (flags['--enabled-only']) {
|
|
51
|
+
tools = tools.filter((t) => t.enabled !== false);
|
|
52
|
+
}
|
|
53
|
+
if (globals.json) {
|
|
54
|
+
if (!flags['--schema']) {
|
|
55
|
+
// Drop inputSchema by default to keep the JSON small; callers can opt in.
|
|
56
|
+
printJson(tools.map(({ inputSchema: _omit, ...rest }) => rest));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
printJson(tools);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (tools.length === 0) {
|
|
64
|
+
printLine(dim('(no tools)'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
printTable(tools.map((t) => ({
|
|
68
|
+
server: t.server,
|
|
69
|
+
tool: t.name,
|
|
70
|
+
enabled: t.enabled === false ? 'no' : 'yes',
|
|
71
|
+
description: truncate(t.description ?? '', 60),
|
|
72
|
+
})), ['server', 'tool', 'enabled', 'description']);
|
|
73
|
+
printLine(dim(`\nUse \`mcphub tools get <tool> [--server <name>]\` to see input schema and required params.`));
|
|
74
|
+
}
|
|
75
|
+
async function get(client, args, globals) {
|
|
76
|
+
const { positional, flags } = extractFlags(args, { valued: ['--server'] });
|
|
77
|
+
const name = positional[0];
|
|
78
|
+
if (!name) {
|
|
79
|
+
throw new CliUsageError('Usage: mcphub tools get <tool-name> [--server <server-name>]');
|
|
80
|
+
}
|
|
81
|
+
const wantedServer = flags['--server'];
|
|
82
|
+
const matches = (await fetchFlatTools(client)).filter((t) => t.name === name && (!wantedServer || t.server === wantedServer));
|
|
83
|
+
if (matches.length === 0) {
|
|
84
|
+
throw new CliUsageError(wantedServer
|
|
85
|
+
? `Tool "${name}" not found on server "${wantedServer}". Run \`mcphub tools list\` to see what's available.`
|
|
86
|
+
: `Tool "${name}" not found. Run \`mcphub tools list\` to see what's available.`);
|
|
87
|
+
}
|
|
88
|
+
if (matches.length > 1 && !wantedServer) {
|
|
89
|
+
const hosts = matches.map((m) => m.server).join(', ');
|
|
90
|
+
throw new CliUsageError(`Tool "${name}" exists on multiple servers (${hosts}). Pass --server <name> to pick one.`);
|
|
91
|
+
}
|
|
92
|
+
const tool = matches[0];
|
|
93
|
+
if (globals.json) {
|
|
94
|
+
printJson(tool);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const schema = tool.inputSchema;
|
|
98
|
+
const required = new Set(schema?.required ?? []);
|
|
99
|
+
const props = schema?.properties ?? {};
|
|
100
|
+
printLine(`${bold('Server:')} ${tool.server} (${tool.serverStatus})`);
|
|
101
|
+
printLine(`${bold('Tool:')} ${tool.name}`);
|
|
102
|
+
if (tool.description) {
|
|
103
|
+
printLine(`${bold('Description:')} ${tool.description}`);
|
|
104
|
+
}
|
|
105
|
+
if (tool.enabled === false) {
|
|
106
|
+
printLine(dim('(disabled — calls will fail until re-enabled)'));
|
|
107
|
+
}
|
|
108
|
+
printLine('');
|
|
109
|
+
if (Object.keys(props).length === 0) {
|
|
110
|
+
printLine(dim('No documented parameters.'));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
printLine(bold('Parameters:'));
|
|
114
|
+
const rows = Object.entries(props).map(([key, p]) => ({
|
|
115
|
+
param: key,
|
|
116
|
+
type: typeof p === 'object' && p ? p.type ?? '' : '',
|
|
117
|
+
required: required.has(key) ? 'yes' : 'no',
|
|
118
|
+
description: truncate(typeof p === 'object' && p ? p.description ?? '' : '', 60),
|
|
119
|
+
}));
|
|
120
|
+
printTable(rows, ['param', 'type', 'required', 'description']);
|
|
121
|
+
}
|
|
122
|
+
printLine('');
|
|
123
|
+
printLine(bold('Input schema (JSON):'));
|
|
124
|
+
printLine(JSON.stringify(tool.inputSchema ?? {}, null, 2));
|
|
125
|
+
printLine('');
|
|
126
|
+
printLine(bold('Example:'));
|
|
127
|
+
const example = buildExample(tool, required, props);
|
|
128
|
+
printLine(` ${example}`);
|
|
129
|
+
}
|
|
130
|
+
function buildExample(tool, required, props) {
|
|
131
|
+
const sample = (type) => {
|
|
132
|
+
switch (type) {
|
|
133
|
+
case 'number':
|
|
134
|
+
case 'integer':
|
|
135
|
+
return '0';
|
|
136
|
+
case 'boolean':
|
|
137
|
+
return 'true';
|
|
138
|
+
case 'array':
|
|
139
|
+
return '[]';
|
|
140
|
+
case 'object':
|
|
141
|
+
return '{}';
|
|
142
|
+
default:
|
|
143
|
+
return '<value>';
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const parts = ['mcphub', 'call', tool.name];
|
|
147
|
+
// Show required params first, with a hint at the type. Optional params are
|
|
148
|
+
// intentionally omitted so the example is the minimum-viable call.
|
|
149
|
+
const reqKeys = Array.from(required);
|
|
150
|
+
for (const key of reqKeys) {
|
|
151
|
+
const p = props[key];
|
|
152
|
+
parts.push(`${key}=${sample(typeof p === 'object' && p ? p.type : undefined)}`);
|
|
153
|
+
}
|
|
154
|
+
parts.push(`--server`, tool.server);
|
|
155
|
+
return parts.join(' ');
|
|
156
|
+
}
|
|
157
|
+
function truncate(s, n) {
|
|
158
|
+
if (s.length <= n)
|
|
159
|
+
return s;
|
|
160
|
+
return s.slice(0, n - 1) + '…';
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/cli/commands/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ApiClient } from './http.js';
|
|
2
|
+
import { CliUsageError } from './errors.js';
|
|
3
|
+
import { getProfile, loadCredentials, } from './profile.js';
|
|
4
|
+
// Resolve where requests should go and what token to use, in this order:
|
|
5
|
+
// 1. CLI flags (--url / --token / --bearer)
|
|
6
|
+
// 2. Environment variables (MCPHUB_URL / MCPHUB_TOKEN / MCPHUB_TOKEN_KIND)
|
|
7
|
+
// 3. Active profile in credentials.json (--profile <name> or current)
|
|
8
|
+
// Commands that only need a URL (e.g. discover) call resolveTargetForPublic()
|
|
9
|
+
// instead, which doesn't require a token.
|
|
10
|
+
export function resolveTarget(globals, creds) {
|
|
11
|
+
const credentials = creds ?? loadCredentials();
|
|
12
|
+
const profile = getProfile(credentials, globals.profile);
|
|
13
|
+
const baseUrl = globals.url ?? process.env.MCPHUB_URL ?? profile?.url;
|
|
14
|
+
if (!baseUrl) {
|
|
15
|
+
throw new CliUsageError('No mcphub URL configured. Use --url <url>, MCPHUB_URL env, or run `mcphub login`.');
|
|
16
|
+
}
|
|
17
|
+
const tokenKind = (globals.bearer ? 'bearer' : undefined) ??
|
|
18
|
+
process.env.MCPHUB_TOKEN_KIND ??
|
|
19
|
+
profile?.tokenKind ??
|
|
20
|
+
'jwt';
|
|
21
|
+
const token = globals.token ?? process.env.MCPHUB_TOKEN ?? profile?.token;
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new CliUsageError('Not logged in. Use --token <token>, MCPHUB_TOKEN env, or run `mcphub login`.');
|
|
24
|
+
}
|
|
25
|
+
return { baseUrl, token, tokenKind, profileName: globals.profile ?? credentials.current };
|
|
26
|
+
}
|
|
27
|
+
export function resolveTargetForPublic(globals, remote, creds) {
|
|
28
|
+
const credentials = creds ?? loadCredentials();
|
|
29
|
+
const profile = getProfile(credentials, globals.profile);
|
|
30
|
+
const baseUrl = remote ?? globals.url ?? process.env.MCPHUB_URL ?? profile?.url;
|
|
31
|
+
if (!baseUrl) {
|
|
32
|
+
throw new CliUsageError('No mcphub URL configured. Use --remote <url>, --url <url>, MCPHUB_URL env, or run `mcphub login`.');
|
|
33
|
+
}
|
|
34
|
+
return { baseUrl };
|
|
35
|
+
}
|
|
36
|
+
export function buildClient(target, fetchImpl) {
|
|
37
|
+
return new ApiClient({
|
|
38
|
+
baseUrl: target.baseUrl,
|
|
39
|
+
token: target.token,
|
|
40
|
+
tokenKind: target.tokenKind,
|
|
41
|
+
fetchImpl,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAEL,UAAU,EACV,eAAe,GAEhB,MAAM,cAAc,CAAC;AAkBtB,yEAAyE;AACzE,4CAA4C;AAC5C,2EAA2E;AAC3E,sEAAsE;AACtE,8EAA8E;AAC9E,0CAA0C;AAE1C,MAAM,UAAU,aAAa,CAAC,OAAoB,EAAE,KAAmB;IACrE,MAAM,WAAW,GAAG,KAAK,IAAI,eAAe,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAwB,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,EAAE,GAAG,CAAC;IACtE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,aAAa,CACrB,mFAAmF,CACpF,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GACb,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,iBAA2C;QACxD,OAAO,EAAE,SAAS;QAClB,KAAK,CAAC;IACR,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,EAAE,KAAK,CAAC;IAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,aAAa,CACrB,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,OAAoB,EACpB,MAAe,EACf,KAAmB;IAEnB,MAAM,WAAW,GAAG,KAAK,IAAI,eAAe,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,EAAE,GAAG,CAAC;IAChF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,aAAa,CACrB,mGAAmG,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAsB,EAAE,SAAwB;IAC1E,OAAO,IAAI,SAAS,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS;KACV,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Errors thrown by the CLI layer. Top-level handler in main.ts inspects the
|
|
2
|
+
// constructor (or `requiresLogin` flag) to choose an exit code and decide
|
|
3
|
+
// whether to print remediation hints.
|
|
4
|
+
export class CliUsageError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'CliUsageError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class CliApiError extends Error {
|
|
11
|
+
constructor(init) {
|
|
12
|
+
super(init.message);
|
|
13
|
+
this.name = 'CliApiError';
|
|
14
|
+
this.status = init.status;
|
|
15
|
+
this.body = init.body;
|
|
16
|
+
this.requiresLogin = init.requiresLogin ?? init.status === 401;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,0EAA0E;AAC1E,sCAAsC;AAEtC,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AASD,MAAM,OAAO,WAAY,SAAQ,KAAK;IAKpC,YAAY,IAAqB;QAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IACjE,CAAC;CACF"}
|
package/dist/cli/help.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { printLine } from './output.js';
|
|
2
|
+
const TOP_LEVEL_HELP = `mcphub — official CLI for the mcphub server
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
mcphub start the mcphub server (legacy, no-arg form)
|
|
6
|
+
mcphub <command> [options] run a CLI command
|
|
7
|
+
|
|
8
|
+
Commands:
|
|
9
|
+
login interactively log in to a mcphub instance
|
|
10
|
+
logout clear the cached token for the active profile
|
|
11
|
+
config manage local profiles and credentials
|
|
12
|
+
servers list/get/add/remove/toggle/reload MCP servers
|
|
13
|
+
groups manage server groups
|
|
14
|
+
keys manage bearer keys
|
|
15
|
+
tools list MCP tools and inspect their input schema
|
|
16
|
+
call call an MCP tool via /mcp/$smart or /mcp/<server|group>
|
|
17
|
+
export export the running hub's mcp_settings.json
|
|
18
|
+
discover browse a remote hub's public marketplace
|
|
19
|
+
install install a server from a remote marketplace
|
|
20
|
+
help [command] show help for a command
|
|
21
|
+
|
|
22
|
+
Global options:
|
|
23
|
+
--url <url> override the active profile's base URL
|
|
24
|
+
--token <token> override the active profile's token
|
|
25
|
+
--bearer treat --token as a bearer key (default: JWT)
|
|
26
|
+
--profile <name> use a specific saved profile
|
|
27
|
+
--json print JSON output instead of human-friendly
|
|
28
|
+
--debug print stack traces on error
|
|
29
|
+
|
|
30
|
+
Environment:
|
|
31
|
+
MCPHUB_URL, MCPHUB_TOKEN, MCPHUB_TOKEN_KIND
|
|
32
|
+
XDG_CONFIG_HOME, XDG_DATA_HOME, NO_COLOR
|
|
33
|
+
`;
|
|
34
|
+
const COMMAND_HELP = {
|
|
35
|
+
login: `mcphub login [--url <url>] [--username <name>] [--password <pwd>]
|
|
36
|
+
|
|
37
|
+
Log in to a mcphub instance and cache a JWT in the active profile.
|
|
38
|
+
Prompts for missing values. The token is written to credentials.json
|
|
39
|
+
with 0600 permissions.`,
|
|
40
|
+
logout: `mcphub logout
|
|
41
|
+
|
|
42
|
+
Clear the token from the active profile (URL and username are preserved).`,
|
|
43
|
+
config: `mcphub config <subcommand>
|
|
44
|
+
|
|
45
|
+
Subcommands:
|
|
46
|
+
show print the active profile (token masked)
|
|
47
|
+
list list all saved profiles
|
|
48
|
+
use <name> switch the active profile
|
|
49
|
+
set-url <url> set the URL of a profile (--profile to target)
|
|
50
|
+
set-token <token> [--bearer] set the token of a profile manually
|
|
51
|
+
remove <name> delete a saved profile`,
|
|
52
|
+
servers: `mcphub servers <subcommand>
|
|
53
|
+
|
|
54
|
+
Subcommands:
|
|
55
|
+
list list all servers
|
|
56
|
+
get <name> show one server's config
|
|
57
|
+
add <name> --from-file <path> add a server from a JSON file
|
|
58
|
+
add <name> --type stdio --command <cmd> [--arg <a> ...] [--env K=V ...]
|
|
59
|
+
remove <name> delete a server
|
|
60
|
+
toggle <name> [--on|--off] enable/disable a server
|
|
61
|
+
reload <name> reconnect a server`,
|
|
62
|
+
groups: `mcphub groups <subcommand>
|
|
63
|
+
|
|
64
|
+
Subcommands:
|
|
65
|
+
list list groups
|
|
66
|
+
get <id|name> show one group
|
|
67
|
+
add <name> [--description <d>] create a group
|
|
68
|
+
remove <id|name> delete a group
|
|
69
|
+
add-server <group> <server> add a server to a group
|
|
70
|
+
remove-server <group> <server> remove a server from a group`,
|
|
71
|
+
keys: `mcphub keys <subcommand>
|
|
72
|
+
|
|
73
|
+
Subcommands:
|
|
74
|
+
list list bearer keys
|
|
75
|
+
create --name <n> [--access-type all|groups|servers|custom]
|
|
76
|
+
[--groups a,b] [--servers x,y]
|
|
77
|
+
delete <id> delete a key`,
|
|
78
|
+
tools: `mcphub tools <subcommand>
|
|
79
|
+
|
|
80
|
+
The agent-friendly index for \`call\`. Use it to discover what's available
|
|
81
|
+
and what params each tool wants without hand-parsing \`servers list\` JSON.
|
|
82
|
+
|
|
83
|
+
Subcommands:
|
|
84
|
+
list [--server <name>] [--enabled-only] [--schema]
|
|
85
|
+
list tools across all (or one) servers
|
|
86
|
+
get <tool> [--server <name>] show one tool's description, parameters,
|
|
87
|
+
input schema, and a sample \`call\` command
|
|
88
|
+
schema <tool> [--server <name>] alias for \`get\``,
|
|
89
|
+
call: `mcphub call <tool> [k=v ...] [--server <s>|--group <g>|--smart] [--params-json <json>]
|
|
90
|
+
|
|
91
|
+
Discover what to pass via:
|
|
92
|
+
mcphub tools list # all tools
|
|
93
|
+
mcphub tools get <tool> # required params + sample command
|
|
94
|
+
|
|
95
|
+
Argument parsing:
|
|
96
|
+
key=value string by default
|
|
97
|
+
key=42 / key=true / key=null auto-coerced to number/boolean/null
|
|
98
|
+
key=@path load JSON from file
|
|
99
|
+
--params-json '{"a":1}' override the entire params object
|
|
100
|
+
|
|
101
|
+
Routing precedence: --smart > --server > --group > default ($smart). All
|
|
102
|
+
three resolve to /mcp/<slug>; --server is the natural pair for
|
|
103
|
+
\`tools list\` output.`,
|
|
104
|
+
export: `mcphub export [--out <path>]
|
|
105
|
+
|
|
106
|
+
Download the running hub's mcp_settings.json. Default: stdout (pretty JSON).`,
|
|
107
|
+
discover: `mcphub discover [subcommand] [--remote <url>] [--search <q>]
|
|
108
|
+
[--category <c>] [--tag <t>] [--limit <n>]
|
|
109
|
+
|
|
110
|
+
Browse the public marketplace API (requires the hub to have
|
|
111
|
+
systemConfig.discovery.enabled=true).
|
|
112
|
+
|
|
113
|
+
Subcommands:
|
|
114
|
+
(default) list market servers
|
|
115
|
+
info <name> show a single server
|
|
116
|
+
categories list categories
|
|
117
|
+
tags list tags`,
|
|
118
|
+
install: `mcphub install <name> [--remote <url>] [--type npm|docker|uvx|pip|binary]
|
|
119
|
+
[--to hub|file|stdout] [--out <path>]
|
|
120
|
+
[--env K=V ...] [--dry-run] [--yes] [--force]
|
|
121
|
+
|
|
122
|
+
Install a server from a remote hub's marketplace.
|
|
123
|
+
|
|
124
|
+
--to hub POST /api/servers on the active profile's hub (default)
|
|
125
|
+
--to file merge mcpServers into a Claude Desktop / OpenClaw-style JSON
|
|
126
|
+
--to stdout print the mcpServers snippet (same as --dry-run)
|
|
127
|
+
`,
|
|
128
|
+
};
|
|
129
|
+
export function printHelp(command) {
|
|
130
|
+
if (!command) {
|
|
131
|
+
printLine(TOP_LEVEL_HELP);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const help = COMMAND_HELP[command];
|
|
135
|
+
if (!help) {
|
|
136
|
+
printLine(`No help available for "${command}".`);
|
|
137
|
+
printLine('');
|
|
138
|
+
printLine(TOP_LEVEL_HELP);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
printLine(help);
|
|
142
|
+
}
|
|
143
|
+
export function printVersion() {
|
|
144
|
+
// The version is read lazily so tests don't have to mock the package.json
|
|
145
|
+
// path. We import via createRequire to keep this ESM-safe.
|
|
146
|
+
import('node:module').then(({ createRequire }) => {
|
|
147
|
+
try {
|
|
148
|
+
const require = createRequire(import.meta.url);
|
|
149
|
+
const pkg = require('../../package.json');
|
|
150
|
+
printLine(pkg.version ?? 'unknown');
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
printLine('unknown');
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BtB,CAAC;AAEF,MAAM,YAAY,GAA2B;IAC3C,KAAK,EAAE;;;;uBAIc;IAErB,MAAM,EAAE;;0EAEgE;IAExE,MAAM,EAAE;;;;;;;;0DAQgD;IAExD,OAAO,EAAE;;;;;;;;;sDAS2C;IAEpD,MAAM,EAAE;;;;;;;;gEAQsD;IAE9D,IAAI,EAAE;;;;;;gDAMwC;IAE9C,KAAK,EAAE;;;;;;;;;;qDAU4C;IAEnD,IAAI,EAAE;;;;;;;;;;;;;;uBAce;IAErB,MAAM,EAAE;;6EAEmE;IAE3E,QAAQ,EAAE;;;;;;;;;;6CAUiC;IAE3C,OAAO,EAAE;;;;;;;;;CASV;CACA,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,SAAS,CAAC,0BAA0B,OAAO,IAAI,CAAC,CAAC;QACjD,SAAS,CAAC,EAAE,CAAC,CAAC;QACd,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,0EAA0E;IAC1E,2DAA2D;IAC3D,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE;QAC/C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;YAC1C,SAAS,CAAC,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/cli/http.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { CliApiError } from './errors.js';
|
|
2
|
+
// Thin fetch wrapper. Auth injection is determined by tokenKind so a single
|
|
3
|
+
// client can target dashboard API (JWT via x-auth-token) or scoped bearer key
|
|
4
|
+
// (Authorization: Bearer ...) routes. Non-2xx → CliApiError with parsed body.
|
|
5
|
+
export class ApiClient {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, '');
|
|
8
|
+
this.token = opts.token;
|
|
9
|
+
this.tokenKind = opts.tokenKind ?? 'jwt';
|
|
10
|
+
this.fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
11
|
+
}
|
|
12
|
+
buildHeaders(extra) {
|
|
13
|
+
const headers = {
|
|
14
|
+
Accept: 'application/json',
|
|
15
|
+
...(extra ?? {}),
|
|
16
|
+
};
|
|
17
|
+
if (this.token) {
|
|
18
|
+
if (this.tokenKind === 'bearer') {
|
|
19
|
+
headers.Authorization = `Bearer ${this.token}`;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
headers['x-auth-token'] = this.token;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return headers;
|
|
26
|
+
}
|
|
27
|
+
async request(method, path, body, init) {
|
|
28
|
+
const url = path.startsWith('http') ? path : `${this.baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;
|
|
29
|
+
const headers = this.buildHeaders(init?.headers);
|
|
30
|
+
let payload;
|
|
31
|
+
if (body !== undefined) {
|
|
32
|
+
headers['Content-Type'] = 'application/json';
|
|
33
|
+
payload = JSON.stringify(body);
|
|
34
|
+
}
|
|
35
|
+
const res = await this.fetchImpl(url, {
|
|
36
|
+
...init,
|
|
37
|
+
method,
|
|
38
|
+
headers,
|
|
39
|
+
body: payload,
|
|
40
|
+
});
|
|
41
|
+
const text = await res.text();
|
|
42
|
+
let parsed = undefined;
|
|
43
|
+
if (text) {
|
|
44
|
+
try {
|
|
45
|
+
parsed = JSON.parse(text);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
parsed = text;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
const message = extractMessage(parsed) ?? `${method} ${path} failed with ${res.status}`;
|
|
53
|
+
throw new CliApiError({
|
|
54
|
+
status: res.status,
|
|
55
|
+
message,
|
|
56
|
+
body: parsed,
|
|
57
|
+
requiresLogin: res.status === 401,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return parsed;
|
|
61
|
+
}
|
|
62
|
+
get(path, init) {
|
|
63
|
+
return this.request('GET', path, undefined, init);
|
|
64
|
+
}
|
|
65
|
+
post(path, body, init) {
|
|
66
|
+
return this.request('POST', path, body, init);
|
|
67
|
+
}
|
|
68
|
+
put(path, body, init) {
|
|
69
|
+
return this.request('PUT', path, body, init);
|
|
70
|
+
}
|
|
71
|
+
delete(path, init) {
|
|
72
|
+
return this.request('DELETE', path, undefined, init);
|
|
73
|
+
}
|
|
74
|
+
// POST to /mcp/:group? with a JSON-RPC body. `group` may be a literal group
|
|
75
|
+
// name, '$smart' for smart routing, or null for the global endpoint.
|
|
76
|
+
async mcpCall(group, payload) {
|
|
77
|
+
const suffix = group ? `/${encodeURIComponent(group)}` : '';
|
|
78
|
+
return this.request('POST', `/mcp${suffix}`, payload);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function extractMessage(body) {
|
|
82
|
+
if (body && typeof body === 'object') {
|
|
83
|
+
const obj = body;
|
|
84
|
+
if (typeof obj.message === 'string')
|
|
85
|
+
return obj.message;
|
|
86
|
+
if (typeof obj.error === 'string')
|
|
87
|
+
return obj.error;
|
|
88
|
+
}
|
|
89
|
+
if (typeof body === 'string' && body.trim())
|
|
90
|
+
return body;
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=http.js.map
|