@edilsonfjdev/mcp-setup 0.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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/bin/mcp-setup.js +3 -0
  4. package/dist/add-2HOZTV5H.js +66 -0
  5. package/dist/chunk-H3PELLAE.js +162 -0
  6. package/dist/chunk-JNVJQZTK.js +169 -0
  7. package/dist/chunk-Q36CDQK6.js +28 -0
  8. package/dist/chunk-UZ72QCYF.js +79 -0
  9. package/dist/config-loader-O23HRZIK.js +14 -0
  10. package/dist/doctor-OBFIE3JN.js +161 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.js +42 -0
  13. package/dist/install-DAWHBGCE.js +169 -0
  14. package/dist/list-QO4GBJHR.js +29 -0
  15. package/dist/profiles-HU3NVRTV.js +30 -0
  16. package/dist/remove-T6C2DD7O.js +39 -0
  17. package/dist/update-GOCA4IZG.js +55 -0
  18. package/dist/validate-6RKOV7JG.js +167 -0
  19. package/package.json +74 -0
  20. package/templates/mcps/clickup.json +35 -0
  21. package/templates/mcps/context7.json +19 -0
  22. package/templates/mcps/coolify.json +24 -0
  23. package/templates/mcps/figma.json +19 -0
  24. package/templates/mcps/github.json +22 -0
  25. package/templates/mcps/hetzner.json +23 -0
  26. package/templates/mcps/linear.json +33 -0
  27. package/templates/mcps/n8n-docs.json +20 -0
  28. package/templates/mcps/n8n-instance.json +22 -0
  29. package/templates/mcps/playwright.json +20 -0
  30. package/templates/mcps/postgres.json +20 -0
  31. package/templates/mcps/semgrep.json +19 -0
  32. package/templates/mcps/sentry.json +34 -0
  33. package/templates/mcps/slack.json +34 -0
  34. package/templates/mcps/stitch.json +22 -0
  35. package/templates/profiles/agents.json +7 -0
  36. package/templates/profiles/base.json +7 -0
  37. package/templates/profiles/full.json +7 -0
  38. package/templates/profiles/headless.json +20 -0
  39. package/templates/profiles/minimal.json +7 -0
  40. package/templates/profiles/saas.json +7 -0
  41. package/templates/scopes/scope-map.json +24 -0
@@ -0,0 +1,161 @@
1
+ import {
2
+ getRequiredVars,
3
+ loadEnv,
4
+ validateAllCredentials,
5
+ validatePresence
6
+ } from "./chunk-JNVJQZTK.js";
7
+ import {
8
+ logger
9
+ } from "./chunk-Q36CDQK6.js";
10
+
11
+ // src/utils/preflight.ts
12
+ import { exec as execCb } from "child_process";
13
+ import { promisify } from "util";
14
+ var exec = promisify(execCb);
15
+ async function checkNodeVersion() {
16
+ const version = process.versions.node;
17
+ const major = parseInt(version.split(".")[0]);
18
+ if (major >= 18) {
19
+ return { check: "Node.js", status: "ok", message: `v${version}` };
20
+ }
21
+ return {
22
+ check: "Node.js",
23
+ status: "fail",
24
+ message: `Node.js >= 18 \xE9 necess\xE1rio. Vers\xE3o atual: v${version}`
25
+ };
26
+ }
27
+ async function checkClaudeCli() {
28
+ try {
29
+ const { stdout } = await exec("claude --version");
30
+ return { check: "Claude Code", status: "ok", message: stdout.trim() };
31
+ } catch {
32
+ return {
33
+ check: "Claude Code",
34
+ status: "fail",
35
+ message: "Claude Code n\xE3o encontrado. Instale em: https://claude.ai/code"
36
+ };
37
+ }
38
+ }
39
+ async function runPreflight() {
40
+ return Promise.all([
41
+ checkNodeVersion(),
42
+ checkClaudeCli()
43
+ ]);
44
+ }
45
+
46
+ // src/utils/gitignore-audit.ts
47
+ import { existsSync, readFileSync } from "fs";
48
+ import { resolve } from "path";
49
+ function auditGitignore(projectPath) {
50
+ const basePath = projectPath || process.cwd();
51
+ const gitignorePath = resolve(basePath, ".gitignore");
52
+ const results = [];
53
+ if (!existsSync(gitignorePath)) {
54
+ results.push({
55
+ status: "error",
56
+ message: "Arquivo .gitignore n\xE3o encontrado no projeto",
57
+ suggestion: "Crie um .gitignore: touch .gitignore"
58
+ });
59
+ return results;
60
+ }
61
+ const content = readFileSync(gitignorePath, "utf-8");
62
+ const lines = content.split("\n").map((l) => l.trim());
63
+ if (!lines.includes(".env")) {
64
+ results.push({
65
+ status: "warning",
66
+ message: ".env N\xC3O est\xE1 no .gitignore \u2014 risco de commit de credenciais",
67
+ suggestion: "echo '.env' >> .gitignore"
68
+ });
69
+ } else {
70
+ results.push({
71
+ status: "ok",
72
+ message: ".env est\xE1 protegido no .gitignore"
73
+ });
74
+ }
75
+ if (!lines.some((l) => l === ".env.local" || l === ".env.*" || l === ".env.*.local")) {
76
+ results.push({
77
+ status: "warning",
78
+ message: ".env.local n\xE3o est\xE1 explicitamente no .gitignore",
79
+ suggestion: "echo '.env.local' >> .gitignore"
80
+ });
81
+ }
82
+ if (!lines.some((l) => l === ".claude.json")) {
83
+ results.push({
84
+ status: "warning",
85
+ message: ".claude.json n\xE3o est\xE1 no .gitignore \u2014 pode conter tokens",
86
+ suggestion: "echo '.claude.json' >> .gitignore"
87
+ });
88
+ }
89
+ return results;
90
+ }
91
+
92
+ // src/commands/doctor.ts
93
+ import chalk from "chalk";
94
+ async function doctorCommand() {
95
+ logger.info("Diagn\xF3stico do ambiente MCP Setup\n");
96
+ let hasErrors = false;
97
+ logger.info("Pr\xE9-requisitos:");
98
+ const preflight = await runPreflight();
99
+ for (const check of preflight) {
100
+ if (check.status === "ok") {
101
+ console.log(chalk.green(` \u2713 ${check.check}: ${check.message}`));
102
+ } else {
103
+ console.log(chalk.red(` \u2717 ${check.check}: ${check.message}`));
104
+ hasErrors = true;
105
+ }
106
+ }
107
+ console.log("");
108
+ logger.info("Seguran\xE7a:");
109
+ const gitAudit = auditGitignore();
110
+ for (const result of gitAudit) {
111
+ if (result.status === "ok") {
112
+ console.log(chalk.green(` \u2713 ${result.message}`));
113
+ } else if (result.status === "warning") {
114
+ console.log(chalk.yellow(` ! ${result.message}`));
115
+ if (result.suggestion) console.log(chalk.gray(` \u2192 ${result.suggestion}`));
116
+ } else {
117
+ console.log(chalk.red(` \u2717 ${result.message}`));
118
+ if (result.suggestion) console.log(chalk.gray(` \u2192 ${result.suggestion}`));
119
+ hasErrors = true;
120
+ }
121
+ }
122
+ console.log("");
123
+ logger.info("Configura\xE7\xE3o:");
124
+ const envResult = loadEnv();
125
+ if (envResult.success) {
126
+ console.log(chalk.green(` \u2713 Arquivo .env encontrado: ${envResult.path}`));
127
+ const required = getRequiredVars("base");
128
+ const presence = validatePresence(envResult.vars, required);
129
+ if (presence.valid) {
130
+ console.log(chalk.green(` \u2713 Todas as credenciais do template "base" presentes (${presence.present.length}/${required.length})`));
131
+ } else {
132
+ console.log(chalk.yellow(` ! Credenciais faltando para template "base": ${presence.missing.length}`));
133
+ for (const m of presence.missing) {
134
+ console.log(chalk.yellow(` - ${m.name}: ${m.description}`));
135
+ }
136
+ }
137
+ const validations = validateAllCredentials("base", envResult.vars);
138
+ const formatErrors = validations.filter((v) => !v.valid && presence.present.includes(v.variable));
139
+ if (formatErrors.length > 0) {
140
+ console.log(chalk.yellow(` ! ${formatErrors.length} credencial(is) com formato inv\xE1lido:`));
141
+ for (const f of formatErrors) {
142
+ console.log(chalk.yellow(` - ${f.variable}: ${f.error}`));
143
+ }
144
+ } else if (presence.present.length > 0) {
145
+ console.log(chalk.green(` \u2713 Formato das credenciais v\xE1lido`));
146
+ }
147
+ } else {
148
+ console.log(chalk.yellow(` ! ${envResult.error}`));
149
+ console.log(chalk.gray(" \u2192 cp .env.example .env"));
150
+ }
151
+ console.log("");
152
+ if (hasErrors) {
153
+ logger.error("Problemas encontrados \u2014 corrija os itens acima");
154
+ process.exit(1);
155
+ } else {
156
+ logger.success("Ambiente saud\xE1vel \u2014 pronto para usar mcp-setup");
157
+ }
158
+ }
159
+ export {
160
+ doctorCommand
161
+ };
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ // src/cli.ts
2
+ import { Command } from "commander";
3
+ import { createRequire } from "module";
4
+ var require2 = createRequire(import.meta.url);
5
+ var pkg = require2("../package.json");
6
+ var cli = new Command();
7
+ cli.name("mcp-setup").description("Instala\xE7\xE3o e configura\xE7\xE3o de MCP Servers para Claude Code").version(pkg.version).option("--verbose", "Sa\xEDda detalhada com informa\xE7\xF5es de debug").option("--no-color", "Desativar cores no output").option("--yes", "Pular confirma\xE7\xF5es interativas");
8
+ cli.command("install").description("Instala MCPs de um template pr\xE9-definido").requiredOption("-t, --template <nome>", "Template a instalar (minimal, base, saas, agents, full)").option("-s, --scope <escopo>", "Escopo de instala\xE7\xE3o (user, project, local)", "user").option("--add <mcps...>", "MCPs adicionais para incluir").option("--remove <mcps...>", "MCPs para excluir do template").option("--dry-run", "Simular instala\xE7\xE3o sem executar").option("--skip-oauth", "Ignorar MCPs que exigem OAuth (para ambientes headless/VPS)").action(async (options) => {
9
+ const { installCommand } = await import("./install-DAWHBGCE.js");
10
+ await installCommand(options);
11
+ });
12
+ cli.command("validate").description("Valida credenciais e configura\xE7\xE3o do ambiente").option("--health", "Testar conectividade real com cada MCP").action(async (options) => {
13
+ const { validateCommand } = await import("./validate-6RKOV7JG.js");
14
+ await validateCommand(options);
15
+ });
16
+ cli.command("list").description("Lista MCPs configurados no ambiente").option("-s, --scope <escopo>", "Filtrar por escopo (user, project, local)").action(async (options) => {
17
+ const { listCommand } = await import("./list-QO4GBJHR.js");
18
+ await listCommand(options);
19
+ });
20
+ cli.command("add <mcp>").description("Adiciona um MCP individual").option("-s, --scope <escopo>", "Escopo de instala\xE7\xE3o (user, project, local)", "user").option("--dry-run", "Simular sem executar").action(async (mcp, options) => {
21
+ const { addCommand } = await import("./add-2HOZTV5H.js");
22
+ await addCommand(mcp, options);
23
+ });
24
+ cli.command("remove <mcp>").description("Remove um MCP configurado").option("-s, --scope <escopo>", "Escopo de remo\xE7\xE3o").option("--yes", "Pular confirma\xE7\xE3o").action(async (mcp, options) => {
25
+ const { removeCommand } = await import("./remove-T6C2DD7O.js");
26
+ await removeCommand(mcp, options);
27
+ });
28
+ cli.command("update [mcp]").description("Atualiza MCPs para a configura\xE7\xE3o mais recente").option("--all", "Atualizar todos os MCPs instalados").option("--dry-run", "Simular sem executar").action(async (mcp, options) => {
29
+ const { updateCommand } = await import("./update-GOCA4IZG.js");
30
+ await updateCommand(mcp, options);
31
+ });
32
+ cli.command("doctor").description("Diagn\xF3stico completo do ambiente MCP").action(async () => {
33
+ const { doctorCommand } = await import("./doctor-OBFIE3JN.js");
34
+ await doctorCommand();
35
+ });
36
+ cli.command("profiles").description("Lista profiles/templates dispon\xEDveis").option("--verbose", "Mostrar MCPs de cada profile").action(async (options) => {
37
+ const { profilesCommand } = await import("./profiles-HU3NVRTV.js");
38
+ await profilesCommand(options);
39
+ });
40
+
41
+ // src/index.ts
42
+ cli.parse(process.argv);
@@ -0,0 +1,169 @@
1
+ import {
2
+ loadEnv,
3
+ validateAllCredentials
4
+ } from "./chunk-JNVJQZTK.js";
5
+ import {
6
+ applyHeadlessMode,
7
+ executeCommands,
8
+ filterAlreadyInstalled,
9
+ generateCommands,
10
+ getInstalledMcps,
11
+ resolveScopesForProfile
12
+ } from "./chunk-H3PELLAE.js";
13
+ import {
14
+ loadMcp,
15
+ loadProfile
16
+ } from "./chunk-UZ72QCYF.js";
17
+ import {
18
+ logger
19
+ } from "./chunk-Q36CDQK6.js";
20
+
21
+ // src/core/template-composer.ts
22
+ function resolveMcpList(profile, options) {
23
+ let mcpList = [...profile.mcps];
24
+ if (profile.extends) {
25
+ const parent = loadProfile(profile.extends);
26
+ mcpList = [...parent.mcps];
27
+ if (profile.add) {
28
+ for (const mcp of profile.add) {
29
+ if (!mcpList.includes(mcp)) mcpList.push(mcp);
30
+ }
31
+ }
32
+ if (profile.remove) {
33
+ mcpList = mcpList.filter((m) => !profile.remove.includes(m));
34
+ }
35
+ }
36
+ if (options?.add) {
37
+ for (const mcp of options.add) {
38
+ if (!mcpList.includes(mcp)) mcpList.push(mcp);
39
+ }
40
+ }
41
+ if (options?.remove) {
42
+ mcpList = mcpList.filter((m) => !options.remove.includes(m));
43
+ }
44
+ return mcpList;
45
+ }
46
+ function getProfileMcps(profileName, options) {
47
+ const profile = loadProfile(profileName);
48
+ const mcpList = resolveMcpList(profile, options);
49
+ return mcpList.map((name) => loadMcp(name));
50
+ }
51
+
52
+ // src/commands/install.ts
53
+ async function installCommand(options) {
54
+ const { template, scope, add, remove, dryRun, skipOauth } = options;
55
+ logger.info(`Instalando MCPs do template "${template}"...`);
56
+ if (dryRun) logger.warn("Modo dry-run: nenhuma altera\xE7\xE3o ser\xE1 feita");
57
+ if (skipOauth) logger.info("Modo headless: MCPs OAuth ser\xE3o configurados via token/API key");
58
+ let mcps;
59
+ try {
60
+ mcps = getProfileMcps(template, { add, remove });
61
+ } catch (error) {
62
+ logger.error(error.message);
63
+ process.exit(1);
64
+ }
65
+ logger.info(`${mcps.length} MCPs resolvidos para o template "${template}"`);
66
+ let oauthSkipped = [];
67
+ if (skipOauth) {
68
+ const headless = applyHeadlessMode(mcps);
69
+ mcps = headless.resolved;
70
+ oauthSkipped = headless.skipped;
71
+ const converted = mcps.filter((m) => m.auth.type === "api-key" || m.auth.type === "bearer");
72
+ if (converted.length > 0) {
73
+ logger.success(`${converted.length} MCP(s) OAuth convertido(s) para modo headless: ${converted.map((m) => m.name).join(", ")}`);
74
+ }
75
+ if (oauthSkipped.length > 0) {
76
+ logger.warn(`${oauthSkipped.length} MCP(s) sem alternativa headless: ${oauthSkipped.map((m) => m.name).join(", ")}`);
77
+ }
78
+ }
79
+ const spinner1 = logger.spinner("Verificando MCPs j\xE1 instalados...");
80
+ const installed = await getInstalledMcps();
81
+ spinner1.stop();
82
+ const { pending, existing } = filterAlreadyInstalled(mcps, installed);
83
+ if (existing.length > 0) {
84
+ logger.info(`${existing.length} MCP(s) j\xE1 instalado(s): ${existing.map((m) => m.name).join(", ")}`);
85
+ }
86
+ if (pending.length === 0) {
87
+ logger.success("Todos os MCPs do template j\xE1 est\xE3o configurados!");
88
+ return;
89
+ }
90
+ logger.info(`${pending.length} MCP(s) pendente(s) para instala\xE7\xE3o`);
91
+ const envResult = loadEnv();
92
+ if (envResult.success) {
93
+ const validations = validateAllCredentials(template, envResult.vars);
94
+ const failures = validations.filter((v) => !v.valid);
95
+ const pendingNameSet = new Set(pending.map((m) => m.name));
96
+ const relevantFailures = failures.filter((f) => {
97
+ const mcp = pending.find((m) => m.auth.envVar === f.variable);
98
+ return mcp && pendingNameSet.has(mcp.name);
99
+ });
100
+ if (relevantFailures.length > 0) {
101
+ logger.warn(`${relevantFailures.length} credencial(is) com problema:`);
102
+ for (const f of relevantFailures) {
103
+ logger.warn(` ${f.variable}: ${f.error}`);
104
+ }
105
+ const criticalFailures = relevantFailures.filter((f) => {
106
+ const mcp = pending.find((m) => m.auth.envVar === f.variable);
107
+ return mcp && mcp.auth.type !== "oauth" && mcp.auth.type !== "none";
108
+ });
109
+ if (criticalFailures.length > 0 && !dryRun) {
110
+ logger.error("Corrija as credenciais acima antes de instalar. Consulte .env.example.");
111
+ process.exit(1);
112
+ }
113
+ } else {
114
+ logger.success("Credenciais validadas para MCPs pendentes");
115
+ }
116
+ } else {
117
+ logger.warn(envResult.error || "Arquivo .env n\xE3o encontrado");
118
+ if (!dryRun) {
119
+ logger.warn("Prosseguindo sem valida\xE7\xE3o de credenciais...");
120
+ }
121
+ }
122
+ const pendingNames = pending.map((m) => m.name);
123
+ const scopes = resolveScopesForProfile(pendingNames, scope);
124
+ const commands = generateCommands(pending, scopes);
125
+ if (dryRun) {
126
+ logger.info("\nComandos que seriam executados:\n");
127
+ for (const cmd of commands) {
128
+ console.log(` [${cmd.scope}] ${cmd.command}`);
129
+ }
130
+ console.log("");
131
+ if (existing.length > 0) logger.info(`${existing.length} j\xE1 instalado(s) (sem a\xE7\xE3o)`);
132
+ if (oauthSkipped.length > 0) logger.warn(`${oauthSkipped.length} sem alternativa headless: ${oauthSkipped.map((m) => m.name).join(", ")}`);
133
+ logger.info(`${pending.length} seria(m) instalado(s)`);
134
+ return;
135
+ }
136
+ const spinner2 = logger.spinner(`Instalando ${commands.length} MCPs...`);
137
+ const results = await executeCommands(commands, false);
138
+ spinner2.stop();
139
+ const success = results.filter((r) => r.success && !r.skipped);
140
+ const skipped = results.filter((r) => r.skipped);
141
+ const failed = results.filter((r) => !r.success);
142
+ console.log("");
143
+ if (existing.length > 0) {
144
+ logger.info(`${existing.length} MCP(s) j\xE1 configurado(s) (sem a\xE7\xE3o)`);
145
+ for (const m of existing) console.log(` ${m.name}`);
146
+ }
147
+ if (success.length > 0) {
148
+ logger.success(`${success.length} MCP(s) instalado(s) com sucesso`);
149
+ for (const r of success) console.log(` ${r.mcpName}: ${r.message}`);
150
+ }
151
+ if (skipped.length > 0) {
152
+ logger.info(`${skipped.length} MCP(s) ignorado(s) na execu\xE7\xE3o`);
153
+ for (const r of skipped) console.log(` ${r.mcpName}`);
154
+ }
155
+ if (oauthSkipped.length > 0) {
156
+ logger.warn(`${oauthSkipped.length} MCP(s) sem alternativa headless (apenas Figma)`);
157
+ for (const m of oauthSkipped) console.log(` ${m.name} \u2014 requer browser para OAuth`);
158
+ }
159
+ if (failed.length > 0) {
160
+ logger.error(`${failed.length} MCP(s) falharam na instala\xE7\xE3o`);
161
+ for (const r of failed) console.log(` ${r.mcpName}: ${r.message}`);
162
+ process.exit(1);
163
+ }
164
+ console.log("");
165
+ logger.success(`Template "${template}" instalado com sucesso!`);
166
+ }
167
+ export {
168
+ installCommand
169
+ };
@@ -0,0 +1,29 @@
1
+ import {
2
+ listMcps
3
+ } from "./chunk-UZ72QCYF.js";
4
+ import {
5
+ logger
6
+ } from "./chunk-Q36CDQK6.js";
7
+
8
+ // src/commands/list.ts
9
+ async function listCommand(options) {
10
+ const mcps = listMcps();
11
+ logger.info(`${mcps.length} MCPs dispon\xEDveis no cat\xE1logo:
12
+ `);
13
+ const byCategory = /* @__PURE__ */ new Map();
14
+ for (const mcp of mcps) {
15
+ const list = byCategory.get(mcp.category) || [];
16
+ list.push(mcp);
17
+ byCategory.set(mcp.category, list);
18
+ }
19
+ for (const [category, categoryMcps] of byCategory) {
20
+ console.log(` ${category.toUpperCase()}`);
21
+ for (const mcp of categoryMcps) {
22
+ console.log(` ${mcp.name.padEnd(16)} ${mcp.authType.padEnd(8)} ${mcp.displayName}`);
23
+ }
24
+ console.log("");
25
+ }
26
+ }
27
+ export {
28
+ listCommand
29
+ };
@@ -0,0 +1,30 @@
1
+ import {
2
+ listProfiles
3
+ } from "./chunk-UZ72QCYF.js";
4
+ import {
5
+ logger
6
+ } from "./chunk-Q36CDQK6.js";
7
+
8
+ // src/commands/profiles.ts
9
+ async function profilesCommand(options) {
10
+ const profiles = listProfiles();
11
+ logger.info("Profiles dispon\xEDveis:\n");
12
+ for (const profile of profiles) {
13
+ console.log(` ${profile.name.padEnd(10)} ${String(profile.mcpCount).padStart(2)} MCPs \u2014 ${profile.description}`);
14
+ }
15
+ if (options.verbose) {
16
+ console.log("");
17
+ for (const profile of profiles) {
18
+ const { loadProfile } = await import("./config-loader-O23HRZIK.js");
19
+ const full = loadProfile(profile.name);
20
+ logger.info(`${profile.displayName} (${profile.name}):`);
21
+ for (const mcp of full.mcps) {
22
+ console.log(` - ${mcp}`);
23
+ }
24
+ console.log("");
25
+ }
26
+ }
27
+ }
28
+ export {
29
+ profilesCommand
30
+ };
@@ -0,0 +1,39 @@
1
+ import {
2
+ loadMcp
3
+ } from "./chunk-UZ72QCYF.js";
4
+ import {
5
+ logger
6
+ } from "./chunk-Q36CDQK6.js";
7
+
8
+ // src/commands/remove.ts
9
+ import { exec as execCb } from "child_process";
10
+ import { promisify } from "util";
11
+ var exec = promisify(execCb);
12
+ async function removeCommand(mcp, options) {
13
+ let mcpDef;
14
+ try {
15
+ mcpDef = loadMcp(mcp);
16
+ } catch {
17
+ logger.error(`MCP "${mcp}" n\xE3o encontrado no cat\xE1logo`);
18
+ process.exit(1);
19
+ }
20
+ logger.info(`Removendo MCP "${mcpDef.displayName}"...`);
21
+ const scopeFlag = options.scope ? `-s ${options.scope}` : "";
22
+ const command = `claude mcp remove ${mcp} ${scopeFlag}`.trim();
23
+ try {
24
+ const { stdout } = await exec(command);
25
+ logger.success(`MCP ${mcpDef.displayName} removido com sucesso`);
26
+ if (stdout.trim()) console.log(` ${stdout.trim()}`);
27
+ } catch (error) {
28
+ const msg = error.stderr || error.message;
29
+ if (msg.includes("not found") || msg.includes("n\xE3o encontrado")) {
30
+ logger.warn(`MCP ${mcpDef.displayName} n\xE3o est\xE1 configurado`);
31
+ } else {
32
+ logger.error(`Falha ao remover ${mcpDef.displayName}: ${msg}`);
33
+ process.exit(1);
34
+ }
35
+ }
36
+ }
37
+ export {
38
+ removeCommand
39
+ };
@@ -0,0 +1,55 @@
1
+ import {
2
+ executeCommand,
3
+ generateCommand,
4
+ resolveScope
5
+ } from "./chunk-H3PELLAE.js";
6
+ import {
7
+ listMcps,
8
+ loadMcp
9
+ } from "./chunk-UZ72QCYF.js";
10
+ import {
11
+ logger
12
+ } from "./chunk-Q36CDQK6.js";
13
+
14
+ // src/commands/update.ts
15
+ async function updateCommand(mcp, options) {
16
+ if (!mcp && !options.all) {
17
+ logger.info("Especifique um MCP para atualizar ou use --all para atualizar todos");
18
+ logger.info("Exemplo: mcp-setup update github");
19
+ logger.info(" mcp-setup update --all");
20
+ return;
21
+ }
22
+ const mcpsToUpdate = mcp ? [mcp] : listMcps().map((m) => m.name);
23
+ logger.info(`Atualizando ${mcpsToUpdate.length} MCP(s)...`);
24
+ let updated = 0;
25
+ let failed = 0;
26
+ for (const mcpName of mcpsToUpdate) {
27
+ try {
28
+ const mcpDef = loadMcp(mcpName);
29
+ const scope = resolveScope(mcpName);
30
+ const cmd = generateCommand(mcpDef, scope);
31
+ if (options.dryRun) {
32
+ logger.info(`[dry-run] ${cmd.command}`);
33
+ continue;
34
+ }
35
+ const result = await executeCommand(cmd, false);
36
+ if (result.success) {
37
+ logger.success(`${mcpDef.displayName} atualizado`);
38
+ updated++;
39
+ } else {
40
+ logger.warn(`${mcpDef.displayName}: ${result.message}`);
41
+ failed++;
42
+ }
43
+ } catch (error) {
44
+ logger.warn(`${mcpName}: ${error.message}`);
45
+ failed++;
46
+ }
47
+ }
48
+ if (!options.dryRun) {
49
+ console.log("");
50
+ logger.info(`${updated} atualizado(s), ${failed} falha(s)`);
51
+ }
52
+ }
53
+ export {
54
+ updateCommand
55
+ };