@enfyra/mcp-server 0.0.28 → 0.0.29
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/README.md +10 -9
- package/package.json +1 -1
- package/src/lib/config-local.mjs +35 -19
package/README.md
CHANGED
|
@@ -20,8 +20,9 @@ npx @enfyra/mcp-server config
|
|
|
20
20
|
- **Interactive (default in a terminal):** first asks **where** to write config with an arrow-key selector — Claude Code, Cursor, Codex, or all — unless you already passed target flags. Then prompts for `ENFYRA_API_URL`, `ENFYRA_EMAIL`, and `ENFYRA_PASSWORD` when missing. Press **Enter** to accept bracketed defaults from env or existing `enfyra` config. Password **Enter** keeps the current saved password when updating.
|
|
21
21
|
- **Re-run anytime** to update the same files; other entries under `mcpServers` are preserved.
|
|
22
22
|
- **Non-interactive** (CI / scripts): `npx @enfyra/mcp-server config --yes` plus optional `-a` / `-e` / `-p` and/or env vars.
|
|
23
|
-
- **One host only:** `--claude-code` / `--claude` / `--claude-only` → `./.mcp.json`. `--cursor` / `--cursor-only` → `./.cursor/mcp.json`. `--codex` / `--codex-only` →
|
|
24
|
-
- **Reconfigure:** `npx @enfyra/mcp-server config --reconfig` prompts for the target host again, uses existing values as defaults, and replaces the old `enfyra` entry for that host.
|
|
23
|
+
- **One host only:** `--claude-code` / `--claude` / `--claude-only` → `./.mcp.json`. `--cursor` / `--cursor-only` → `./.cursor/mcp.json`. `--codex` / `--codex-only` → `./.codex/config.toml`. Pass multiple target flags to write each selected host.
|
|
24
|
+
- **Reconfigure:** `npx @enfyra/mcp-server config --reconfig` prompts for the target host again, uses existing project values as defaults, and replaces the old project `enfyra` entry for that host.
|
|
25
|
+
- **Global/user config:** add `--global` only when you intentionally want the selected host config under your home directory instead of this project.
|
|
25
26
|
- **Help:** `npx @enfyra/mcp-server -h` or `npx @enfyra/mcp-server config --help`
|
|
26
27
|
|
|
27
28
|
Equivalent in this repo: `yarn mcp:config` (Yarn v1 reserves `yarn config` for registry settings). Same as `node src/index.mjs config` / `npm run mcp:config`.
|
|
@@ -34,18 +35,18 @@ Use this table to see **where** each host stores config. The **`mcpServers.enfyr
|
|
|
34
35
|
|
|
35
36
|
| | **Codex** | **Claude Code** | **Cursor** |
|
|
36
37
|
|---|-----------|-----------------|------------|
|
|
37
|
-
| **
|
|
38
|
-
| **
|
|
39
|
-
| **Typical install** | `npx @enfyra/mcp-server config --codex` | `
|
|
40
|
-
| **Precedence / merge** |
|
|
41
|
-
| **Gotcha** |
|
|
38
|
+
| **Project (repo, default)** | **`.codex/config.toml`** in the project | **`.mcp.json`** at repository root | **`.cursor/mcp.json`** in the project |
|
|
39
|
+
| **Global (explicit `--global`)** | `~/.codex/config.toml` | `~/.mcp.json` from this helper, or Claude's `~/.claude.json` via `claude mcp add --scope user` | `~/.cursor/mcp.json` |
|
|
40
|
+
| **Typical install** | `npx @enfyra/mcp-server config --codex` | `npx @enfyra/mcp-server config --claude-code` | `npx @enfyra/mcp-server config --cursor` |
|
|
41
|
+
| **Precedence / merge** | Project config is merged/replaced for `enfyra` | Project `.mcp.json` is merged/replaced for `enfyra` | Project `.cursor/mcp.json` is merged/replaced for `enfyra` |
|
|
42
|
+
| **Gotcha** | Open this folder in a new Codex session after editing config | Do not put MCP server definitions in `.claude/settings.json` | Root **`.mcp.json`** is for Claude Code project scope, not Cursor — use **`.cursor/mcp.json`** for Cursor |
|
|
42
43
|
|
|
43
44
|
Expand **one** block below for step-by-step setup.
|
|
44
45
|
|
|
45
46
|
<details open>
|
|
46
47
|
<summary><strong>Codex</strong> — setup</summary>
|
|
47
48
|
|
|
48
|
-
The config command
|
|
49
|
+
The config command writes project Codex config to `./.codex/config.toml` by default:
|
|
49
50
|
|
|
50
51
|
```bash
|
|
51
52
|
npx @enfyra/mcp-server config --codex
|
|
@@ -73,7 +74,7 @@ ENFYRA_EMAIL = "your-email@example.com"
|
|
|
73
74
|
ENFYRA_PASSWORD = "your-password"
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
The config writer replaces only `[mcp_servers.enfyra]` and `[mcp_servers.enfyra.env]`; other Codex config and other MCP servers are preserved.
|
|
77
|
+
The config writer replaces only `[mcp_servers.enfyra]` and `[mcp_servers.enfyra.env]`; other Codex config and other MCP servers are preserved. Open this folder in a new Codex session after updating `./.codex/config.toml`. Use `--global --codex` only when you intentionally want `~/.codex/config.toml`.
|
|
77
78
|
|
|
78
79
|
</details>
|
|
79
80
|
|
package/package.json
CHANGED
package/src/lib/config-local.mjs
CHANGED
|
@@ -13,32 +13,34 @@ function printHelp() {
|
|
|
13
13
|
Usage:
|
|
14
14
|
npx @enfyra/mcp-server config [options]
|
|
15
15
|
|
|
16
|
-
Writes project config under the current working directory
|
|
16
|
+
Writes project config under the current working directory:
|
|
17
17
|
• ./.mcp.json — Claude Code project scope
|
|
18
18
|
• ./.cursor/mcp.json — Cursor project scope
|
|
19
|
-
•
|
|
19
|
+
• ./.codex/config.toml — Codex project scope
|
|
20
20
|
|
|
21
21
|
Options:
|
|
22
22
|
--api-url, -a <url> ENFYRA_API_URL
|
|
23
23
|
--email, -e <email> ENFYRA_EMAIL
|
|
24
24
|
--password, -p <secret> ENFYRA_PASSWORD
|
|
25
|
+
--global Write global/user config for selected hosts instead of project config
|
|
25
26
|
--reconfig Always choose target again in interactive mode and replace the old enfyra config for that target
|
|
26
27
|
--yes Non-interactive: no prompts (CI / scripts); use CLI, env, existing file, then defaults
|
|
27
28
|
Target — non-interactive default is all; with TTY and no target flags, choose with ↑/↓:
|
|
28
29
|
--claude-code, --claude, --claude-only Only ./.mcp.json (Claude Code project scope)
|
|
29
30
|
--cursor, --cursor-only Only ./.cursor/mcp.json (Cursor)
|
|
30
|
-
--codex, --codex-only Only
|
|
31
|
+
--codex, --codex-only Only ./.codex/config.toml (Codex project scope)
|
|
31
32
|
Passing multiple target flags writes each selected target.
|
|
32
33
|
-h, --help Show this help
|
|
33
34
|
|
|
34
35
|
Interactive mode: lets you choose Claude Code / Cursor / Codex / all if you did not pass target flags; then asks for URL / email / password
|
|
35
|
-
when missing. Existing
|
|
36
|
+
when missing. Existing project config is used as defaults. Re-run to update.
|
|
36
37
|
|
|
37
38
|
Examples:
|
|
38
39
|
npx @enfyra/mcp-server config
|
|
39
40
|
npx @enfyra/mcp-server config --claude-code
|
|
40
41
|
npx @enfyra/mcp-server config --cursor --yes
|
|
41
42
|
npx @enfyra/mcp-server config --codex --yes
|
|
43
|
+
npx @enfyra/mcp-server config --global --codex
|
|
42
44
|
npx @enfyra/mcp-server config --reconfig
|
|
43
45
|
npx @enfyra/mcp-server config -a http://localhost:3000/api -e admin@x.com -p 'secret'
|
|
44
46
|
npx @enfyra/mcp-server config --yes
|
|
@@ -57,6 +59,7 @@ function parseArgs(argv) {
|
|
|
57
59
|
help: false,
|
|
58
60
|
yes: false,
|
|
59
61
|
reconfig: false,
|
|
62
|
+
global: false,
|
|
60
63
|
};
|
|
61
64
|
let pickClaude = false;
|
|
62
65
|
let pickCursor = false;
|
|
@@ -73,6 +76,7 @@ function parseArgs(argv) {
|
|
|
73
76
|
else if (a === 'help') out.help = true;
|
|
74
77
|
else if (a === '--yes') out.yes = true;
|
|
75
78
|
else if (a === '--reconfig') out.reconfig = true;
|
|
79
|
+
else if (a === '--global') out.global = true;
|
|
76
80
|
else if (a === '--api-url' || a === '-a') out.apiUrl = next();
|
|
77
81
|
else if (a === '--email' || a === '-e') out.email = next();
|
|
78
82
|
else if (a === '--password' || a === '-p') out.password = next();
|
|
@@ -200,11 +204,23 @@ async function readCodexEnfyraEnv(absPath) {
|
|
|
200
204
|
return null;
|
|
201
205
|
}
|
|
202
206
|
|
|
203
|
-
|
|
207
|
+
function getCodexConfigPath(root, globalScope) {
|
|
208
|
+
return globalScope ? join(homedir(), '.codex', 'config.toml') : join(root, '.codex', 'config.toml');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function getClaudeConfigPath(root, globalScope) {
|
|
212
|
+
return globalScope ? join(homedir(), '.mcp.json') : join(root, '.mcp.json');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function getCursorConfigPath(root, globalScope) {
|
|
216
|
+
return globalScope ? join(homedir(), '.cursor', 'mcp.json') : join(root, '.cursor', 'mcp.json');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function loadExistingEnfyraEnv(root, readClaude, readCursor, readCodex, globalScope) {
|
|
204
220
|
const paths = [];
|
|
205
|
-
if (readClaude) paths.push(
|
|
206
|
-
if (readCursor) paths.push(
|
|
207
|
-
if (!readClaude && readCursor) paths.push(join(root, '.mcp.json'));
|
|
221
|
+
if (readClaude) paths.push(getClaudeConfigPath(root, globalScope));
|
|
222
|
+
if (readCursor) paths.push(getCursorConfigPath(root, globalScope));
|
|
223
|
+
if (!globalScope && !readClaude && readCursor) paths.push(join(root, '.mcp.json'));
|
|
208
224
|
const seen = new Set();
|
|
209
225
|
for (const p of paths) {
|
|
210
226
|
if (seen.has(p)) continue;
|
|
@@ -225,7 +241,7 @@ async function loadExistingEnfyraEnv(root, readClaude, readCursor, readCodex) {
|
|
|
225
241
|
}
|
|
226
242
|
}
|
|
227
243
|
if (readCodex) {
|
|
228
|
-
const codex = await readCodexEnfyraEnv(
|
|
244
|
+
const codex = await readCodexEnfyraEnv(getCodexConfigPath(root, globalScope));
|
|
229
245
|
if (codex) return codex;
|
|
230
246
|
}
|
|
231
247
|
return { apiUrl: '', email: '', password: '' };
|
|
@@ -234,15 +250,15 @@ async function loadExistingEnfyraEnv(root, readClaude, readCursor, readCodex) {
|
|
|
234
250
|
async function promptTargetChoice() {
|
|
235
251
|
const choices = [
|
|
236
252
|
{
|
|
237
|
-
label: 'Claude Code — ./.mcp.json',
|
|
253
|
+
label: 'Claude Code — project ./.mcp.json',
|
|
238
254
|
value: { claude: true, cursor: false, codex: false },
|
|
239
255
|
},
|
|
240
256
|
{
|
|
241
|
-
label: 'Cursor — ./.cursor/mcp.json',
|
|
257
|
+
label: 'Cursor — project ./.cursor/mcp.json',
|
|
242
258
|
value: { claude: false, cursor: true, codex: false },
|
|
243
259
|
},
|
|
244
260
|
{
|
|
245
|
-
label: 'Codex —
|
|
261
|
+
label: 'Codex — project ./.codex/config.toml',
|
|
246
262
|
value: { claude: false, cursor: false, codex: true },
|
|
247
263
|
},
|
|
248
264
|
{
|
|
@@ -259,7 +275,7 @@ async function promptTargetChoice() {
|
|
|
259
275
|
'Where should Enfyra MCP config be written?\n'
|
|
260
276
|
+ ' [1] Claude Code — ./.mcp.json\n'
|
|
261
277
|
+ ' [2] Cursor — ./.cursor/mcp.json\n'
|
|
262
|
-
+ ' [3] Codex —
|
|
278
|
+
+ ' [3] Codex — ./.codex/config.toml\n'
|
|
263
279
|
+ ' [4] All [default]\n'
|
|
264
280
|
+ 'Choice [4]: ',
|
|
265
281
|
)).trim().toLowerCase();
|
|
@@ -420,7 +436,7 @@ export async function runLocalConfig(argv) {
|
|
|
420
436
|
writeCodex = t.codex;
|
|
421
437
|
}
|
|
422
438
|
|
|
423
|
-
const existing = await loadExistingEnfyraEnv(root, writeClaude, writeCursor, writeCodex);
|
|
439
|
+
const existing = await loadExistingEnfyraEnv(root, writeClaude, writeCursor, writeCodex, opts.global);
|
|
424
440
|
|
|
425
441
|
let apiUrl;
|
|
426
442
|
let email;
|
|
@@ -441,17 +457,17 @@ export async function runLocalConfig(argv) {
|
|
|
441
457
|
const written = [];
|
|
442
458
|
|
|
443
459
|
if (writeClaude) {
|
|
444
|
-
const p =
|
|
460
|
+
const p = getClaudeConfigPath(root, opts.global);
|
|
445
461
|
await mergeMcpFile(p, serverEntry);
|
|
446
462
|
written.push(p);
|
|
447
463
|
}
|
|
448
464
|
if (writeCursor) {
|
|
449
|
-
const p =
|
|
465
|
+
const p = getCursorConfigPath(root, opts.global);
|
|
450
466
|
await mergeMcpFile(p, serverEntry);
|
|
451
467
|
written.push(p);
|
|
452
468
|
}
|
|
453
469
|
if (writeCodex) {
|
|
454
|
-
const p =
|
|
470
|
+
const p = getCodexConfigPath(root, opts.global);
|
|
455
471
|
await mergeCodexConfig(p, apiUrl, email, password);
|
|
456
472
|
written.push(p);
|
|
457
473
|
}
|
|
@@ -459,9 +475,9 @@ export async function runLocalConfig(argv) {
|
|
|
459
475
|
console.log('Enfyra MCP — local config updated:\n');
|
|
460
476
|
for (const p of written) console.log(` ${p}`);
|
|
461
477
|
console.log('\nNext steps:');
|
|
462
|
-
console.log(' • Codex:
|
|
478
|
+
console.log(' • Codex: open this folder in a new Codex session so project ./.codex/config.toml is loaded.');
|
|
463
479
|
console.log(' • Claude Code: open this folder; approve project MCP if prompted (`claude mcp reset-project-choices` to reset).');
|
|
464
|
-
console.log(' • Cursor: restart Cursor or reload MCP
|
|
480
|
+
console.log(' • Cursor: open this folder, restart Cursor or reload MCP, then confirm server under Settings → MCP.');
|
|
465
481
|
console.log(' • Run `config` again anytime to change values (same files are merged/overwritten for `enfyra`).');
|
|
466
482
|
if (!email || !password) {
|
|
467
483
|
console.log('\nWarning: ENFYRA_EMAIL or ENFYRA_PASSWORD is empty — tools may not authenticate until set.');
|