@samanhappy/mcphub 1.0.0 → 1.0.2
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 +6 -4
- package/README.md +24 -4
- package/README.zh.md +25 -4
- package/bin/cli.js +64 -50
- package/dist/betterAuth.js +21 -0
- package/dist/betterAuth.js.map +1 -1
- 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/controllers/serverController.js +3 -0
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/dao/ActivityDao.js +2 -0
- package/dist/dao/ActivityDao.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/Activity.js +4 -0
- package/dist/db/entities/Activity.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/activityLoggingService.js +1 -0
- package/dist/services/activityLoggingService.js.map +1 -1
- package/dist/services/betterAuthConfig.js +18 -1
- package/dist/services/betterAuthConfig.js.map +1 -1
- package/dist/services/dataService.js +10 -1
- package/dist/services/dataService.js.map +1 -1
- package/dist/services/mcpService.js +46 -12
- package/dist/services/mcpService.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/rateLimit.js +3 -3
- package/dist/utils/serverConfigPersistence.js +5 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/frontend/dist/assets/ActivityPage-B1B9ySGe.js +2 -0
- package/frontend/dist/assets/ActivityPage-B1B9ySGe.js.map +1 -0
- package/frontend/dist/assets/Dashboard-CYzpYZ1d.js +2 -0
- package/frontend/dist/assets/Dashboard-CYzpYZ1d.js.map +1 -0
- package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js → EndpointCopy-DVmlWW-s.js} +2 -2
- package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js.map → EndpointCopy-DVmlWW-s.js.map} +1 -1
- package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js → GroupsPage-CsyoUc8S.js} +2 -2
- package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js.map → GroupsPage-CsyoUc8S.js.map} +1 -1
- package/frontend/dist/assets/LoginPage-C3t8hbb2.js +2 -0
- package/frontend/dist/assets/LoginPage-C3t8hbb2.js.map +1 -0
- package/frontend/dist/assets/{LogsPage-HBGNLtyN.js → LogsPage-DOZeagVs.js} +2 -2
- package/frontend/dist/assets/{LogsPage-HBGNLtyN.js.map → LogsPage-DOZeagVs.js.map} +1 -1
- package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js → MarketPage-kMEHUGfJ.js} +2 -2
- package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js.map → MarketPage-kMEHUGfJ.js.map} +1 -1
- package/frontend/dist/assets/{PromptsPage-DUge8OO4.js → PromptsPage-D7JYoTav.js} +2 -2
- package/frontend/dist/assets/{PromptsPage-DUge8OO4.js.map → PromptsPage-D7JYoTav.js.map} +1 -1
- package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js → ResourcesPage-BlwePI9a.js} +2 -2
- package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js.map → ResourcesPage-BlwePI9a.js.map} +1 -1
- package/frontend/dist/assets/ServersPage-DrkPpCgK.js +37 -0
- package/frontend/dist/assets/ServersPage-DrkPpCgK.js.map +1 -0
- package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js → SettingsPage-BWigWLml.js} +2 -2
- package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js.map → SettingsPage-BWigWLml.js.map} +1 -1
- package/frontend/dist/assets/{StatusDot-DR803YdX.js → StatusDot-BDBIaafQ.js} +2 -2
- package/frontend/dist/assets/{StatusDot-DR803YdX.js.map → StatusDot-BDBIaafQ.js.map} +1 -1
- package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js → ToggleGroup-OOcsllhw.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js.map → ToggleGroup-OOcsllhw.js.map} +1 -1
- package/frontend/dist/assets/{UsersPage-CMscqAmn.js → UsersPage-DL8E7KtW.js} +2 -2
- package/frontend/dist/assets/{UsersPage-CMscqAmn.js.map → UsersPage-DL8E7KtW.js.map} +1 -1
- package/frontend/dist/assets/index-C7wNc_3N.js +3 -0
- package/frontend/dist/assets/index-C7wNc_3N.js.map +1 -0
- package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
- package/frontend/dist/assets/{resourceService-BFMkDDIh.js → resourceService-B-U4FKGB.js} +2 -2
- package/frontend/dist/assets/{resourceService-BFMkDDIh.js.map → resourceService-B-U4FKGB.js.map} +1 -1
- package/frontend/dist/assets/{useServerData-BnLmpLAC.js → useServerData-DYoDryJj.js} +2 -2
- package/frontend/dist/assets/{useServerData-BnLmpLAC.js.map → useServerData-DYoDryJj.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-6utb1Z46.js +2 -0
- package/frontend/dist/assets/{useSettingsData-Cqi9d7Ug.js.map → useSettingsData-6utb1Z46.js.map} +1 -1
- package/frontend/dist/assets/{variableDetection-BigiltQM.js → variableDetection-DsYuiOB_.js} +3 -3
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +2 -1
- package/frontend/dist/assets/ActivityPage-VwilVMvp.js +0 -2
- package/frontend/dist/assets/ActivityPage-VwilVMvp.js.map +0 -1
- package/frontend/dist/assets/Dashboard-DuBJTbbA.js +0 -2
- package/frontend/dist/assets/Dashboard-DuBJTbbA.js.map +0 -1
- package/frontend/dist/assets/LoginPage-C8RkMoJN.js +0 -2
- package/frontend/dist/assets/LoginPage-C8RkMoJN.js.map +0 -1
- package/frontend/dist/assets/ServersPage-DtnlfwJF.js +0 -37
- package/frontend/dist/assets/ServersPage-DtnlfwJF.js.map +0 -1
- package/frontend/dist/assets/index-B9cW2F0H.js +0 -3
- package/frontend/dist/assets/index-B9cW2F0H.js.map +0 -1
- package/frontend/dist/assets/index-Crcbkt8x.css +0 -1
- package/frontend/dist/assets/useSettingsData-Cqi9d7Ug.js +0 -2
- package/frontend/dist/assets/variableDetection-BigiltQM.js.map +0 -1
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/cli/http.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { CliApiError, CliUsageError } from './errors.js';
|
|
2
|
+
import { parseGlobalFlags } from './parse-args.js';
|
|
3
|
+
import { printError, printLine, printWarn } from './output.js';
|
|
4
|
+
import { printHelp, printVersion } from './help.js';
|
|
5
|
+
const SUBCOMMAND_LOADERS = {
|
|
6
|
+
login: () => import('./commands/login.js'),
|
|
7
|
+
logout: () => import('./commands/login.js'),
|
|
8
|
+
config: () => import('./commands/config.js'),
|
|
9
|
+
servers: () => import('./commands/servers.js'),
|
|
10
|
+
groups: () => import('./commands/groups.js'),
|
|
11
|
+
keys: () => import('./commands/keys.js'),
|
|
12
|
+
tools: () => import('./commands/tools.js'),
|
|
13
|
+
call: () => import('./commands/call.js'),
|
|
14
|
+
export: () => import('./commands/export.js'),
|
|
15
|
+
discover: () => import('./commands/discover.js'),
|
|
16
|
+
install: () => import('./commands/install.js'),
|
|
17
|
+
};
|
|
18
|
+
export async function runCli(argv) {
|
|
19
|
+
const { globalFlags, rest } = parseGlobalFlags(argv);
|
|
20
|
+
const command = rest.shift();
|
|
21
|
+
try {
|
|
22
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
23
|
+
printHelp(rest[0]);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (command === '--version' || command === '-v') {
|
|
27
|
+
printVersion();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const loader = SUBCOMMAND_LOADERS[command];
|
|
31
|
+
if (!loader) {
|
|
32
|
+
throw new CliUsageError(`Unknown command: ${command}. Run \`mcphub --help\` for a list.`);
|
|
33
|
+
}
|
|
34
|
+
const mod = await loader();
|
|
35
|
+
const handler = command === 'logout' ? mod.logout : mod.run;
|
|
36
|
+
if (!handler) {
|
|
37
|
+
throw new CliUsageError(`Command not implemented: ${command}`);
|
|
38
|
+
}
|
|
39
|
+
await handler(rest, globalFlags);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
handleTopLevelError(err, globalFlags);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function handleTopLevelError(err, globals) {
|
|
46
|
+
if (err instanceof CliUsageError) {
|
|
47
|
+
printError(err.message);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (err instanceof CliApiError) {
|
|
52
|
+
printError(`API error (${err.status}): ${err.message}`);
|
|
53
|
+
if (err.requiresLogin) {
|
|
54
|
+
printWarn('Hint: run `mcphub login` to refresh your token.');
|
|
55
|
+
}
|
|
56
|
+
if (globals.debug && err.body !== undefined) {
|
|
57
|
+
printLine(typeof err.body === 'string' ? err.body : JSON.stringify(err.body, null, 2));
|
|
58
|
+
}
|
|
59
|
+
process.exitCode = 2;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
63
|
+
printError(`Unexpected error: ${message}`);
|
|
64
|
+
if (globals.debug && err instanceof Error && err.stack) {
|
|
65
|
+
printLine(err.stack);
|
|
66
|
+
}
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
}
|
|
69
|
+
// Self-run when invoked directly (`tsx src/cli/main.ts ...` or
|
|
70
|
+
// `node dist/cli/main.js ...`). bin/cli.js also imports runCli explicitly, so
|
|
71
|
+
// the dispatcher works in both modes.
|
|
72
|
+
import { fileURLToPath as toPath } from 'node:url';
|
|
73
|
+
import process from 'node:process';
|
|
74
|
+
const invokedDirectly = process.argv[1] !== undefined &&
|
|
75
|
+
(process.argv[1] === toPath(import.meta.url) ||
|
|
76
|
+
process.argv[1].endsWith('/cli/main.ts') ||
|
|
77
|
+
process.argv[1].endsWith('/cli/main.js'));
|
|
78
|
+
if (invokedDirectly) {
|
|
79
|
+
void runCli(process.argv.slice(2));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// stdout/stderr helpers. Honors NO_COLOR and non-TTY stdout. JSON output is
|
|
2
|
+
// always emitted via printJson() so --json never mixes with ANSI escapes.
|
|
3
|
+
const colorEnabled = process.env.NO_COLOR === undefined &&
|
|
4
|
+
process.env.TERM !== 'dumb' &&
|
|
5
|
+
process.stdout.isTTY === true;
|
|
6
|
+
const wrap = (code, text) => colorEnabled ? `\x1b[${code}m${text}\x1b[0m` : text;
|
|
7
|
+
export const red = (s) => wrap(31, s);
|
|
8
|
+
export const green = (s) => wrap(32, s);
|
|
9
|
+
export const yellow = (s) => wrap(33, s);
|
|
10
|
+
export const cyan = (s) => wrap(36, s);
|
|
11
|
+
export const dim = (s) => wrap(2, s);
|
|
12
|
+
export const bold = (s) => wrap(1, s);
|
|
13
|
+
export function printJson(value) {
|
|
14
|
+
process.stdout.write(JSON.stringify(value, null, 2) + '\n');
|
|
15
|
+
}
|
|
16
|
+
export function printLine(text = '') {
|
|
17
|
+
process.stdout.write(text + '\n');
|
|
18
|
+
}
|
|
19
|
+
export function printError(text) {
|
|
20
|
+
process.stderr.write(red(text) + '\n');
|
|
21
|
+
}
|
|
22
|
+
export function printWarn(text) {
|
|
23
|
+
process.stderr.write(yellow(text) + '\n');
|
|
24
|
+
}
|
|
25
|
+
// Minimal column-aligned table printer. Renders to stdout. Columns are sized
|
|
26
|
+
// by the widest cell in each column; values are coerced via String().
|
|
27
|
+
export function printTable(rows, columns) {
|
|
28
|
+
if (rows.length === 0) {
|
|
29
|
+
printLine(dim('(empty)'));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const widths = columns.map((col) => Math.max(col.length, ...rows.map((r) => String(r[col] ?? '').length)));
|
|
33
|
+
const renderRow = (cells) => cells.map((cell, i) => cell.padEnd(widths[i])).join(' ');
|
|
34
|
+
printLine(bold(renderRow(columns)));
|
|
35
|
+
printLine(dim(renderRow(widths.map((w) => '-'.repeat(w)))));
|
|
36
|
+
for (const row of rows) {
|
|
37
|
+
printLine(renderRow(columns.map((col) => String(row[col] ?? ''))));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function maskToken(token) {
|
|
41
|
+
if (!token)
|
|
42
|
+
return '(none)';
|
|
43
|
+
if (token.length <= 4)
|
|
44
|
+
return '*'.repeat(token.length);
|
|
45
|
+
return '*'.repeat(Math.max(token.length - 4, 4)) + token.slice(-4);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { CliUsageError } from './errors.js';
|
|
2
|
+
// Boolean flags that don't take a value when present without "=".
|
|
3
|
+
const BOOLEAN_GLOBALS = new Set(['--bearer', '--json', '--debug']);
|
|
4
|
+
// Flags handled at the top level (consumed by main.ts before dispatching to
|
|
5
|
+
// a subcommand handler). Anything else flows through to the subcommand's
|
|
6
|
+
// argv unchanged so subcommand-specific flags can be parsed locally.
|
|
7
|
+
const VALUED_GLOBALS = new Set(['--url', '--token', '--profile']);
|
|
8
|
+
export function parseGlobalFlags(argv) {
|
|
9
|
+
const globalFlags = {};
|
|
10
|
+
const rest = [];
|
|
11
|
+
for (let i = 0; i < argv.length; i++) {
|
|
12
|
+
const arg = argv[i];
|
|
13
|
+
if (BOOLEAN_GLOBALS.has(arg)) {
|
|
14
|
+
assignFlag(globalFlags, arg, true);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (VALUED_GLOBALS.has(arg)) {
|
|
18
|
+
const value = argv[++i];
|
|
19
|
+
if (value === undefined) {
|
|
20
|
+
throw new CliUsageError(`Missing value for ${arg}`);
|
|
21
|
+
}
|
|
22
|
+
assignFlag(globalFlags, arg, value);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
// Support --flag=value form for valued flags
|
|
26
|
+
const eqIdx = arg.indexOf('=');
|
|
27
|
+
if (eqIdx > 0 && arg.startsWith('--')) {
|
|
28
|
+
const name = arg.slice(0, eqIdx);
|
|
29
|
+
const value = arg.slice(eqIdx + 1);
|
|
30
|
+
if (VALUED_GLOBALS.has(name)) {
|
|
31
|
+
assignFlag(globalFlags, name, value);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (BOOLEAN_GLOBALS.has(name)) {
|
|
35
|
+
assignFlag(globalFlags, name, value !== 'false');
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
rest.push(arg);
|
|
40
|
+
}
|
|
41
|
+
return { globalFlags, rest };
|
|
42
|
+
}
|
|
43
|
+
function assignFlag(target, flag, value) {
|
|
44
|
+
switch (flag) {
|
|
45
|
+
case '--url':
|
|
46
|
+
target.url = value;
|
|
47
|
+
break;
|
|
48
|
+
case '--token':
|
|
49
|
+
target.token = value;
|
|
50
|
+
break;
|
|
51
|
+
case '--bearer':
|
|
52
|
+
target.bearer = value;
|
|
53
|
+
break;
|
|
54
|
+
case '--profile':
|
|
55
|
+
target.profile = value;
|
|
56
|
+
break;
|
|
57
|
+
case '--json':
|
|
58
|
+
target.json = value;
|
|
59
|
+
break;
|
|
60
|
+
case '--debug':
|
|
61
|
+
target.debug = value;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Simple subcommand flag extractor. Pulls --name <value> and --bool occurrences
|
|
66
|
+
// out of `argv` and returns positional arguments. Supports --name=value too.
|
|
67
|
+
export function extractFlags(argv, spec) {
|
|
68
|
+
const valued = new Set(spec.valued ?? []);
|
|
69
|
+
const bools = new Set(spec.boolean ?? []);
|
|
70
|
+
const positional = [];
|
|
71
|
+
const flags = {};
|
|
72
|
+
for (let i = 0; i < argv.length; i++) {
|
|
73
|
+
const arg = argv[i];
|
|
74
|
+
if (bools.has(arg)) {
|
|
75
|
+
flags[arg] = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (valued.has(arg)) {
|
|
79
|
+
const value = argv[++i];
|
|
80
|
+
if (value === undefined) {
|
|
81
|
+
throw new CliUsageError(`Missing value for ${arg}`);
|
|
82
|
+
}
|
|
83
|
+
flags[arg] = value;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const eqIdx = arg.indexOf('=');
|
|
87
|
+
if (eqIdx > 0 && arg.startsWith('--')) {
|
|
88
|
+
const name = arg.slice(0, eqIdx);
|
|
89
|
+
const value = arg.slice(eqIdx + 1);
|
|
90
|
+
if (valued.has(name)) {
|
|
91
|
+
flags[name] = value;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (bools.has(name)) {
|
|
95
|
+
flags[name] = value !== 'false';
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
positional.push(arg);
|
|
100
|
+
}
|
|
101
|
+
return { positional, flags };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=parse-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-args.js","sourceRoot":"","sources":["../../src/cli/parse-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const APP_NAME = 'mcphub';
|
|
5
|
+
function homeDir() {
|
|
6
|
+
// Prefer HOME / USERPROFILE so tests (and users) can override via env. On
|
|
7
|
+
// some macOS configurations os.homedir() ignores HOME and reads the real
|
|
8
|
+
// passwd entry, which would defeat both isolation and explicit overrides.
|
|
9
|
+
return process.env.HOME || process.env.USERPROFILE || os.homedir() || process.cwd();
|
|
10
|
+
}
|
|
11
|
+
function xdgConfigHome() {
|
|
12
|
+
return process.env.XDG_CONFIG_HOME || path.join(homeDir(), '.config');
|
|
13
|
+
}
|
|
14
|
+
function xdgDataHome() {
|
|
15
|
+
return process.env.XDG_DATA_HOME || path.join(homeDir(), '.local', 'share');
|
|
16
|
+
}
|
|
17
|
+
function legacyDir() {
|
|
18
|
+
return path.join(homeDir(), `.${APP_NAME}`);
|
|
19
|
+
}
|
|
20
|
+
export function credentialsPath() {
|
|
21
|
+
const legacy = path.join(legacyDir(), 'credentials.json');
|
|
22
|
+
if (fs.existsSync(legacy)) {
|
|
23
|
+
return legacy;
|
|
24
|
+
}
|
|
25
|
+
return path.join(xdgDataHome(), APP_NAME, 'credentials.json');
|
|
26
|
+
}
|
|
27
|
+
export function configPath() {
|
|
28
|
+
return path.join(xdgConfigHome(), APP_NAME, 'config.json');
|
|
29
|
+
}
|
|
30
|
+
const EMPTY_CREDENTIALS = { current: '', profiles: {} };
|
|
31
|
+
export function loadCredentials() {
|
|
32
|
+
const p = credentialsPath();
|
|
33
|
+
if (!fs.existsSync(p)) {
|
|
34
|
+
return { ...EMPTY_CREDENTIALS };
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const raw = fs.readFileSync(p, 'utf8');
|
|
38
|
+
const parsed = JSON.parse(raw);
|
|
39
|
+
if (!parsed || typeof parsed !== 'object' || !parsed.profiles) {
|
|
40
|
+
return { ...EMPTY_CREDENTIALS };
|
|
41
|
+
}
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { ...EMPTY_CREDENTIALS };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function saveCredentials(creds) {
|
|
49
|
+
const p = credentialsPath();
|
|
50
|
+
const dir = path.dirname(p);
|
|
51
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
52
|
+
// Best-effort tighten on existing dir (mkdirSync mode is honored only on
|
|
53
|
+
// creation; chmod on dir works on POSIX, no-op on Windows).
|
|
54
|
+
try {
|
|
55
|
+
fs.chmodSync(dir, 0o700);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* ignore */
|
|
59
|
+
}
|
|
60
|
+
const tmp = `${p}.tmp.${process.pid}`;
|
|
61
|
+
fs.writeFileSync(tmp, JSON.stringify(creds, null, 2), { mode: 0o600 });
|
|
62
|
+
fs.renameSync(tmp, p);
|
|
63
|
+
try {
|
|
64
|
+
fs.chmodSync(p, 0o600);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* ignore */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function loadConfigFile() {
|
|
71
|
+
const p = configPath();
|
|
72
|
+
if (!fs.existsSync(p))
|
|
73
|
+
return {};
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function getProfile(creds, name) {
|
|
82
|
+
const target = name || creds.current;
|
|
83
|
+
if (!target)
|
|
84
|
+
return undefined;
|
|
85
|
+
return creds.profiles[target];
|
|
86
|
+
}
|
|
87
|
+
export function setProfile(creds, name, profile) {
|
|
88
|
+
return {
|
|
89
|
+
current: creds.current || name,
|
|
90
|
+
profiles: { ...creds.profiles, [name]: { ...profile, savedAt: new Date().toISOString() } },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function deleteProfile(creds, name) {
|
|
94
|
+
if (!(name in creds.profiles))
|
|
95
|
+
return creds;
|
|
96
|
+
const next = { ...creds.profiles };
|
|
97
|
+
delete next[name];
|
|
98
|
+
return {
|
|
99
|
+
current: creds.current === name ? Object.keys(next)[0] || '' : creds.current,
|
|
100
|
+
profiles: next,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export function setCurrentProfile(creds, name) {
|
|
104
|
+
if (!(name in creds.profiles)) {
|
|
105
|
+
throw new Error(`Profile not found: ${name}`);
|
|
106
|
+
}
|
|
107
|
+
return { ...creds, current: name };
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/cli/profile.ts"],"names":[],"mappings":"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"}
|