mcpman 1.0.0 → 2.1.0

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.
@@ -10,8 +10,9 @@ import {
10
10
  removeEntry,
11
11
  resolveLockfilePath,
12
12
  writeLockfile
13
- } from "./chunk-6GGMDJQE.js";
14
- import "./chunk-DSCBWQ3W.js";
13
+ } from "./chunk-CYYW35D2.js";
14
+ import "./chunk-HQO4AO6B.js";
15
+ import "./chunk-K3NQKI34.js";
15
16
  export {
16
17
  LOCKFILE_NAME,
17
18
  addEntry,
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  computeTrustScore
4
4
  } from "./chunk-RGKHLY5G.js";
5
+ import "./chunk-K3NQKI34.js";
5
6
  export {
6
7
  computeTrustScore
7
8
  };
@@ -13,6 +13,7 @@ import {
13
13
  setSecret,
14
14
  writeVault
15
15
  } from "./chunk-6X6Q6UZC.js";
16
+ import "./chunk-K3NQKI34.js";
16
17
  export {
17
18
  clearPasswordCache,
18
19
  decrypt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcpman",
3
- "version": "1.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "The package manager for MCP servers",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,7 +9,9 @@
9
9
  "main": "./dist/index.cjs",
10
10
  "module": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",
12
- "files": ["dist"],
12
+ "files": [
13
+ "dist"
14
+ ],
13
15
  "scripts": {
14
16
  "build": "tsup",
15
17
  "dev": "tsup --watch",
@@ -23,17 +25,26 @@
23
25
  "engines": {
24
26
  "node": ">=20.0.0"
25
27
  },
26
- "keywords": ["mcp", "model-context-protocol", "cli", "server-manager"],
28
+ "keywords": [
29
+ "mcp",
30
+ "model-context-protocol",
31
+ "cli",
32
+ "server-manager"
33
+ ],
27
34
  "license": "MIT",
28
35
  "dependencies": {
29
36
  "@clack/prompts": "^0.9.1",
37
+ "@iarna/toml": "^2.2.5",
38
+ "@modelcontextprotocol/sdk": "^1.27.1",
30
39
  "citty": "^0.1.6",
31
40
  "nanospinner": "^1.2.2",
32
- "picocolors": "^1.1.1"
41
+ "picocolors": "^1.1.1",
42
+ "yaml": "^2.8.2"
33
43
  },
34
44
  "devDependencies": {
35
45
  "@biomejs/biome": "^1.9.4",
36
46
  "@types/node": "^22.10.0",
47
+ "@vitest/coverage-v8": "^4.0.18",
37
48
  "tsup": "^8.3.5",
38
49
  "typescript": "^5.7.2",
39
50
  "vitest": "^4.0.18"
@@ -1,181 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- resolveConfigPath
4
- } from "./chunk-DSCBWQ3W.js";
5
-
6
- // src/clients/base-client-handler.ts
7
- import fs from "fs";
8
- import path from "path";
9
-
10
- // src/clients/types.ts
11
- var ConfigParseError = class extends Error {
12
- constructor(configPath, cause) {
13
- super(`Failed to parse config: ${configPath} \u2014 ${String(cause)}`);
14
- this.configPath = configPath;
15
- this.name = "ConfigParseError";
16
- }
17
- };
18
- var ConfigWriteError = class extends Error {
19
- constructor(configPath, cause) {
20
- super(`Failed to write config: ${configPath} \u2014 ${String(cause)}`);
21
- this.configPath = configPath;
22
- this.name = "ConfigWriteError";
23
- }
24
- };
25
-
26
- // src/clients/base-client-handler.ts
27
- async function atomicWrite(filePath, content) {
28
- const tmpPath = `${filePath}.tmp`;
29
- try {
30
- await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
31
- await fs.promises.writeFile(tmpPath, content, { encoding: "utf-8", mode: 384 });
32
- await fs.promises.rename(tmpPath, filePath);
33
- } catch (err) {
34
- try {
35
- await fs.promises.unlink(tmpPath);
36
- } catch {
37
- }
38
- throw err;
39
- }
40
- }
41
- async function pathExists(p) {
42
- try {
43
- await fs.promises.access(p);
44
- return true;
45
- } catch {
46
- return false;
47
- }
48
- }
49
- var BaseClientHandler = class {
50
- async isInstalled() {
51
- const dir = path.dirname(this.getConfigPath());
52
- return pathExists(dir);
53
- }
54
- /** Read raw JSON from disk, return empty object if file missing */
55
- async readRaw() {
56
- const configPath = this.getConfigPath();
57
- try {
58
- const raw = await fs.promises.readFile(configPath, "utf-8");
59
- return JSON.parse(raw);
60
- } catch (err) {
61
- if (err.code === "ENOENT") {
62
- return {};
63
- }
64
- throw new ConfigParseError(configPath, err);
65
- }
66
- }
67
- /** Serialize raw object to disk atomically */
68
- async writeRaw(data) {
69
- const configPath = this.getConfigPath();
70
- try {
71
- await atomicWrite(configPath, JSON.stringify(data, null, 2));
72
- } catch (err) {
73
- throw new ConfigWriteError(configPath, err);
74
- }
75
- }
76
- /** Convert raw JSON to ClientConfig — override for non-standard formats */
77
- toClientConfig(raw) {
78
- const mcpServers = raw.mcpServers ?? {};
79
- return { servers: mcpServers };
80
- }
81
- /** Merge ClientConfig back into raw JSON — override for non-standard formats */
82
- fromClientConfig(raw, config) {
83
- return { ...raw, mcpServers: config.servers };
84
- }
85
- async readConfig() {
86
- const raw = await this.readRaw();
87
- return this.toClientConfig(raw);
88
- }
89
- async writeConfig(config) {
90
- const raw = await this.readRaw();
91
- await this.writeRaw(this.fromClientConfig(raw, config));
92
- }
93
- async addServer(name, entry) {
94
- const config = await this.readConfig();
95
- config.servers[name] = entry;
96
- await this.writeConfig(config);
97
- }
98
- async removeServer(name) {
99
- const config = await this.readConfig();
100
- delete config.servers[name];
101
- await this.writeConfig(config);
102
- }
103
- };
104
-
105
- // src/clients/claude-desktop.ts
106
- var ClaudeDesktopHandler = class extends BaseClientHandler {
107
- type = "claude-desktop";
108
- displayName = "Claude Desktop";
109
- getConfigPath() {
110
- return resolveConfigPath("claude-desktop");
111
- }
112
- };
113
-
114
- // src/clients/cursor.ts
115
- var CursorHandler = class extends BaseClientHandler {
116
- type = "cursor";
117
- displayName = "Cursor";
118
- getConfigPath() {
119
- return resolveConfigPath("cursor");
120
- }
121
- };
122
-
123
- // src/clients/vscode.ts
124
- var VSCodeHandler = class extends BaseClientHandler {
125
- type = "vscode";
126
- displayName = "VS Code";
127
- getConfigPath() {
128
- return resolveConfigPath("vscode");
129
- }
130
- toClientConfig(raw) {
131
- const mcp = raw.mcp ?? {};
132
- const servers = mcp.servers ?? {};
133
- return { servers };
134
- }
135
- fromClientConfig(raw, config) {
136
- const existingMcp = raw.mcp ?? {};
137
- return {
138
- ...raw,
139
- mcp: { ...existingMcp, servers: config.servers }
140
- };
141
- }
142
- };
143
-
144
- // src/clients/windsurf.ts
145
- var WindsurfHandler = class extends BaseClientHandler {
146
- type = "windsurf";
147
- displayName = "Windsurf";
148
- getConfigPath() {
149
- return resolveConfigPath("windsurf");
150
- }
151
- };
152
-
153
- // src/clients/client-detector.ts
154
- function getAllClientTypes() {
155
- return ["claude-desktop", "cursor", "vscode", "windsurf"];
156
- }
157
- function getClient(type) {
158
- switch (type) {
159
- case "claude-desktop":
160
- return new ClaudeDesktopHandler();
161
- case "cursor":
162
- return new CursorHandler();
163
- case "vscode":
164
- return new VSCodeHandler();
165
- case "windsurf":
166
- return new WindsurfHandler();
167
- }
168
- }
169
- async function getInstalledClients() {
170
- const all = getAllClientTypes().map(getClient);
171
- const results = await Promise.all(
172
- all.map(async (handler) => ({ handler, installed: await handler.isInstalled() }))
173
- );
174
- return results.filter((r) => r.installed).map((r) => r.handler);
175
- }
176
-
177
- export {
178
- getAllClientTypes,
179
- getClient,
180
- getInstalledClients
181
- };