komplian 0.4.6 → 0.4.7
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/komplian-mcp-tools.mjs +238 -0
- package/komplian-onboard.mjs +7 -1
- package/package.json +4 -3
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Komplian MCP — escribe `.cursor/mcp.json` con servidores MCP por stdio (prefijo KOMPLIAN-*)
|
|
4
|
+
* y genera `.cursor/KOMPLIAN_MCP_SETUP.md` (plugins de Cursor que no van en JSON).
|
|
5
|
+
*
|
|
6
|
+
* No incluye secretos: tokens vacíos; rellena en Cursor o vía KOMPLIAN_MCP_SECRETS.env (local, gitignored).
|
|
7
|
+
*
|
|
8
|
+
* Uso: npx komplian mcp-tools --yes
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { mkdirSync, readFileSync, existsSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
import { createInterface } from "node:readline/promises";
|
|
15
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
16
|
+
|
|
17
|
+
const c = {
|
|
18
|
+
reset: "\x1b[0m",
|
|
19
|
+
dim: "\x1b[2m",
|
|
20
|
+
bold: "\x1b[1m",
|
|
21
|
+
cyan: "\x1b[36m",
|
|
22
|
+
green: "\x1b[32m",
|
|
23
|
+
red: "\x1b[31m",
|
|
24
|
+
yellow: "\x1b[33m",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function log(s = "") {
|
|
28
|
+
console.log(s);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Preset Komplian: solo claves KOMPLIAN-* para no pisar servidores del dev. */
|
|
32
|
+
const KOMPLIAN_MCP_PRESET = {
|
|
33
|
+
mcpServers: {
|
|
34
|
+
"KOMPLIAN-github": {
|
|
35
|
+
command: "npx",
|
|
36
|
+
args: ["-y", "@modelcontextprotocol/server-github"],
|
|
37
|
+
env: {
|
|
38
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: "",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
"KOMPLIAN-sentry": {
|
|
42
|
+
command: "npx",
|
|
43
|
+
args: ["-y", "@sentry/mcp-server@latest"],
|
|
44
|
+
env: {},
|
|
45
|
+
},
|
|
46
|
+
"KOMPLIAN-stripe": {
|
|
47
|
+
command: "npx",
|
|
48
|
+
args: ["-y", "@stripe/mcp"],
|
|
49
|
+
env: {
|
|
50
|
+
STRIPE_SECRET_KEY: "",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const SETUP_MD = `# KOMPLIAN — MCP en Cursor
|
|
57
|
+
|
|
58
|
+
Este archivo lo genera \`npx komplian mcp-tools\`. **No commitees** tokens; \`.cursor/mcp.json\` puede llevar env vacíos que rellenas solo en local.
|
|
59
|
+
|
|
60
|
+
## 1. Servidores en \`.cursor/mcp.json\` (stdio / npx)
|
|
61
|
+
|
|
62
|
+
| ID | Qué es | Rellena |
|
|
63
|
+
|----|--------|---------|
|
|
64
|
+
| **KOMPLIAN-github** | GitHub API (issues, PRs) | \`GITHUB_PERSONAL_ACCESS_TOKEN\` en el bloque \`env\` del servidor (PAT con scopes repo/workflow según necesidad). El paquete npm está deprecado a favor del servidor oficial; si falla, sustituye por la config que indique [github/github-mcp-server](https://github.com/github/github-mcp-server). |
|
|
65
|
+
| **KOMPLIAN-sentry** | Sentry (issues, trazas) | Primera vez: login por navegador (device code). **Komplian:** \`organizationSlug\` = \`komplian\`, \`regionUrl\` = \`https://de.sentry.io\`. Proyectos: \`komplian-api\`, \`komplian-app\`. |
|
|
66
|
+
| **KOMPLIAN-stripe** | Stripe API | \`STRIPE_SECRET_KEY\` en \`env\` (mejor **Restricted key** / test en dev). Modo test vs live según [docs Stripe MCP](https://docs.stripe.com/mcp). |
|
|
67
|
+
|
|
68
|
+
## 2. Solo en Cursor (plugins / integraciones)
|
|
69
|
+
|
|
70
|
+
Estos **no** se instalan con npx en este JSON; actívalos en **Cursor → Settings → MCP** (o integraciones) e inicia sesión:
|
|
71
|
+
|
|
72
|
+
| Integración | Uso en Komplian |
|
|
73
|
+
|-------------|-----------------|
|
|
74
|
+
| **Atlassian** (Jira + Confluence) | Site \`komplian.atlassian.net\`, proyecto Jira **KAPP**. Plugin \`plugin-atlassian-atlassian\` / \`user-mcp-atlassian\`. |
|
|
75
|
+
| **Chrome DevTools** | Depuración del navegador (\`user-chrome-devtools\`). |
|
|
76
|
+
|
|
77
|
+
## 3. Reinicio
|
|
78
|
+
|
|
79
|
+
Tras editar \`mcp.json\`, **reinicia Cursor** (o recarga ventana) para cargar MCP.
|
|
80
|
+
|
|
81
|
+
## 4. Referencia interna
|
|
82
|
+
|
|
83
|
+
Ver \`.cursor/rules/mcp-integrations.mdc\` en el monorepo (org Sentry, Stripe, reglas KAPP).
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
function findWorkspaceRoot(start) {
|
|
87
|
+
let dir = resolve(start);
|
|
88
|
+
for (let i = 0; i < 8; i++) {
|
|
89
|
+
if (
|
|
90
|
+
existsSync(join(dir, "api", "package.json")) &&
|
|
91
|
+
existsSync(join(dir, "app", "package.json"))
|
|
92
|
+
) {
|
|
93
|
+
return dir;
|
|
94
|
+
}
|
|
95
|
+
const parent = dirname(dir);
|
|
96
|
+
if (parent === dir) break;
|
|
97
|
+
dir = parent;
|
|
98
|
+
}
|
|
99
|
+
return resolve(start);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function mergeKomplianPreset(existing, preset, force) {
|
|
103
|
+
const base =
|
|
104
|
+
existing && typeof existing === "object" ? structuredClone(existing) : {};
|
|
105
|
+
if (!base.mcpServers || typeof base.mcpServers !== "object") {
|
|
106
|
+
base.mcpServers = {};
|
|
107
|
+
}
|
|
108
|
+
for (const [name, cfg] of Object.entries(preset.mcpServers)) {
|
|
109
|
+
if (!name.startsWith("KOMPLIAN-")) continue;
|
|
110
|
+
if (!force && base.mcpServers[name]) continue;
|
|
111
|
+
base.mcpServers[name] = structuredClone(cfg);
|
|
112
|
+
}
|
|
113
|
+
return base;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function parseMcpArgs(argv) {
|
|
117
|
+
const opts = {
|
|
118
|
+
yes: false,
|
|
119
|
+
force: false,
|
|
120
|
+
dryRun: false,
|
|
121
|
+
global: false,
|
|
122
|
+
help: false,
|
|
123
|
+
workspace: "",
|
|
124
|
+
};
|
|
125
|
+
const rest = [];
|
|
126
|
+
for (let i = 0; i < argv.length; i++) {
|
|
127
|
+
const a = argv[i];
|
|
128
|
+
if (a === "--yes" || a === "-y") opts.yes = true;
|
|
129
|
+
else if (a === "--force") opts.force = true;
|
|
130
|
+
else if (a === "--dry-run") opts.dryRun = true;
|
|
131
|
+
else if (a === "--global") opts.global = true;
|
|
132
|
+
else if (a === "-h" || a === "--help") opts.help = true;
|
|
133
|
+
else if (a === "--workspace" || a === "-w") opts.workspace = argv[++i] || "";
|
|
134
|
+
else if (a.startsWith("-")) {
|
|
135
|
+
log(`${c.red}✗${c.reset} Opción desconocida: ${a}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
} else rest.push(a);
|
|
138
|
+
}
|
|
139
|
+
if (rest[0]) opts.workspace = rest[0];
|
|
140
|
+
return opts;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function usageMcpTools() {
|
|
144
|
+
log(`Uso: npx komplian mcp-tools [opciones] [carpeta-monorepo]`);
|
|
145
|
+
log(``);
|
|
146
|
+
log(` Añade servidores MCP KOMPLIAN-* en .cursor/mcp.json (GitHub, Sentry, Stripe)`);
|
|
147
|
+
log(` y genera .cursor/KOMPLIAN_MCP_SETUP.md (Atlassian + Chrome DevTools = solo Cursor).`);
|
|
148
|
+
log(``);
|
|
149
|
+
log(` ${c.dim}Secretos: vacíos en JSON; no se publican en el paquete npm komplian.${c.reset}`);
|
|
150
|
+
log(``);
|
|
151
|
+
log(` -y, --yes Sin confirmación`);
|
|
152
|
+
log(` --force Sobreescribe entradas KOMPLIAN-* existentes`);
|
|
153
|
+
log(` --dry-run Imprime JSON sin escribir`);
|
|
154
|
+
log(` --global Fusiona en ~/.cursor/mcp.json (toda la máquina)`);
|
|
155
|
+
log(` -w, --workspace Raíz del monorepo (por defecto: cwd)`);
|
|
156
|
+
log(` -h, --help`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function confirmForceOverwrite(yes) {
|
|
160
|
+
if (yes) return true;
|
|
161
|
+
const rl = createInterface({ input, output });
|
|
162
|
+
const ans = await rl.question(
|
|
163
|
+
`\n${c.bold}¿Sobrescribir entradas KOMPLIAN-* existentes? [y/N]${c.reset} `
|
|
164
|
+
);
|
|
165
|
+
rl.close();
|
|
166
|
+
return /^y(es)?$/i.test((ans || "").trim());
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export async function runMcpTools(argv) {
|
|
170
|
+
const opts = parseMcpArgs(argv);
|
|
171
|
+
if (opts.help) {
|
|
172
|
+
usageMcpTools();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const workspaceRoot = opts.workspace.trim()
|
|
177
|
+
? resolve(opts.workspace.replace(/^~(?=$|[/\\])/, homedir()))
|
|
178
|
+
: findWorkspaceRoot(process.cwd());
|
|
179
|
+
|
|
180
|
+
const cursorDir = opts.global
|
|
181
|
+
? join(homedir(), ".cursor")
|
|
182
|
+
: join(workspaceRoot, ".cursor");
|
|
183
|
+
const mcpPath = join(cursorDir, "mcp.json");
|
|
184
|
+
const setupPath = join(cursorDir, "KOMPLIAN_MCP_SETUP.md");
|
|
185
|
+
|
|
186
|
+
let existing = {};
|
|
187
|
+
if (existsSync(mcpPath)) {
|
|
188
|
+
try {
|
|
189
|
+
existing = JSON.parse(readFileSync(mcpPath, "utf8"));
|
|
190
|
+
} catch {
|
|
191
|
+
log(`${c.red}✗${c.reset} JSON inválido: ${mcpPath}`);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const hadKomplian = Object.keys(existing.mcpServers || {}).some((k) =>
|
|
197
|
+
k.startsWith("KOMPLIAN-")
|
|
198
|
+
);
|
|
199
|
+
if (opts.force && hadKomplian && !opts.yes) {
|
|
200
|
+
const ok = await confirmForceOverwrite(opts.yes);
|
|
201
|
+
if (!ok) {
|
|
202
|
+
log(`${c.yellow}○${c.reset} Cancelado.`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const merged = mergeKomplianPreset(existing, KOMPLIAN_MCP_PRESET, opts.force);
|
|
208
|
+
const json = JSON.stringify(merged, null, 2);
|
|
209
|
+
|
|
210
|
+
if (opts.dryRun) {
|
|
211
|
+
log(`${c.cyan}━━ dry-run ━━${c.reset} ${mcpPath}`);
|
|
212
|
+
log(json);
|
|
213
|
+
log("");
|
|
214
|
+
log(SETUP_MD);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
mkdirSync(cursorDir, { recursive: true });
|
|
219
|
+
const prevStr = existsSync(mcpPath) ? readFileSync(mcpPath, "utf8") : "";
|
|
220
|
+
const changed = prevStr.trim() !== json.trim();
|
|
221
|
+
if (changed) {
|
|
222
|
+
writeFileSync(mcpPath, json + "\n", "utf8");
|
|
223
|
+
}
|
|
224
|
+
writeFileSync(setupPath, SETUP_MD, "utf8");
|
|
225
|
+
|
|
226
|
+
log("");
|
|
227
|
+
const mcpMark = changed ? `${c.green}✓${c.reset}` : `${c.dim}○${c.reset}`;
|
|
228
|
+
const mcpNote = changed ? "" : ` ${c.dim}(sin cambios)${c.reset}`;
|
|
229
|
+
log(`${mcpMark} ${c.bold}mcp.json${c.reset} ${c.dim}${mcpPath}${c.reset}${mcpNote}`);
|
|
230
|
+
log(`${c.green}✓${c.reset} ${c.bold}KOMPLIAN_MCP_SETUP.md${c.reset} ${c.dim}${setupPath}${c.reset}`);
|
|
231
|
+
log("");
|
|
232
|
+
log(`${c.bold}Siguiente${c.reset}`);
|
|
233
|
+
log(` 1. Rellena tokens vacíos en Cursor (Settings → MCP) o edita ${c.bold}mcp.json${c.reset} en local.`);
|
|
234
|
+
log(` 2. Activa en Cursor: ${c.dim}Atlassian + Chrome DevTools${c.reset} (ver guía arriba).`);
|
|
235
|
+
log(` 3. Reinicia Cursor.`);
|
|
236
|
+
log("");
|
|
237
|
+
log(`${c.dim}Paquete npm komplian solo incluye *.mjs — nunca sube tu mcp.json.${c.reset}`);
|
|
238
|
+
}
|
package/komplian-onboard.mjs
CHANGED
|
@@ -394,11 +394,12 @@ function npmInstallEach(workspace) {
|
|
|
394
394
|
}
|
|
395
395
|
|
|
396
396
|
function usage() {
|
|
397
|
-
log(`Uso: komplian onboard
|
|
397
|
+
log(`Uso: komplian onboard | postman | localhost | mcp-tools [opciones]`);
|
|
398
398
|
log(` npx komplian onboard --yes`);
|
|
399
399
|
log(` npx komplian postman login ${c.dim}(una vez · guarda API key)${c.reset}`);
|
|
400
400
|
log(` npx komplian postman --yes ${c.dim}(email @komplian.com)${c.reset}`);
|
|
401
401
|
log(` npx komplian localhost --yes ${c.dim}(env local + api app web admin docs)${c.reset}`);
|
|
402
|
+
log(` npx komplian mcp-tools --yes ${c.dim}(.cursor/mcp.json + guía MCP Komplian)${c.reset}`);
|
|
402
403
|
log(``);
|
|
403
404
|
log(` Antes (una vez): gh auth login -h github.com -s repo -s read:org -w`);
|
|
404
405
|
log(` Requisitos: Node 18+, git, GitHub CLI (gh)`);
|
|
@@ -492,6 +493,11 @@ async function main() {
|
|
|
492
493
|
await runLocalhost(rawArgv.slice(1));
|
|
493
494
|
return;
|
|
494
495
|
}
|
|
496
|
+
if (rawArgv[0] === "mcp-tools") {
|
|
497
|
+
const { runMcpTools } = await import("./komplian-mcp-tools.mjs");
|
|
498
|
+
await runMcpTools(rawArgv.slice(1));
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
495
501
|
|
|
496
502
|
const configPath = join(__dirname, "komplian-team-repos.json");
|
|
497
503
|
const { argv, fromOnboardSubcommand } = normalizeArgv(rawArgv);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "komplian",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Komplian CLI:
|
|
3
|
+
"version": "0.4.7",
|
|
4
|
+
"description": "Komplian CLI: onboard, Postman, localhost, mcp-tools (Cursor MCP). Node 18+. Published tarball has no .env / secrets.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=18"
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"komplian-onboard.mjs",
|
|
14
14
|
"komplian-postman.mjs",
|
|
15
15
|
"komplian-localhost.mjs",
|
|
16
|
+
"komplian-mcp-tools.mjs",
|
|
16
17
|
"komplian-team-repos.json",
|
|
17
18
|
"README.md"
|
|
18
19
|
],
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
"access": "public"
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
|
-
"prepublishOnly": "node --check komplian-onboard.mjs && node --check komplian-postman.mjs && node --check komplian-localhost.mjs"
|
|
24
|
+
"prepublishOnly": "node --check komplian-onboard.mjs && node --check komplian-postman.mjs && node --check komplian-localhost.mjs && node --check komplian-mcp-tools.mjs"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"komplian",
|