terminator-mcp-agent 0.5.12 → 0.5.13
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/config.js +280 -0
- package/package.json +7 -6
package/config.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { execFileSync } = require("child_process");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {Object} ClientConfig
|
|
8
|
+
* @property {Object.<string, any>} mcpServers
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} ClientFileTarget
|
|
13
|
+
* @property {"file"} type
|
|
14
|
+
* @property {string} path
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Object} ClientCommandTarget
|
|
19
|
+
* @property {"command"} type
|
|
20
|
+
* @property {string} command
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// Initialize platform-specific paths
|
|
24
|
+
const homeDir = os.homedir();
|
|
25
|
+
|
|
26
|
+
const platformPaths = {
|
|
27
|
+
win32: {
|
|
28
|
+
baseDir: process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"),
|
|
29
|
+
vscodePath: path.join("Code", "User", "globalStorage"),
|
|
30
|
+
},
|
|
31
|
+
darwin: {
|
|
32
|
+
baseDir: path.join(homeDir, "Library", "Application Support"),
|
|
33
|
+
vscodePath: path.join("Code", "User", "globalStorage"),
|
|
34
|
+
},
|
|
35
|
+
linux: {
|
|
36
|
+
baseDir: process.env.XDG_CONFIG_HOME || path.join(homeDir, ".config"),
|
|
37
|
+
vscodePath: path.join("Code/User/globalStorage"),
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const platform = process.platform;
|
|
42
|
+
const { baseDir, vscodePath } = platformPaths[platform] || platformPaths.linux;
|
|
43
|
+
const defaultClaudePath = path.join(
|
|
44
|
+
baseDir,
|
|
45
|
+
"Claude",
|
|
46
|
+
"claude_desktop_config.json",
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Define client paths using the platform-specific base directories
|
|
50
|
+
const clientPaths = {
|
|
51
|
+
claude: { type: "file", path: defaultClaudePath },
|
|
52
|
+
cline: {
|
|
53
|
+
type: "file",
|
|
54
|
+
path: path.join(
|
|
55
|
+
baseDir,
|
|
56
|
+
vscodePath,
|
|
57
|
+
"saoudrizwan.claude-dev",
|
|
58
|
+
"settings",
|
|
59
|
+
"cline_mcp_settings.json",
|
|
60
|
+
),
|
|
61
|
+
},
|
|
62
|
+
roocode: {
|
|
63
|
+
type: "file",
|
|
64
|
+
path: path.join(
|
|
65
|
+
baseDir,
|
|
66
|
+
vscodePath,
|
|
67
|
+
"rooveterinaryinc.roo-cline",
|
|
68
|
+
"settings",
|
|
69
|
+
"mcp_settings.json",
|
|
70
|
+
),
|
|
71
|
+
},
|
|
72
|
+
windsurf: {
|
|
73
|
+
type: "file",
|
|
74
|
+
path: path.join(homeDir, ".codeium", "windsurf", "mcp_config.json"),
|
|
75
|
+
},
|
|
76
|
+
witsy: { type: "file", path: path.join(baseDir, "Witsy", "settings.json") },
|
|
77
|
+
enconvo: {
|
|
78
|
+
type: "file",
|
|
79
|
+
path: path.join(homeDir, ".config", "enconvo", "mcp_config.json"),
|
|
80
|
+
},
|
|
81
|
+
cursor: { type: "file", path: path.join(homeDir, ".cursor", "mcp.json") },
|
|
82
|
+
vscode: {
|
|
83
|
+
type: "command",
|
|
84
|
+
command: process.platform === "win32" ? "code.cmd" : "code",
|
|
85
|
+
},
|
|
86
|
+
"vscode-insiders": {
|
|
87
|
+
type: "command",
|
|
88
|
+
command:
|
|
89
|
+
process.platform === "win32" ? "code-insiders.cmd" : "code-insiders",
|
|
90
|
+
},
|
|
91
|
+
boltai: { type: "file", path: path.join(homeDir, ".boltai", "mcp.json") },
|
|
92
|
+
"amazon-bedrock": {
|
|
93
|
+
type: "file",
|
|
94
|
+
path: path.join(homeDir, "Amazon Bedrock Client", "mcp_config.json"),
|
|
95
|
+
},
|
|
96
|
+
amazonq: {
|
|
97
|
+
type: "file",
|
|
98
|
+
path: path.join(homeDir, ".aws", "amazonq", "mcp.json"),
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {string} [client]
|
|
104
|
+
* @returns {ClientFileTarget|ClientCommandTarget}
|
|
105
|
+
*/
|
|
106
|
+
function getConfigPath(client) {
|
|
107
|
+
const normalizedClient = client ? client.toLowerCase() : "claude";
|
|
108
|
+
verbose(`Getting config path for client: ${normalizedClient}`);
|
|
109
|
+
|
|
110
|
+
const configTarget = clientPaths[normalizedClient] || {
|
|
111
|
+
type: "file",
|
|
112
|
+
path: path.join(
|
|
113
|
+
path.dirname(defaultClaudePath),
|
|
114
|
+
"..",
|
|
115
|
+
client || "claude",
|
|
116
|
+
`${normalizedClient}_config.json`,
|
|
117
|
+
),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
verbose(`Config path resolved to: ${JSON.stringify(configTarget)}`);
|
|
121
|
+
return configTarget;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param {string} client
|
|
126
|
+
* @returns {ClientConfig}
|
|
127
|
+
*/
|
|
128
|
+
function readConfig(client) {
|
|
129
|
+
verbose(`Reading config for client: ${client}`);
|
|
130
|
+
try {
|
|
131
|
+
const configPath = getConfigPath(client);
|
|
132
|
+
|
|
133
|
+
// Command-based installers (i.e. VS Code) do not currently support listing servers
|
|
134
|
+
if (configPath.type === "command") {
|
|
135
|
+
return { mcpServers: {} };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
verbose(`Checking if config file exists at: ${configPath.path}`);
|
|
139
|
+
if (!fs.existsSync(configPath.path)) {
|
|
140
|
+
verbose(`Config file not found, returning default empty config`);
|
|
141
|
+
return { mcpServers: {} };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
verbose(`Reading config file content`);
|
|
145
|
+
const rawConfig = JSON.parse(fs.readFileSync(configPath.path, "utf8"));
|
|
146
|
+
verbose(
|
|
147
|
+
`Config loaded successfully: ${JSON.stringify(rawConfig, null, 2)}`,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
...rawConfig,
|
|
152
|
+
mcpServers: rawConfig.mcpServers || {},
|
|
153
|
+
};
|
|
154
|
+
} catch (error) {
|
|
155
|
+
verbose(
|
|
156
|
+
`Error reading config: ${error instanceof Error ? error.stack : JSON.stringify(error)}`,
|
|
157
|
+
);
|
|
158
|
+
return { mcpServers: {} };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @param {ClientConfig} config
|
|
164
|
+
* @param {string} [client]
|
|
165
|
+
*/
|
|
166
|
+
function writeConfig(configObj, client) {
|
|
167
|
+
verbose(`Writing config for client: ${client || "default"}`);
|
|
168
|
+
verbose(`Config data: ${JSON.stringify(configObj, null, 2)}`);
|
|
169
|
+
|
|
170
|
+
if (!configObj.mcpServers || typeof configObj.mcpServers !== "object") {
|
|
171
|
+
verbose(`Invalid mcpServers structure in config`);
|
|
172
|
+
throw new Error("Invalid mcpServers structure");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const configPath = getConfigPath(client);
|
|
176
|
+
if (configPath.type === "command") {
|
|
177
|
+
writeConfigCommand(configObj, configPath);
|
|
178
|
+
} else {
|
|
179
|
+
writeConfigFile(configObj, configPath);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @param {ClientConfig} config
|
|
185
|
+
* @param {ClientCommandTarget} target
|
|
186
|
+
*/
|
|
187
|
+
function writeConfigCommand(config, target) {
|
|
188
|
+
const args = [];
|
|
189
|
+
for (const [name, server] of Object.entries(config.mcpServers)) {
|
|
190
|
+
args.push("--add-mcp", JSON.stringify({ ...server, name }));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
verbose(`Running command: ${JSON.stringify([target.command, ...args])}`);
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
const output = execFileSync(target.command, args);
|
|
197
|
+
verbose(`Executed command successfully: ${output.toString()}`);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
verbose(
|
|
200
|
+
`Error executing command: ${error instanceof Error ? error.message : String(error)}`,
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
if (error && error.code === "ENOENT") {
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Command '${target.command}' not found. Make sure ${target.command} is installed and on your PATH`,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @param {ClientConfig} config
|
|
215
|
+
* @param {ClientFileTarget} target
|
|
216
|
+
*/
|
|
217
|
+
function writeConfigFile(config, target) {
|
|
218
|
+
const configDir = path.dirname(target.path);
|
|
219
|
+
|
|
220
|
+
verbose(`Ensuring config directory exists: ${configDir}`);
|
|
221
|
+
if (!fs.existsSync(configDir)) {
|
|
222
|
+
verbose(`Creating directory: ${configDir}`);
|
|
223
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
let existingConfig = { mcpServers: {} };
|
|
227
|
+
try {
|
|
228
|
+
if (fs.existsSync(target.path)) {
|
|
229
|
+
verbose(`Reading existing config file for merging`);
|
|
230
|
+
existingConfig = JSON.parse(fs.readFileSync(target.path, "utf8"));
|
|
231
|
+
verbose(
|
|
232
|
+
`Existing config loaded: ${JSON.stringify(existingConfig, null, 2)}`,
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
} catch (error) {
|
|
236
|
+
verbose(
|
|
237
|
+
`Error reading existing config for merge: ${error instanceof Error ? error.message : String(error)}`,
|
|
238
|
+
);
|
|
239
|
+
// If reading fails, continue with empty existing config
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
verbose(`Merging configs`);
|
|
243
|
+
const mergedConfig = {
|
|
244
|
+
...existingConfig,
|
|
245
|
+
...config,
|
|
246
|
+
};
|
|
247
|
+
verbose(`Merged config: ${JSON.stringify(mergedConfig, null, 2)}`);
|
|
248
|
+
|
|
249
|
+
verbose(`Writing config to file: ${target.path}`);
|
|
250
|
+
fs.writeFileSync(target.path, JSON.stringify(mergedConfig, null, 2));
|
|
251
|
+
verbose(`Config successfully written`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function verbose(msg) {
|
|
255
|
+
if (process.env.MCP_VERBOSE) {
|
|
256
|
+
console.log(`[config] ${msg}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const supportedClients = [
|
|
261
|
+
{ key: "cursor", label: "Cursor" },
|
|
262
|
+
{ key: "claude", label: "Claude" },
|
|
263
|
+
{ key: "vscode", label: "VS Code" },
|
|
264
|
+
{ key: "insiders", label: "VS Code Insiders" },
|
|
265
|
+
{ key: "windsurf", label: "Windsurf" },
|
|
266
|
+
{ key: "cline", label: "Cline" },
|
|
267
|
+
{ key: "roocode", label: "RooCode" },
|
|
268
|
+
{ key: "witsy", label: "Witsy" },
|
|
269
|
+
{ key: "enconvo", label: "Enconvo" },
|
|
270
|
+
{ key: "boltai", label: "BoltAI" },
|
|
271
|
+
{ key: "amazon-bedrock", label: "Amazon Bedrock" },
|
|
272
|
+
{ key: "amazonq", label: "Amazon Q" },
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
module.exports = {
|
|
276
|
+
getConfigPath,
|
|
277
|
+
readConfig,
|
|
278
|
+
writeConfig,
|
|
279
|
+
supportedClients,
|
|
280
|
+
};
|
package/package.json
CHANGED
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|
"node": ">= 10"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"index.js"
|
|
10
|
+
"index.js",
|
|
11
|
+
"config.js"
|
|
11
12
|
],
|
|
12
13
|
"name": "terminator-mcp-agent",
|
|
13
14
|
"optionalDependencies": {
|
|
14
|
-
"terminator-mcp-darwin-arm64": "0.5.
|
|
15
|
-
"terminator-mcp-darwin-x64": "0.5.
|
|
16
|
-
"terminator-mcp-linux-x64-gnu": "0.5.
|
|
17
|
-
"terminator-mcp-win32-x64-msvc": "0.5.
|
|
15
|
+
"terminator-mcp-darwin-arm64": "0.5.13",
|
|
16
|
+
"terminator-mcp-darwin-x64": "0.5.13",
|
|
17
|
+
"terminator-mcp-linux-x64-gnu": "0.5.13",
|
|
18
|
+
"terminator-mcp-win32-x64-msvc": "0.5.13"
|
|
18
19
|
},
|
|
19
20
|
"repository": {
|
|
20
21
|
"type": "git",
|
|
@@ -26,5 +27,5 @@
|
|
|
26
27
|
"sync-version": "node ./utils/sync-version.js",
|
|
27
28
|
"update-badges": "node ./utils/update-badges.js"
|
|
28
29
|
},
|
|
29
|
-
"version": "0.5.
|
|
30
|
+
"version": "0.5.13"
|
|
30
31
|
}
|