@echomem/mcp 1.0.0 → 1.0.1

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 (2) hide show
  1. package/dist/setup.js +37 -6
  2. package/package.json +1 -1
package/dist/setup.js CHANGED
@@ -39,15 +39,17 @@ export function knownClients() {
39
39
  { id: "windsurf", label: "Windsurf", kind: "json", configPath: home(".codeium", "windsurf", "mcp_config.json") },
40
40
  { id: "claude-desktop", label: "Claude Desktop", kind: "json", configPath: path.join(appSupport, "Claude", "claude_desktop_config.json") },
41
41
  { id: "claude-code", label: "Claude Code", kind: "snippet", note: "run: claude mcp add-json echomem '<entry>' (or add to .mcp.json)" },
42
- { id: "codex", label: "Codex", kind: "snippet", note: "add to ~/.codex/config.toml under [mcp_servers.echomem]" },
42
+ { id: "codex", label: "Codex", kind: "command", detectDir: home(".codex"), configPath: home(".codex", "config.toml"), note: "add to ~/.codex/config.toml under [mcp_servers.echomem]" },
43
43
  ];
44
44
  }
45
45
  /** A client is "present" if its config dir already exists (JSON) — a cheap heuristic for detection. */
46
46
  export function detectClients() {
47
47
  return knownClients().filter((c) => {
48
- if (c.kind !== "json")
49
- return false;
50
- return fs.existsSync(path.dirname(c.configPath));
48
+ if (c.kind === "json")
49
+ return fs.existsSync(path.dirname(c.configPath));
50
+ if (c.kind === "command")
51
+ return fs.existsSync(c.detectDir);
52
+ return false;
51
53
  });
52
54
  }
53
55
  /**
@@ -61,6 +63,28 @@ export function buildServerEntry(opts = {}) {
61
63
  }
62
64
  return { command: "npx", args: ["-y", "@echomem/mcp"] };
63
65
  }
66
+ /** The TOML block EchoMem adds to ~/.codex/config.toml. No secret — the bridge reads the keystore. */
67
+ export function codexTomlBlock(entry) {
68
+ const command = JSON.stringify(String(entry.command));
69
+ const args = (Array.isArray(entry.args) ? entry.args : []).map((a) => JSON.stringify(String(a))).join(", ");
70
+ return `[mcp_servers.echomem]\ncommand = ${command}\nargs = [${args}]\n`;
71
+ }
72
+ /** Write/merge the EchoMem entry straight into Codex's config.toml — no `codex` CLI needed. Idempotent. */
73
+ function writeCodexConfig(configPath, entry) {
74
+ let content = "";
75
+ try {
76
+ content = fs.readFileSync(configPath, "utf8");
77
+ }
78
+ catch {
79
+ /* fresh config */
80
+ }
81
+ if (/^\s*\[mcp_servers\.echomem\]/m.test(content))
82
+ return "exists";
83
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
84
+ const sep = content ? (content.endsWith("\n") ? "\n" : "\n\n") : "";
85
+ fs.appendFileSync(configPath, sep + codexTomlBlock(entry));
86
+ return "wrote";
87
+ }
64
88
  /** Merge the EchoMem entry into a JSON client's `mcpServers` map without clobbering siblings. */
65
89
  export function writeJsonClientConfig(configPath, entry) {
66
90
  let config = {};
@@ -243,9 +267,9 @@ async function cmdSetup(flags) {
243
267
  const requested = typeof flags.client === "string" ? flags.client : undefined;
244
268
  const targets = (requested ? knownClients().filter((c) => c.id === requested) : detectClients());
245
269
  if (targets.length === 0) {
246
- console.log("No JSON-config client auto-detected. Add this MCP server entry manually:\n");
270
+ console.log("No client auto-detected. Add this MCP server entry manually:\n");
247
271
  console.log(JSON.stringify({ echomem: entry }, null, 2));
248
- console.log("\n(Or re-run with --client cursor|windsurf|claude-desktop.)");
272
+ console.log("\n(Or re-run with --client cursor|windsurf|claude-desktop|codex.)");
249
273
  }
250
274
  else {
251
275
  for (const c of targets) {
@@ -253,6 +277,13 @@ async function cmdSetup(flags) {
253
277
  writeJsonClientConfig(c.configPath, entry);
254
278
  console.log(`✅ Wrote EchoMem MCP entry to ${c.label}: ${c.configPath}`);
255
279
  }
280
+ else if (c.kind === "command") {
281
+ const result = writeCodexConfig(c.configPath, entry);
282
+ if (result === "wrote")
283
+ console.log(`✅ Wrote EchoMem MCP entry to ${c.label}: ${c.configPath} — start a new Codex session to load it.`);
284
+ else
285
+ console.log(`✅ ${c.label} already has the EchoMem MCP entry: ${c.configPath}`);
286
+ }
256
287
  else {
257
288
  console.log(`ℹ️ ${c.label}: ${c.note}\n entry: ${JSON.stringify(entry)}`);
258
289
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@echomem/mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "EchoMem Cloud-First MCP Server",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",