fathom-mcp 0.4.10 → 0.4.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fathom-mcp",
3
- "version": "0.4.10",
3
+ "version": "0.4.11",
4
4
  "description": "MCP server for Fathom — vault operations, search, rooms, and cross-workspace communication",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -411,19 +411,20 @@ async function runInit(flags = {}) {
411
411
  }
412
412
 
413
413
  // 5. Server URL
414
- const serverUrl = nonInteractive
414
+ let serverUrl = nonInteractive
415
415
  ? (flagServer || "http://localhost:4243")
416
416
  : await ask(rl, "\n Fathom server URL", "http://localhost:4243");
417
417
 
418
418
  // 6. API key
419
- const apiKey = flagApiKey || (nonInteractive ? "" : await ask(rl, " API key (from dashboard or server first-run output)", ""));
419
+ let apiKey = flagApiKey || (nonInteractive ? "" : await ask(rl, " API key (from dashboard or server first-run output)", ""));
420
420
 
421
421
  // 7. Server probe — check reachability early
422
- const regClient = createClient({ server: serverUrl, apiKey, workspace });
423
- const serverReachable = serverUrl ? await regClient.healthCheck() : false;
422
+ let regClient = createClient({ server: serverUrl, apiKey, workspace });
423
+ let serverReachable = serverUrl ? await regClient.healthCheck() : false;
424
424
  const serverOnPath = detectFathomServer();
425
425
 
426
- if (!serverReachable) {
426
+ // Retry loop for server connectivity (interactive mode)
427
+ while (!serverReachable && !nonInteractive) {
427
428
  console.log(`\n ⚠ Fathom server not reachable at ${serverUrl}\n`);
428
429
  if (serverOnPath === "installed") {
429
430
  console.log(" Start it: fathom-server");
@@ -433,11 +434,25 @@ async function runInit(flags = {}) {
433
434
  console.log(" # or: docker run -p 4243:4243 ghcr.io/myra/fathom-server");
434
435
  }
435
436
  console.log("\n Without the server, only \"local\" and \"none\" vault modes are available.");
437
+ const retry = await askYesNo(rl, "\n Try a different server URL or API key?", true);
438
+ if (!retry) break;
439
+ serverUrl = await ask(rl, "\n Fathom server URL", serverUrl);
440
+ apiKey = await ask(rl, " API key", apiKey);
441
+ regClient = createClient({ server: serverUrl, apiKey, workspace });
442
+ serverReachable = await regClient.healthCheck();
443
+ if (serverReachable) {
444
+ console.log(" ✓ Server connected!");
445
+ }
436
446
  }
437
447
 
438
448
  // 8. Vault mode selection
439
449
  let vaultMode;
440
450
  if (nonInteractive) {
451
+ if (!serverReachable && flagServer) {
452
+ console.error(`\n Error: Server at ${serverUrl} is not reachable.`);
453
+ console.error(" Fix the URL or start the server, then re-run init.");
454
+ process.exit(1);
455
+ }
441
456
  vaultMode = serverReachable ? "hosted" : "local";
442
457
  console.log(` Vault mode: ${vaultMode} (auto-selected)`);
443
458
  } else {
package/src/index.js CHANGED
@@ -624,6 +624,16 @@ async function main() {
624
624
  // Startup sync for synced mode (fire-and-forget)
625
625
  startupSync().catch(() => {});
626
626
 
627
+ // Heartbeat — report liveness to server every 30s
628
+ if (config.server && config.workspace) {
629
+ const beat = () =>
630
+ client
631
+ .heartbeat(config.workspace, config.agents?.[0], config.vaultMode)
632
+ .catch(() => {});
633
+ beat(); // immediate
634
+ setInterval(beat, 30_000);
635
+ }
636
+
627
637
  const transport = new StdioServerTransport();
628
638
  await server.connect(transport);
629
639
  }
@@ -205,6 +205,15 @@ export function createClient(config) {
205
205
  });
206
206
  }
207
207
 
208
+ // --- Heartbeat -------------------------------------------------------------
209
+
210
+ async function heartbeat(ws, agent, vaultMode) {
211
+ const body = {};
212
+ if (agent) body.agent = agent;
213
+ if (vaultMode) body.vault_mode = vaultMode;
214
+ return request("POST", `/api/workspaces/${encodeURIComponent(ws)}/heartbeat`, { body });
215
+ }
216
+
208
217
  // --- Auth ------------------------------------------------------------------
209
218
 
210
219
  async function getApiKey() {
@@ -245,6 +254,7 @@ export function createClient(config) {
245
254
  pushFile,
246
255
  syncManifest,
247
256
  createRoutine,
257
+ heartbeat,
248
258
  getApiKey,
249
259
  healthCheck,
250
260
  };