mcpick 0.0.17 → 0.0.19

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 (75) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/CHANGELOG.md +15 -0
  3. package/dist/add-B9nVyh8T.js +113 -0
  4. package/dist/add-json-CXNDl3al.js +58 -0
  5. package/dist/atomic-write-BqEykHp9.js +26 -0
  6. package/dist/backup-DSDhHI5f.js +64 -0
  7. package/dist/cache-D6kd7qE8.js +226 -0
  8. package/dist/claude-cli-BeA-bmoW.js +394 -0
  9. package/dist/cli-DNNZjJYL.js +84 -0
  10. package/dist/clone-DLFLewBY.js +88 -0
  11. package/dist/config-DijVdEFn.js +176 -0
  12. package/dist/dev-DRJRNp7y.js +265 -0
  13. package/dist/disable-BA8tXPJN.js +39 -0
  14. package/dist/enable-Bdnnn_Cq.js +40 -0
  15. package/dist/get-BPjMXTMc.js +41 -0
  16. package/dist/hook-state-Di8lUsPr.js +171 -0
  17. package/dist/hooks-Bmn7pUZa.js +280 -0
  18. package/dist/index.js +1230 -303
  19. package/dist/list-B8YeDWt6.js +64 -0
  20. package/dist/marketplace-Br89Tg-Z.js +168 -0
  21. package/dist/output-BchYq0mR.js +15 -0
  22. package/dist/paths-BPISiJi4.js +124 -0
  23. package/dist/plugin-cache-Bby9Dxm9.js +405 -0
  24. package/dist/plugins-DHYJF5CP.js +212 -0
  25. package/dist/profile-CX97sMGp.js +120 -0
  26. package/dist/profile-DkY_lBEm.js +70 -0
  27. package/dist/redact-O35tjnRD.js +26 -0
  28. package/dist/registry-CfUKT7_C.js +92 -0
  29. package/dist/reload-CYDhkCVZ.js +31 -0
  30. package/dist/remove-DIPWYMpk.js +31 -0
  31. package/dist/reset-project-choices-DRM5KByw.js +28 -0
  32. package/dist/restore-DdMfUljI.js +84 -0
  33. package/dist/rolldown-runtime-CiIaOW0V.js +13 -0
  34. package/dist/settings-DEcWtzLE.js +201 -0
  35. package/dist/validation-xMlbgGCF.js +44 -0
  36. package/package.json +20 -19
  37. package/dist/cli/commands/add-json.js +0 -60
  38. package/dist/cli/commands/add.js +0 -135
  39. package/dist/cli/commands/backup.js +0 -83
  40. package/dist/cli/commands/cache.js +0 -296
  41. package/dist/cli/commands/dev.js +0 -161
  42. package/dist/cli/commands/disable.js +0 -36
  43. package/dist/cli/commands/enable.js +0 -39
  44. package/dist/cli/commands/get.js +0 -45
  45. package/dist/cli/commands/hooks.js +0 -314
  46. package/dist/cli/commands/list.js +0 -63
  47. package/dist/cli/commands/marketplace.js +0 -211
  48. package/dist/cli/commands/plugins.js +0 -265
  49. package/dist/cli/commands/profile.js +0 -134
  50. package/dist/cli/commands/reload.js +0 -36
  51. package/dist/cli/commands/remove.js +0 -35
  52. package/dist/cli/commands/reset-project-choices.js +0 -32
  53. package/dist/cli/commands/restore.js +0 -105
  54. package/dist/cli/index.js +0 -28
  55. package/dist/cli/output.js +0 -21
  56. package/dist/commands/add-server.js +0 -310
  57. package/dist/commands/backup.js +0 -60
  58. package/dist/commands/edit-config.js +0 -109
  59. package/dist/commands/edit-plugins.js +0 -201
  60. package/dist/commands/manage-cache.js +0 -155
  61. package/dist/commands/manage-hooks.js +0 -99
  62. package/dist/commands/manage-marketplace.js +0 -293
  63. package/dist/commands/restore.js +0 -118
  64. package/dist/core/config.js +0 -146
  65. package/dist/core/dev-override.js +0 -210
  66. package/dist/core/hook-state.js +0 -220
  67. package/dist/core/plugin-cache.js +0 -506
  68. package/dist/core/profile.js +0 -94
  69. package/dist/core/registry.js +0 -121
  70. package/dist/core/settings.js +0 -243
  71. package/dist/core/validation.js +0 -49
  72. package/dist/types.js +0 -2
  73. package/dist/utils/atomic-write.js +0 -27
  74. package/dist/utils/claude-cli.js +0 -483
  75. package/dist/utils/paths.js +0 -114
@@ -0,0 +1,5 @@
1
+ {
2
+ "editor.defaultFormatter": "oxc.oxc-vscode",
3
+ "editor.formatOnSave": true,
4
+ "oxc.fmt.configPath": "./vite.config.ts"
5
+ }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # mcpick
2
2
 
3
+ ## 0.0.19
4
+
5
+ ### Patch Changes
6
+
7
+ - 5ed618e: Migrate build tooling from tsc/prettier to vite-plus, fix all lint warnings
8
+ - 08997dc: feat: rewrite --help for LLM agents with workflow, concepts, and examples sections
9
+
10
+ ## 0.0.18
11
+
12
+ ### Patch Changes
13
+
14
+ - 58ff00f: Add clone command and skip redundant stdio transport flag
15
+ - 7f277da: redact env keys when listing
16
+ - b52fcbd: Show available CLI commands hint in TUI intro
17
+
3
18
  ## 0.0.17
4
19
 
5
20
  ### Patch Changes
@@ -0,0 +1,113 @@
1
+ import { n as validate_mcp_server } from "./validation-xMlbgGCF.js";
2
+ import { t as add_server_to_registry } from "./registry-CfUKT7_C.js";
3
+ import { t as add_mcp_via_cli } from "./claude-cli-BeA-bmoW.js";
4
+ import { n as output, t as error } from "./output-BchYq0mR.js";
5
+ import { defineCommand } from "citty";
6
+ //#region src/cli/commands/add.ts
7
+ var add_default = defineCommand({
8
+ meta: {
9
+ name: "add",
10
+ description: "Add a new MCP server to the registry and enable it"
11
+ },
12
+ args: {
13
+ name: {
14
+ type: "string",
15
+ description: "Server name",
16
+ required: true
17
+ },
18
+ command: {
19
+ type: "string",
20
+ description: "Command to run (for stdio transport)"
21
+ },
22
+ args: {
23
+ type: "string",
24
+ description: "Comma-separated arguments (e.g. \"npx,-y,mcp-sqlite\")"
25
+ },
26
+ url: {
27
+ type: "string",
28
+ description: "URL (for sse or http transport)"
29
+ },
30
+ type: {
31
+ type: "string",
32
+ description: "Transport type: stdio, sse, or http (default: stdio)",
33
+ default: "stdio"
34
+ },
35
+ env: {
36
+ type: "string",
37
+ description: "Environment variables as KEY=val,KEY=val"
38
+ },
39
+ headers: {
40
+ type: "string",
41
+ description: "HTTP headers as KEY=val,KEY=val"
42
+ },
43
+ description: {
44
+ type: "string",
45
+ description: "Server description"
46
+ },
47
+ scope: {
48
+ type: "string",
49
+ description: "Scope: local, project, or user (default: local)",
50
+ default: "local"
51
+ },
52
+ json: {
53
+ type: "boolean",
54
+ description: "Output as JSON",
55
+ default: false
56
+ }
57
+ },
58
+ async run({ args }) {
59
+ const scope = args.scope;
60
+ if (![
61
+ "local",
62
+ "project",
63
+ "user"
64
+ ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
65
+ const transport = args.type;
66
+ if (![
67
+ "stdio",
68
+ "sse",
69
+ "http"
70
+ ].includes(transport)) error(`Invalid type: ${transport}. Use stdio, sse, or http.`);
71
+ const server_data = { name: args.name };
72
+ if (transport === "stdio") {
73
+ if (!args.command) error("--command is required for stdio transport");
74
+ server_data.command = args.command;
75
+ if (args.args) server_data.args = args.args.split(",");
76
+ } else {
77
+ if (!args.url) error(`--url is required for ${transport} transport`);
78
+ server_data.type = transport;
79
+ server_data.url = args.url;
80
+ if (args.headers) server_data.headers = parse_key_value_pairs(args.headers);
81
+ }
82
+ if (args.env) server_data.env = parse_key_value_pairs(args.env);
83
+ if (args.description) server_data.description = args.description;
84
+ let server;
85
+ try {
86
+ server = validate_mcp_server(server_data);
87
+ } catch (err) {
88
+ error(`Invalid server config: ${err instanceof Error ? err.message : "validation failed"}`);
89
+ }
90
+ await add_server_to_registry(server);
91
+ const result = await add_mcp_via_cli(server, scope);
92
+ if (args.json) output({
93
+ added: server.name,
94
+ scope,
95
+ cli: result.success,
96
+ error: result.error
97
+ }, true);
98
+ else if (result.success) console.log(`Added '${server.name}' and enabled (scope: ${scope})`);
99
+ else console.log(`Added '${server.name}' to registry but CLI failed: ${result.error}`);
100
+ }
101
+ });
102
+ function parse_key_value_pairs(input) {
103
+ const result = {};
104
+ for (const pair of input.split(",")) {
105
+ const eq = pair.indexOf("=");
106
+ if (eq > 0) result[pair.substring(0, eq)] = pair.substring(eq + 1);
107
+ }
108
+ return result;
109
+ }
110
+ //#endregion
111
+ export { add_default as default };
112
+
113
+ //# sourceMappingURL=add-B9nVyh8T.js.map
@@ -0,0 +1,58 @@
1
+ import { u as mcp_add_json_via_cli } from "./claude-cli-BeA-bmoW.js";
2
+ import { n as output, t as error } from "./output-BchYq0mR.js";
3
+ import { defineCommand } from "citty";
4
+ //#region src/cli/commands/add-json.ts
5
+ var add_json_default = defineCommand({
6
+ meta: {
7
+ name: "add-json",
8
+ description: "Add an MCP server from a JSON configuration string"
9
+ },
10
+ args: {
11
+ name: {
12
+ type: "positional",
13
+ description: "Server name",
14
+ required: true
15
+ },
16
+ config: {
17
+ type: "positional",
18
+ description: "JSON configuration string",
19
+ required: true
20
+ },
21
+ scope: {
22
+ type: "string",
23
+ description: "Scope: local, project, or user (default: local)",
24
+ default: "local"
25
+ },
26
+ json: {
27
+ type: "boolean",
28
+ description: "Output as JSON",
29
+ default: false
30
+ }
31
+ },
32
+ async run({ args }) {
33
+ const scope = args.scope;
34
+ if (![
35
+ "local",
36
+ "project",
37
+ "user"
38
+ ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
39
+ try {
40
+ JSON.parse(args.config);
41
+ } catch {
42
+ error("Invalid JSON configuration. Provide a valid JSON string.");
43
+ }
44
+ const result = await mcp_add_json_via_cli(args.name, args.config, scope);
45
+ if (args.json) output({
46
+ added: args.name,
47
+ scope,
48
+ success: result.success,
49
+ error: result.error
50
+ }, true);
51
+ else if (result.success) console.log(`Added '${args.name}' from JSON (scope: ${scope})`);
52
+ else error(result.error || "Unknown error");
53
+ }
54
+ });
55
+ //#endregion
56
+ export { add_json_default as default };
57
+
58
+ //# sourceMappingURL=add-json-CXNDl3al.js.map
@@ -0,0 +1,26 @@
1
+ import { readFile, rename, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ //#region src/utils/atomic-write.ts
4
+ /**
5
+ * Atomically write a JSON file with fresh-read merging.
6
+ *
7
+ * 1. Re-reads the file right before writing to pick up concurrent changes
8
+ * 2. Applies the merge function to the freshest data
9
+ * 3. Writes to a temp file, then renames (atomic on same filesystem)
10
+ */
11
+ async function atomic_json_write(file_path, merge) {
12
+ let existing = {};
13
+ try {
14
+ const content = await readFile(file_path, "utf-8");
15
+ existing = JSON.parse(content);
16
+ } catch {}
17
+ const merged = merge(existing);
18
+ const content = JSON.stringify(merged, null, 2);
19
+ const tmp_path = join(dirname(file_path), `.${Date.now()}.tmp`);
20
+ await writeFile(tmp_path, content, "utf-8");
21
+ await rename(tmp_path, file_path);
22
+ }
23
+ //#endregion
24
+ export { atomic_json_write as t };
25
+
26
+ //# sourceMappingURL=atomic-write-BqEykHp9.js.map
@@ -0,0 +1,64 @@
1
+ import { m as get_plugin_backup_filename, n as get_backup_filename, r as get_backups_dir, t as ensure_directory_exists } from "./paths-BPISiJi4.js";
2
+ import { s as read_claude_config } from "./config-DijVdEFn.js";
3
+ import { a as read_claude_settings } from "./settings-DEcWtzLE.js";
4
+ import { n as output } from "./output-BchYq0mR.js";
5
+ import { readdir, unlink, writeFile } from "node:fs/promises";
6
+ import { join } from "node:path";
7
+ import { defineCommand } from "citty";
8
+ //#region src/cli/commands/backup.ts
9
+ const MAX_BACKUPS = 10;
10
+ async function cleanup_old_backups(prefix) {
11
+ try {
12
+ const backups_dir = get_backups_dir();
13
+ const backup_files = (await readdir(backups_dir)).filter((f) => f.startsWith(prefix) && f.endsWith(".json")).sort().reverse();
14
+ if (backup_files.length > MAX_BACKUPS) for (const file of backup_files.slice(MAX_BACKUPS)) await unlink(join(backups_dir, file));
15
+ } catch {}
16
+ }
17
+ var backup_default = defineCommand({
18
+ meta: {
19
+ name: "backup",
20
+ description: "Create a timestamped backup of MCP servers and plugins"
21
+ },
22
+ args: { json: {
23
+ type: "boolean",
24
+ description: "Output as JSON",
25
+ default: false
26
+ } },
27
+ async run({ args }) {
28
+ const current_config = await read_claude_config();
29
+ const current_settings = await read_claude_settings();
30
+ const backups_dir = get_backups_dir();
31
+ await ensure_directory_exists(backups_dir);
32
+ const mcp_path = join(backups_dir, get_backup_filename());
33
+ const mcp_backup = { mcpServers: current_config.mcpServers || {} };
34
+ await writeFile(mcp_path, JSON.stringify(mcp_backup, null, 2), "utf-8");
35
+ const plugins = current_settings.enabledPlugins || {};
36
+ const plugin_count = Object.keys(plugins).length;
37
+ let plugin_path = null;
38
+ if (plugin_count > 0) {
39
+ plugin_path = join(backups_dir, get_plugin_backup_filename());
40
+ await writeFile(plugin_path, JSON.stringify({ enabledPlugins: plugins }, null, 2), "utf-8");
41
+ }
42
+ await cleanup_old_backups("mcp-servers-");
43
+ await cleanup_old_backups("plugins-");
44
+ const server_count = Object.keys(current_config.mcpServers || {}).length;
45
+ if (args.json) output({
46
+ mcp: {
47
+ path: mcp_path,
48
+ servers: server_count
49
+ },
50
+ plugins: plugin_path ? {
51
+ path: plugin_path,
52
+ plugins: plugin_count
53
+ } : null
54
+ }, true);
55
+ else {
56
+ console.log(`Backup created: ${mcp_path} (${server_count} servers)`);
57
+ if (plugin_path) console.log(`Plugin backup: ${plugin_path} (${plugin_count} plugins)`);
58
+ }
59
+ }
60
+ });
61
+ //#endregion
62
+ export { backup_default as default };
63
+
64
+ //# sourceMappingURL=backup-DSDhHI5f.js.map
@@ -0,0 +1,226 @@
1
+ import { a as list_linked_plugins, c as read_installed_plugins, d as refresh_all_marketplaces, f as scan_all_cache_keys, i as link_local_plugin, n as clear_plugin_caches, p as unlink_local_plugin, r as get_cached_plugins_info, t as clean_orphaned_versions } from "./plugin-cache-Bby9Dxm9.js";
2
+ import { n as output, t as error } from "./output-BchYq0mR.js";
3
+ import { defineCommand } from "citty";
4
+ var cache_default = defineCommand({
5
+ meta: {
6
+ name: "cache",
7
+ description: "Manage plugin cache"
8
+ },
9
+ subCommands: {
10
+ status: defineCommand({
11
+ meta: {
12
+ name: "status",
13
+ description: "Show cached plugins with staleness info"
14
+ },
15
+ args: { json: {
16
+ type: "boolean",
17
+ description: "Output as JSON",
18
+ default: false
19
+ } },
20
+ async run({ args }) {
21
+ const plugins = await get_cached_plugins_info();
22
+ if (args.json) {
23
+ output(plugins, true);
24
+ return;
25
+ }
26
+ if (plugins.length === 0) {
27
+ console.log("No cached plugins found.");
28
+ return;
29
+ }
30
+ for (const p of plugins) {
31
+ const stale_markers = [];
32
+ if (p.isVersionStale) stale_markers.push(`version: ${p.installedVersion} → ${p.latestVersion}`);
33
+ if (p.isShaStale) stale_markers.push("commits behind");
34
+ if (p.orphanedVersions.length > 0) stale_markers.push(`${p.orphanedVersions.length} orphaned`);
35
+ const status_str = stale_markers.length > 0 ? ` [stale: ${stale_markers.join(", ")}]` : " [up to date]";
36
+ console.log(`${p.name}@${p.marketplace} v${p.installedVersion}${status_str}`);
37
+ }
38
+ }
39
+ }),
40
+ clear: defineCommand({
41
+ meta: {
42
+ name: "clear",
43
+ description: "Clear plugin caches (refreshes marketplace first)"
44
+ },
45
+ args: {
46
+ plugin: {
47
+ type: "positional",
48
+ description: "Plugin key (name@marketplace) — omit for all",
49
+ required: false
50
+ },
51
+ all: {
52
+ type: "boolean",
53
+ description: "Clear all plugin caches",
54
+ default: false
55
+ },
56
+ json: {
57
+ type: "boolean",
58
+ description: "Output as JSON",
59
+ default: false
60
+ }
61
+ },
62
+ async run({ args }) {
63
+ const installed = await read_installed_plugins();
64
+ const installed_keys = Object.keys(installed.plugins);
65
+ const scanned_keys = args.all ? await scan_all_cache_keys() : [];
66
+ const all_keys = [...new Set([...installed_keys, ...scanned_keys])];
67
+ if (all_keys.length === 0) {
68
+ if (args.json) output({
69
+ cleared: [],
70
+ errors: []
71
+ }, true);
72
+ else console.log("No cached plugins to clear.");
73
+ return;
74
+ }
75
+ let keys_to_clear;
76
+ if (args.plugin) {
77
+ if (!installed.plugins[args.plugin] && !scanned_keys.includes(args.plugin)) error(`Plugin '${args.plugin}' not found in cache. Run 'mcpick cache status' to see cached plugins.`);
78
+ keys_to_clear = [args.plugin];
79
+ } else if (args.all) keys_to_clear = all_keys;
80
+ else error("Specify a plugin key or use --all. Run \"mcpick cache status\" to see cached plugins.");
81
+ const result = await clear_plugin_caches(keys_to_clear);
82
+ if (args.json) output(result, true);
83
+ else {
84
+ for (const key of result.cleared) console.log(`Cleared: ${key}`);
85
+ for (const err of result.errors) console.error(`Error: ${err}`);
86
+ if (result.cleared.length > 0) console.log("\nRun /reload-plugins in Claude Code or restart your session.");
87
+ }
88
+ }
89
+ }),
90
+ "clean-orphaned": defineCommand({
91
+ meta: {
92
+ name: "clean-orphaned",
93
+ description: "Remove orphaned plugin version directories"
94
+ },
95
+ args: { json: {
96
+ type: "boolean",
97
+ description: "Output as JSON",
98
+ default: false
99
+ } },
100
+ async run({ args }) {
101
+ const result = await clean_orphaned_versions();
102
+ if (args.json) output(result, true);
103
+ else if (result.cleaned === 0) console.log("No orphaned versions found.");
104
+ else {
105
+ for (const p of result.paths) console.log(`Removed: ${p}`);
106
+ console.log(`\nCleaned ${result.cleaned} orphaned version(s).`);
107
+ }
108
+ }
109
+ }),
110
+ refresh: defineCommand({
111
+ meta: {
112
+ name: "refresh",
113
+ description: "Refresh all marketplace clones (git pull)"
114
+ },
115
+ args: { json: {
116
+ type: "boolean",
117
+ description: "Output as JSON",
118
+ default: false
119
+ } },
120
+ async run({ args }) {
121
+ const results = await refresh_all_marketplaces();
122
+ if (args.json) {
123
+ output(Object.fromEntries(results), true);
124
+ return;
125
+ }
126
+ if (results.size === 0) {
127
+ console.log("No marketplaces configured.");
128
+ return;
129
+ }
130
+ for (const [name, result] of results) if (result.success) console.log(`${name} refreshed`);
131
+ else console.error(`${name} failed: ${result.error}`);
132
+ }
133
+ }),
134
+ link: defineCommand({
135
+ meta: {
136
+ name: "link",
137
+ description: "Symlink a local directory into the plugin cache for dev"
138
+ },
139
+ args: {
140
+ path: {
141
+ type: "positional",
142
+ description: "Local path to the plugin/marketplace directory",
143
+ required: true
144
+ },
145
+ as: {
146
+ type: "string",
147
+ description: "Plugin key (name@marketplace) for the cache entry",
148
+ required: true
149
+ },
150
+ json: {
151
+ type: "boolean",
152
+ description: "Output as JSON",
153
+ default: false
154
+ }
155
+ },
156
+ async run({ args }) {
157
+ if (!args.as) error("--as is required. Specify plugin key as name@marketplace.");
158
+ if (!args.as.includes("@")) error("Plugin key must be in name@marketplace format (e.g. my-plugin@my-marketplace)");
159
+ const result = await link_local_plugin(args.path, args.as);
160
+ if (args.json) output(result, true);
161
+ else if (result.success) {
162
+ console.log(`Linked: ${result.key}`);
163
+ console.log(` ${result.symlinkPath} → ${result.targetPath}`);
164
+ console.log("\nRun /reload-plugins in Claude Code or restart your session.");
165
+ } else error(result.error || "Unknown error");
166
+ }
167
+ }),
168
+ unlink: defineCommand({
169
+ meta: {
170
+ name: "unlink",
171
+ description: "Remove a symlink from the plugin cache"
172
+ },
173
+ args: {
174
+ key: {
175
+ type: "positional",
176
+ description: "Plugin key (name@marketplace)",
177
+ required: true
178
+ },
179
+ json: {
180
+ type: "boolean",
181
+ description: "Output as JSON",
182
+ default: false
183
+ }
184
+ },
185
+ async run({ args }) {
186
+ const result = await unlink_local_plugin(args.key);
187
+ if (args.json) output(result, true);
188
+ else if (result.success) {
189
+ console.log(`Unlinked: ${args.key}`);
190
+ if (result.restored) console.log(" Original cache directory restored from backup.");
191
+ console.log("\nRun /reload-plugins in Claude Code or restart your session.");
192
+ } else error(result.error || "Unknown error");
193
+ }
194
+ }),
195
+ links: defineCommand({
196
+ meta: {
197
+ name: "links",
198
+ description: "List all symlinked plugin cache entries"
199
+ },
200
+ args: { json: {
201
+ type: "boolean",
202
+ description: "Output as JSON",
203
+ default: false
204
+ } },
205
+ async run({ args }) {
206
+ const linked = await list_linked_plugins();
207
+ if (args.json) {
208
+ output(linked, true);
209
+ return;
210
+ }
211
+ if (linked.length === 0) {
212
+ console.log("No linked plugins.");
213
+ return;
214
+ }
215
+ for (const l of linked) {
216
+ console.log(`${l.key}`);
217
+ console.log(` ${l.symlinkPath} → ${l.targetPath}`);
218
+ }
219
+ }
220
+ })
221
+ }
222
+ });
223
+ //#endregion
224
+ export { cache_default as default };
225
+
226
+ //# sourceMappingURL=cache-D6kd7qE8.js.map