@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 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` → `~/.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 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
- | **Global (all projects)** | `~/.codex/config.toml` | `~/.claude.json` scopes **user** or **local** | `~/.cursor/mcp.json` |
38
- | **Project (repo)** | Use global config | **`.mcp.json`** at repository root (`--scope project`) | **`.cursor/mcp.json`** in the project |
39
- | **Typical install** | `npx @enfyra/mcp-server config --codex` | `claude mcp add --transport stdio …` | Edit `mcp.json` or **Settings → MCP** |
40
- | **Precedence / merge** | `config.toml` section is replaced for `enfyra`; other servers are preserved | local → project `.mcp.json` user | Project `.cursor/mcp.json` overrides global `~/.cursor/mcp.json` |
41
- | **Gotcha** | Restart Codex or start a new 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 |
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 can write/update `~/.codex/config.toml` directly:
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. Restart Codex or start a new session after updating `~/.codex/config.toml`.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfyra/mcp-server",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "MCP server for Enfyra - manage your Enfyra instance via Claude Code",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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 and Codex config under your home 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
- ~/.codex/config.toml — Codex user scope
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 ~/.codex/config.toml (Codex)
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 ./.mcp.json, ./.cursor/mcp.json, and ~/.codex/config.toml are used as defaults. Re-run to update.
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
- async function loadExistingEnfyraEnv(root, readClaude, readCursor, readCodex) {
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(join(root, '.mcp.json'));
206
- if (readCursor) paths.push(join(root, '.cursor', 'mcp.json'));
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(join(homedir(), '.codex', 'config.toml'));
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 — ~/.codex/config.toml',
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 — ~/.codex/config.toml\n'
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 = join(root, '.mcp.json');
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 = join(root, '.cursor', 'mcp.json');
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 = join(homedir(), '.codex', 'config.toml');
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: restart Codex or start a new session so ~/.codex/config.toml is reloaded.');
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; confirm server under Settings → 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.');