@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.
Files changed (133) hide show
  1. package/README.fr.md +6 -4
  2. package/README.md +24 -4
  3. package/README.zh.md +25 -4
  4. package/bin/cli.js +64 -50
  5. package/dist/betterAuth.js +21 -0
  6. package/dist/betterAuth.js.map +1 -1
  7. package/dist/cli/call-arguments.js +81 -0
  8. package/dist/cli/call-arguments.js.map +1 -0
  9. package/dist/cli/commands/call.js +75 -0
  10. package/dist/cli/commands/call.js.map +1 -0
  11. package/dist/cli/commands/config.js +132 -0
  12. package/dist/cli/commands/config.js.map +1 -0
  13. package/dist/cli/commands/discover.js +127 -0
  14. package/dist/cli/commands/discover.js.map +1 -0
  15. package/dist/cli/commands/export.js +20 -0
  16. package/dist/cli/commands/export.js.map +1 -0
  17. package/dist/cli/commands/groups.js +107 -0
  18. package/dist/cli/commands/groups.js.map +1 -0
  19. package/dist/cli/commands/install.js +173 -0
  20. package/dist/cli/commands/install.js.map +1 -0
  21. package/dist/cli/commands/keys.js +91 -0
  22. package/dist/cli/commands/keys.js.map +1 -0
  23. package/dist/cli/commands/login.js +70 -0
  24. package/dist/cli/commands/login.js.map +1 -0
  25. package/dist/cli/commands/servers.js +142 -0
  26. package/dist/cli/commands/servers.js.map +1 -0
  27. package/dist/cli/commands/tools.js +162 -0
  28. package/dist/cli/commands/tools.js.map +1 -0
  29. package/dist/cli/context.js +44 -0
  30. package/dist/cli/context.js.map +1 -0
  31. package/dist/cli/errors.js +19 -0
  32. package/dist/cli/errors.js.map +1 -0
  33. package/dist/cli/help.js +157 -0
  34. package/dist/cli/help.js.map +1 -0
  35. package/dist/cli/http.js +93 -0
  36. package/dist/cli/http.js.map +1 -0
  37. package/dist/cli/main.js +81 -0
  38. package/dist/cli/main.js.map +1 -0
  39. package/dist/cli/output.js +47 -0
  40. package/dist/cli/output.js.map +1 -0
  41. package/dist/cli/parse-args.js +103 -0
  42. package/dist/cli/parse-args.js.map +1 -0
  43. package/dist/cli/profile.js +109 -0
  44. package/dist/cli/profile.js.map +1 -0
  45. package/dist/cli/prompts.js +56 -0
  46. package/dist/cli/prompts.js.map +1 -0
  47. package/dist/controllers/oauthServerController.js +37 -1
  48. package/dist/controllers/oauthServerController.js.map +1 -1
  49. package/dist/controllers/serverController.js +3 -0
  50. package/dist/controllers/serverController.js.map +1 -1
  51. package/dist/dao/ActivityDao.js +2 -0
  52. package/dist/dao/ActivityDao.js.map +1 -1
  53. package/dist/dao/ServerDaoDbImpl.js +3 -0
  54. package/dist/dao/ServerDaoDbImpl.js.map +1 -1
  55. package/dist/db/connection.js +48 -4
  56. package/dist/db/connection.js.map +1 -1
  57. package/dist/db/entities/Activity.js +4 -0
  58. package/dist/db/entities/Activity.js.map +1 -1
  59. package/dist/db/entities/Server.js +4 -0
  60. package/dist/db/entities/Server.js.map +1 -1
  61. package/dist/db/entities/VectorEmbedding.js +2 -5
  62. package/dist/db/entities/VectorEmbedding.js.map +1 -1
  63. package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
  64. package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
  65. package/dist/services/activityLoggingService.js +1 -0
  66. package/dist/services/activityLoggingService.js.map +1 -1
  67. package/dist/services/betterAuthConfig.js +18 -1
  68. package/dist/services/betterAuthConfig.js.map +1 -1
  69. package/dist/services/dataService.js +10 -1
  70. package/dist/services/dataService.js.map +1 -1
  71. package/dist/services/mcpService.js +46 -12
  72. package/dist/services/mcpService.js.map +1 -1
  73. package/dist/services/vectorSearchService.js +16 -3
  74. package/dist/services/vectorSearchService.js.map +1 -1
  75. package/dist/utils/migration.js +1 -0
  76. package/dist/utils/migration.js.map +1 -1
  77. package/dist/utils/rateLimit.js +3 -3
  78. package/dist/utils/serverConfigPersistence.js +5 -0
  79. package/dist/utils/serverConfigPersistence.js.map +1 -1
  80. package/frontend/dist/assets/ActivityPage-B1B9ySGe.js +2 -0
  81. package/frontend/dist/assets/ActivityPage-B1B9ySGe.js.map +1 -0
  82. package/frontend/dist/assets/Dashboard-CYzpYZ1d.js +2 -0
  83. package/frontend/dist/assets/Dashboard-CYzpYZ1d.js.map +1 -0
  84. package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js → EndpointCopy-DVmlWW-s.js} +2 -2
  85. package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js.map → EndpointCopy-DVmlWW-s.js.map} +1 -1
  86. package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js → GroupsPage-CsyoUc8S.js} +2 -2
  87. package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js.map → GroupsPage-CsyoUc8S.js.map} +1 -1
  88. package/frontend/dist/assets/LoginPage-C3t8hbb2.js +2 -0
  89. package/frontend/dist/assets/LoginPage-C3t8hbb2.js.map +1 -0
  90. package/frontend/dist/assets/{LogsPage-HBGNLtyN.js → LogsPage-DOZeagVs.js} +2 -2
  91. package/frontend/dist/assets/{LogsPage-HBGNLtyN.js.map → LogsPage-DOZeagVs.js.map} +1 -1
  92. package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js → MarketPage-kMEHUGfJ.js} +2 -2
  93. package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js.map → MarketPage-kMEHUGfJ.js.map} +1 -1
  94. package/frontend/dist/assets/{PromptsPage-DUge8OO4.js → PromptsPage-D7JYoTav.js} +2 -2
  95. package/frontend/dist/assets/{PromptsPage-DUge8OO4.js.map → PromptsPage-D7JYoTav.js.map} +1 -1
  96. package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js → ResourcesPage-BlwePI9a.js} +2 -2
  97. package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js.map → ResourcesPage-BlwePI9a.js.map} +1 -1
  98. package/frontend/dist/assets/ServersPage-DrkPpCgK.js +37 -0
  99. package/frontend/dist/assets/ServersPage-DrkPpCgK.js.map +1 -0
  100. package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js → SettingsPage-BWigWLml.js} +2 -2
  101. package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js.map → SettingsPage-BWigWLml.js.map} +1 -1
  102. package/frontend/dist/assets/{StatusDot-DR803YdX.js → StatusDot-BDBIaafQ.js} +2 -2
  103. package/frontend/dist/assets/{StatusDot-DR803YdX.js.map → StatusDot-BDBIaafQ.js.map} +1 -1
  104. package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js → ToggleGroup-OOcsllhw.js} +2 -2
  105. package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js.map → ToggleGroup-OOcsllhw.js.map} +1 -1
  106. package/frontend/dist/assets/{UsersPage-CMscqAmn.js → UsersPage-DL8E7KtW.js} +2 -2
  107. package/frontend/dist/assets/{UsersPage-CMscqAmn.js.map → UsersPage-DL8E7KtW.js.map} +1 -1
  108. package/frontend/dist/assets/index-C7wNc_3N.js +3 -0
  109. package/frontend/dist/assets/index-C7wNc_3N.js.map +1 -0
  110. package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
  111. package/frontend/dist/assets/{resourceService-BFMkDDIh.js → resourceService-B-U4FKGB.js} +2 -2
  112. package/frontend/dist/assets/{resourceService-BFMkDDIh.js.map → resourceService-B-U4FKGB.js.map} +1 -1
  113. package/frontend/dist/assets/{useServerData-BnLmpLAC.js → useServerData-DYoDryJj.js} +2 -2
  114. package/frontend/dist/assets/{useServerData-BnLmpLAC.js.map → useServerData-DYoDryJj.js.map} +1 -1
  115. package/frontend/dist/assets/useSettingsData-6utb1Z46.js +2 -0
  116. package/frontend/dist/assets/{useSettingsData-Cqi9d7Ug.js.map → useSettingsData-6utb1Z46.js.map} +1 -1
  117. package/frontend/dist/assets/{variableDetection-BigiltQM.js → variableDetection-DsYuiOB_.js} +3 -3
  118. package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
  119. package/frontend/dist/index.html +2 -2
  120. package/package.json +2 -1
  121. package/frontend/dist/assets/ActivityPage-VwilVMvp.js +0 -2
  122. package/frontend/dist/assets/ActivityPage-VwilVMvp.js.map +0 -1
  123. package/frontend/dist/assets/Dashboard-DuBJTbbA.js +0 -2
  124. package/frontend/dist/assets/Dashboard-DuBJTbbA.js.map +0 -1
  125. package/frontend/dist/assets/LoginPage-C8RkMoJN.js +0 -2
  126. package/frontend/dist/assets/LoginPage-C8RkMoJN.js.map +0 -1
  127. package/frontend/dist/assets/ServersPage-DtnlfwJF.js +0 -37
  128. package/frontend/dist/assets/ServersPage-DtnlfwJF.js.map +0 -1
  129. package/frontend/dist/assets/index-B9cW2F0H.js +0 -3
  130. package/frontend/dist/assets/index-B9cW2F0H.js.map +0 -1
  131. package/frontend/dist/assets/index-Crcbkt8x.css +0 -1
  132. package/frontend/dist/assets/useSettingsData-Cqi9d7Ug.js +0 -2
  133. package/frontend/dist/assets/variableDetection-BigiltQM.js.map +0 -1
@@ -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"}
@@ -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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"}
@@ -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":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,kEAAkE;AAClE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAEnE,4EAA4E;AAC5E,yEAAyE;AACzE,qEAAqE;AAErE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AAOlE,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,MAAM,WAAW,GAAgB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACnC,SAAS;QACX,CAAC;QAED,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,aAAa,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YACtD,CAAC;YACD,UAAU,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QAED,6CAA6C;QAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACnC,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBACrC,SAAS;YACX,CAAC;YACD,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC;gBACjD,SAAS;YACX,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,UAAU,CAAC,MAAmB,EAAE,IAAY,EAAE,KAAuB;IAC5E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,MAAM,CAAC,GAAG,GAAG,KAAe,CAAC;YAC7B,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,CAAC,KAAK,GAAG,KAAe,CAAC;YAC/B,MAAM;QACR,KAAK,UAAU;YACb,MAAM,CAAC,MAAM,GAAG,KAAgB,CAAC;YACjC,MAAM;QACR,KAAK,WAAW;YACd,MAAM,CAAC,OAAO,GAAG,KAAe,CAAC;YACjC,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,CAAC,IAAI,GAAG,KAAgB,CAAC;YAC/B,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,CAAC,KAAK,GAAG,KAAgB,CAAC;YAChC,MAAM;IACV,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAC1B,IAAc,EACd,IAA+C;IAE/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAqC,EAAE,CAAC;IAEnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,aAAa,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YACtD,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACnB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACnC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC;gBAChC,SAAS;YACX,CAAC;QACH,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC"}
@@ -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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"}