mcpick 0.0.22 → 0.0.23

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 (43) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +4 -0
  3. package/dist/add-LJQa2my2.js +164 -0
  4. package/dist/add-json-TEdYweZ5.js +95 -0
  5. package/dist/{backup-bdg6dvsb.js → backup-kyS5IVIr.js} +5 -5
  6. package/dist/{cache-CSUcGdZP.js → cache-DTfzTsEE.js} +3 -3
  7. package/dist/{cli-avr5R1LO.js → cli-By-0nYNQ.js} +22 -21
  8. package/dist/{clients-CSQgqHzb.js → clients-qMozizys.js} +3 -3
  9. package/dist/{clone-CQ0skkT6.js → clone-BVhYjRGO.js} +5 -5
  10. package/dist/{config-BhX4eAgg.js → config-DzMmTJYL.js} +4 -4
  11. package/dist/{dev-CTDg5g-c.js → dev-Cst8WkQ-.js} +6 -6
  12. package/dist/disable-BaOs9lrm.js +83 -0
  13. package/dist/enable--3mjSmTq.js +84 -0
  14. package/dist/{get-l-eAJhBy.js → get-CjhNWyRj.js} +2 -2
  15. package/dist/{hooks-BWZ_Kgx3.js → hooks-DFmxgD0t.js} +3 -4
  16. package/dist/index.js +533 -68
  17. package/dist/{list-By--kltj.js → list-D5CkCXpP.js} +5 -5
  18. package/dist/{marketplace-DdiKDDKK.js → marketplace-C3EGyIG0.js} +3 -3
  19. package/dist/{output-BgN9Uuxf.js → output-HtT5HCof.js} +2 -2
  20. package/dist/{paths-6wrIM8yh.js → paths-BPISiJi4.js} +1 -1
  21. package/dist/{plugin-cache-DKcW8LGV.js → plugin-cache-BSgB42wa.js} +35 -16
  22. package/dist/{plugins-CsXE8AH4.js → plugins-Dn2mPFKm.js} +4 -5
  23. package/dist/{profile-DzGPsdsl.js → profile-Dq3ORPil.js} +4 -5
  24. package/dist/{redact-Dltz2gde.js → redact-wBMtzbno.js} +1 -1
  25. package/dist/{reload-C29-vuvy.js → reload-257iU7Z7.js} +2 -2
  26. package/dist/remove-26XFzkPd.js +87 -0
  27. package/dist/{reset-project-choices-Dhh4CxIC.js → reset-project-choices-D2F04LfC.js} +2 -2
  28. package/dist/{restore-BI8aiszM.js → restore-BYYsoNqF.js} +5 -6
  29. package/dist/rollback-CPdaME91.js +55 -0
  30. package/dist/{skills-DPBDmION.js → skills-DfWk9mpk.js} +2 -2
  31. package/dist/{validation-qWlF51fw.js → validation-xMlbgGCF.js} +1 -1
  32. package/package.json +4 -4
  33. package/.github/copilot-instructions.md +0 -50
  34. package/.github/workflows/ci.yml +0 -26
  35. package/.vscode/settings.json +0 -5
  36. package/CONTEXT.md +0 -49
  37. package/dist/add-Bok0qbXi.js +0 -112
  38. package/dist/add-json-C44vy2A_.js +0 -58
  39. package/dist/atomic-write-4lANmzsO.js +0 -26
  40. package/dist/disable-DLlOj7sc.js +0 -38
  41. package/dist/enable-CGFYYC2A.js +0 -39
  42. package/dist/remove-B5q4rQRU.js +0 -30
  43. package/dist/settings-CZR8bVfh.js +0 -201
@@ -1,112 +0,0 @@
1
- import { n as validate_mcp_server } from "./validation-qWlF51fw.js";
2
- import { d as add_mcp_via_cli, w as add_server_to_registry } from "./index.js";
3
- import { n as output, t as error } from "./output-BgN9Uuxf.js";
4
- import { defineCommand } from "citty";
5
- //#region src/cli/commands/add.ts
6
- var add_default = defineCommand({
7
- meta: {
8
- name: "add",
9
- description: "Add a new MCP server to the registry and enable it"
10
- },
11
- args: {
12
- name: {
13
- type: "string",
14
- description: "Server name",
15
- required: true
16
- },
17
- command: {
18
- type: "string",
19
- description: "Command to run (for stdio transport)"
20
- },
21
- args: {
22
- type: "string",
23
- description: "Comma-separated arguments (e.g. \"npx,-y,mcp-sqlite\")"
24
- },
25
- url: {
26
- type: "string",
27
- description: "URL (for sse or http transport)"
28
- },
29
- type: {
30
- type: "string",
31
- description: "Transport type: stdio, sse, or http (default: stdio)",
32
- default: "stdio"
33
- },
34
- env: {
35
- type: "string",
36
- description: "Environment variables as KEY=val,KEY=val"
37
- },
38
- headers: {
39
- type: "string",
40
- description: "HTTP headers as KEY=val,KEY=val"
41
- },
42
- description: {
43
- type: "string",
44
- description: "Server description"
45
- },
46
- scope: {
47
- type: "string",
48
- description: "Scope: local, project, or user (default: local)",
49
- default: "local"
50
- },
51
- json: {
52
- type: "boolean",
53
- description: "Output as JSON",
54
- default: false
55
- }
56
- },
57
- async run({ args }) {
58
- const scope = args.scope;
59
- if (![
60
- "local",
61
- "project",
62
- "user"
63
- ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
64
- const transport = args.type;
65
- if (![
66
- "stdio",
67
- "sse",
68
- "http"
69
- ].includes(transport)) error(`Invalid type: ${transport}. Use stdio, sse, or http.`);
70
- const server_data = { name: args.name };
71
- if (transport === "stdio") {
72
- if (!args.command) error("--command is required for stdio transport");
73
- server_data.command = args.command;
74
- if (args.args) server_data.args = args.args.split(",");
75
- } else {
76
- if (!args.url) error(`--url is required for ${transport} transport`);
77
- server_data.type = transport;
78
- server_data.url = args.url;
79
- if (args.headers) server_data.headers = parse_key_value_pairs(args.headers);
80
- }
81
- if (args.env) server_data.env = parse_key_value_pairs(args.env);
82
- if (args.description) server_data.description = args.description;
83
- let server;
84
- try {
85
- server = validate_mcp_server(server_data);
86
- } catch (err) {
87
- error(`Invalid server config: ${err instanceof Error ? err.message : "validation failed"}`);
88
- }
89
- await add_server_to_registry(server);
90
- const result = await add_mcp_via_cli(server, scope);
91
- if (args.json) output({
92
- added: server.name,
93
- scope,
94
- cli: result.success,
95
- error: result.error
96
- }, true);
97
- else if (result.success) console.log(`Added '${server.name}' and enabled (scope: ${scope})`);
98
- else console.log(`Added '${server.name}' to registry but CLI failed: ${result.error}`);
99
- }
100
- });
101
- function parse_key_value_pairs(input) {
102
- const result = {};
103
- for (const pair of input.split(",")) {
104
- const eq = pair.indexOf("=");
105
- if (eq > 0) result[pair.substring(0, eq)] = pair.substring(eq + 1);
106
- }
107
- return result;
108
- }
109
- //#endregion
110
- export { add_default as default };
111
-
112
- //# sourceMappingURL=add-Bok0qbXi.js.map
@@ -1,58 +0,0 @@
1
- import { _ as mcp_add_json_via_cli } from "./index.js";
2
- import { n as output, t as error } from "./output-BgN9Uuxf.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-C44vy2A_.js.map
@@ -1,26 +0,0 @@
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-4lANmzsO.js.map
@@ -1,38 +0,0 @@
1
- import { T as get_all_available_servers, b as remove_mcp_via_cli } from "./index.js";
2
- import { t as error } from "./output-BgN9Uuxf.js";
3
- import { defineCommand } from "citty";
4
- //#region src/cli/commands/disable.ts
5
- var disable_default = defineCommand({
6
- meta: {
7
- name: "disable",
8
- description: "Disable an MCP server"
9
- },
10
- args: {
11
- server: {
12
- type: "positional",
13
- description: "Server name to disable",
14
- required: true
15
- },
16
- scope: {
17
- type: "string",
18
- description: "Scope: local, project, or user (default: local)",
19
- default: "local"
20
- }
21
- },
22
- async run({ args }) {
23
- const scope = args.scope;
24
- if (![
25
- "local",
26
- "project",
27
- "user"
28
- ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
29
- await get_all_available_servers();
30
- const result = await remove_mcp_via_cli(args.server);
31
- if (!result.success) error(result.error || "Failed to disable server");
32
- console.log(`Disabled '${args.server}' (scope: ${scope})`);
33
- }
34
- });
35
- //#endregion
36
- export { disable_default as default };
37
-
38
- //# sourceMappingURL=disable-DLlOj7sc.js.map
@@ -1,39 +0,0 @@
1
- import { T as get_all_available_servers, d as add_mcp_via_cli } from "./index.js";
2
- import { t as error } from "./output-BgN9Uuxf.js";
3
- import { defineCommand } from "citty";
4
- //#region src/cli/commands/enable.ts
5
- var enable_default = defineCommand({
6
- meta: {
7
- name: "enable",
8
- description: "Enable an MCP server"
9
- },
10
- args: {
11
- server: {
12
- type: "positional",
13
- description: "Server name to enable",
14
- required: true
15
- },
16
- scope: {
17
- type: "string",
18
- description: "Scope: local, project, or user (default: local)",
19
- default: "local"
20
- }
21
- },
22
- async run({ args }) {
23
- const scope = args.scope;
24
- if (![
25
- "local",
26
- "project",
27
- "user"
28
- ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
29
- const server = (await get_all_available_servers()).find((s) => s.name === args.server);
30
- if (!server) error(`Server '${args.server}' not found in registry. Run 'mcpick list' to see available servers.`);
31
- const result = await add_mcp_via_cli(server, scope);
32
- if (!result.success) error(result.error || "Failed to enable server");
33
- console.log(`Enabled '${server.name}' (scope: ${scope})`);
34
- }
35
- });
36
- //#endregion
37
- export { enable_default as default };
38
-
39
- //# sourceMappingURL=enable-CGFYYC2A.js.map
@@ -1,30 +0,0 @@
1
- import { O as read_server_registry, T as get_all_available_servers, b as remove_mcp_via_cli, k as write_server_registry } from "./index.js";
2
- import { t as error } from "./output-BgN9Uuxf.js";
3
- import { defineCommand } from "citty";
4
- //#region src/cli/commands/remove.ts
5
- var remove_default = defineCommand({
6
- meta: {
7
- name: "remove",
8
- description: "Remove an MCP server from the registry and disable it"
9
- },
10
- args: { server: {
11
- type: "positional",
12
- description: "Server name to remove",
13
- required: true
14
- } },
15
- async run({ args }) {
16
- if (!(await get_all_available_servers()).find((s) => s.name === args.server)) error(`Server '${args.server}' not found. Run 'mcpick list' to see available servers.`);
17
- const registry = await read_server_registry();
18
- const index = registry.servers.findIndex((s) => s.name === args.server);
19
- if (index >= 0) {
20
- registry.servers.splice(index, 1);
21
- await write_server_registry(registry);
22
- }
23
- await remove_mcp_via_cli(args.server);
24
- console.log(`Removed '${args.server}'`);
25
- }
26
- });
27
- //#endregion
28
- export { remove_default as default };
29
-
30
- //# sourceMappingURL=remove-B5q4rQRU.js.map
@@ -1,201 +0,0 @@
1
- import { t as atomic_json_write } from "./atomic-write-4lANmzsO.js";
2
- import { a as get_claude_settings_path } from "./paths-6wrIM8yh.js";
3
- import { access, readFile } from "node:fs/promises";
4
- import { join, resolve } from "node:path";
5
- //#region src/core/settings.ts
6
- async function read_claude_settings() {
7
- const settings_path = get_claude_settings_path();
8
- try {
9
- await access(settings_path);
10
- const content = await readFile(settings_path, "utf-8");
11
- return JSON.parse(content);
12
- } catch (error) {
13
- if (error instanceof Error && "code" in error && error.code === "ENOENT") return {};
14
- throw error;
15
- }
16
- }
17
- async function write_claude_settings(updates) {
18
- await atomic_json_write(get_claude_settings_path(), (existing) => {
19
- for (const [key, value] of Object.entries(updates)) existing[key] = value;
20
- return existing;
21
- });
22
- }
23
- /**
24
- * Parse enabledPlugins into structured list.
25
- * Keys are in format "plugin-name@marketplace-name"
26
- */
27
- function get_all_plugins(settings) {
28
- const enabled_plugins = settings.enabledPlugins || {};
29
- return Object.entries(enabled_plugins).map(([key, enabled]) => {
30
- const at_index = key.lastIndexOf("@");
31
- return {
32
- name: at_index > 0 ? key.substring(0, at_index) : key,
33
- marketplace: at_index > 0 ? key.substring(at_index + 1) : "unknown",
34
- enabled
35
- };
36
- });
37
- }
38
- /**
39
- * Build the enabledPlugins record from a list of PluginInfo
40
- */
41
- function build_enabled_plugins(plugins) {
42
- const result = {};
43
- for (const plugin of plugins) {
44
- const key = `${plugin.name}@${plugin.marketplace}`;
45
- result[key] = plugin.enabled;
46
- }
47
- return result;
48
- }
49
- async function read_settings_file(path) {
50
- try {
51
- await access(path);
52
- const content = await readFile(path, "utf-8");
53
- return JSON.parse(content);
54
- } catch {
55
- return {};
56
- }
57
- }
58
- function get_settings_paths() {
59
- return [
60
- {
61
- scope: "user",
62
- path: resolve(process.env.HOME || process.env.USERPROFILE || "", ".claude", "settings.json")
63
- },
64
- {
65
- scope: "project",
66
- path: resolve(process.cwd(), ".claude", "settings.json")
67
- },
68
- {
69
- scope: "project-local",
70
- path: resolve(process.cwd(), ".claude", "settings.local.json")
71
- }
72
- ];
73
- }
74
- /**
75
- * Read all hooks across all scopes (settings + plugins), flattened for display.
76
- */
77
- async function get_all_hooks() {
78
- const entries = [];
79
- for (const { scope, path } of get_settings_paths()) {
80
- const hooks = (await read_settings_file(path)).hooks;
81
- if (!hooks) continue;
82
- for (const [event, matchers] of Object.entries(hooks)) {
83
- if (!Array.isArray(matchers)) continue;
84
- for (let mi = 0; mi < matchers.length; mi++) {
85
- const m = matchers[mi];
86
- if (!m.hooks?.length) continue;
87
- for (let hi = 0; hi < m.hooks.length; hi++) entries.push({
88
- event,
89
- matcher: m.matcher,
90
- handler: m.hooks[hi],
91
- scope,
92
- source: scope,
93
- matcher_index: mi,
94
- hook_index: hi
95
- });
96
- }
97
- }
98
- }
99
- const plugin_hooks = await get_all_plugin_hooks();
100
- entries.push(...plugin_hooks);
101
- return entries;
102
- }
103
- /**
104
- * Scan all installed plugins for hooks.json and return flattened hook entries.
105
- * Checks both cache and marketplace source paths since Claude Code reads from both.
106
- */
107
- async function get_all_plugin_hooks() {
108
- const { read_installed_plugins } = await import("./plugin-cache-DKcW8LGV.js").then((n) => n.s);
109
- const { get_marketplaces_dir } = await import("./paths-6wrIM8yh.js").then((n) => n.b);
110
- const installed = await read_installed_plugins();
111
- const entries = [];
112
- const seen_hooks = /* @__PURE__ */ new Set();
113
- for (const [plugin_key, installs] of Object.entries(installed.plugins)) {
114
- if (!installs?.length) continue;
115
- const install = installs[0];
116
- const at_index = plugin_key.lastIndexOf("@");
117
- const plugin_name = at_index > 0 ? plugin_key.substring(0, at_index) : plugin_key;
118
- const marketplace_name = at_index > 0 ? plugin_key.substring(at_index + 1) : "";
119
- const hooks_paths = [join(install.installPath, "hooks", "hooks.json")];
120
- if (marketplace_name) hooks_paths.push(join(get_marketplaces_dir(), marketplace_name, "plugins", plugin_name, "hooks", "hooks.json"));
121
- for (const hooks_path of hooks_paths) {
122
- let hooks_data;
123
- try {
124
- const content = await readFile(hooks_path, "utf-8");
125
- hooks_data = JSON.parse(content);
126
- } catch {
127
- continue;
128
- }
129
- const hooks = hooks_data.hooks || hooks_data;
130
- for (const [event, matchers] of Object.entries(hooks)) {
131
- if (!Array.isArray(matchers)) continue;
132
- for (let mi = 0; mi < matchers.length; mi++) {
133
- const m = matchers[mi];
134
- if (!m.hooks?.length) continue;
135
- for (let hi = 0; hi < m.hooks.length; hi++) {
136
- const h = m.hooks[hi];
137
- const dedup_key = `${plugin_key}:${event}:${h.type}:${h.command || h.url || h.prompt}`;
138
- if (seen_hooks.has(dedup_key)) continue;
139
- seen_hooks.add(dedup_key);
140
- entries.push({
141
- event,
142
- matcher: m.matcher,
143
- handler: h,
144
- scope: "user",
145
- source: "plugin",
146
- matcher_index: mi,
147
- hook_index: hi,
148
- plugin_key,
149
- hooks_json_path: hooks_path
150
- });
151
- }
152
- }
153
- }
154
- }
155
- }
156
- return entries;
157
- }
158
- /**
159
- * Remove a specific hook entry by scope/event/indices.
160
- */
161
- async function remove_hook(entry) {
162
- const scope_path = get_settings_paths().find((s) => s.scope === entry.scope);
163
- if (!scope_path) throw new Error(`Unknown scope: ${entry.scope}`);
164
- await atomic_json_write(scope_path.path, (existing) => {
165
- const hooks = existing.hooks;
166
- if (!hooks) return existing;
167
- const matchers = hooks[entry.event];
168
- if (!matchers?.[entry.matcher_index]) return existing;
169
- const matcher = matchers[entry.matcher_index];
170
- matcher.hooks.splice(entry.hook_index, 1);
171
- if (matcher.hooks.length === 0) matchers.splice(entry.matcher_index, 1);
172
- if (matchers.length === 0) delete hooks[entry.event];
173
- if (Object.keys(hooks).length === 0) delete existing.hooks;
174
- return existing;
175
- });
176
- }
177
- /**
178
- * Add a hook to a specific scope.
179
- */
180
- async function add_hook(scope, event, matcher, handler) {
181
- const scope_path = get_settings_paths().find((s) => s.scope === scope);
182
- if (!scope_path) throw new Error(`Unknown scope: ${scope}`);
183
- await atomic_json_write(scope_path.path, (existing) => {
184
- if (!existing.hooks) existing.hooks = {};
185
- const hooks = existing.hooks;
186
- if (!hooks[event]) hooks[event] = [];
187
- const matchers = hooks[event];
188
- const existing_matcher = matchers.find((m) => (m.matcher || void 0) === matcher);
189
- if (existing_matcher) existing_matcher.hooks.push(handler);
190
- else {
191
- const new_matcher = { hooks: [handler] };
192
- if (matcher) new_matcher.matcher = matcher;
193
- matchers.push(new_matcher);
194
- }
195
- return existing;
196
- });
197
- }
198
- //#endregion
199
- export { read_claude_settings as a, get_all_plugins as i, build_enabled_plugins as n, remove_hook as o, get_all_hooks as r, write_claude_settings as s, add_hook as t };
200
-
201
- //# sourceMappingURL=settings-CZR8bVfh.js.map