@tacitai/mcp-server 0.6.1 → 0.6.3

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 -19
  2. package/package.json +1 -1
package/dist/setup.js CHANGED
@@ -425,7 +425,7 @@ async function runSmoke(apiUrl, token) {
425
425
  export async function setup(argv) {
426
426
  const opts = parseArgs(argv);
427
427
  // Resolve api-url: flag > env > default.
428
- const apiUrl = opts.apiUrl ?? process.env['TACIT_API_URL'] ?? 'https://beta.tacitai.app';
428
+ const apiUrl = opts.apiUrl ?? process.env['TACIT_API_URL'] ?? 'https://api-beta.tacitai.app';
429
429
  // Determine profile and token.
430
430
  let profile = opts.profile;
431
431
  let token = opts.token;
@@ -463,42 +463,60 @@ export async function setup(argv) {
463
463
  // fall back to env-var placeholder when the token came from the environment.
464
464
  const resolvedToken = token ?? null;
465
465
  const profileEntry = buildProfileEntry(apiUrl, envVarName, resolvedToken);
466
- const existing = readExistingConfig();
467
- const merged = mergeConfig(existing, profile, profileEntry);
468
- const output = configToBytes(merged);
469
466
  // D10: emit confirmation string BEFORE writing (also printed in dry-run).
470
- process.stdout.write(`Writing tacit entry to ~/.claude/mcp.json (profile: ${profile})...\n`);
467
+ process.stdout.write(`\n Registering MCP server "${profile}" with Claude Code...\n`);
471
468
  if (opts.dryRun) {
472
- // Redact any literal token in dry-run preview to avoid leaking secrets to stdout.
473
- const redacted = resolvedToken
474
- ? configToBytes(mergeConfig(existing, profile, buildProfileEntry(apiUrl, envVarName, null)))
475
- : output;
476
- process.stdout.write('(dry-run) Would write:\n');
477
- process.stdout.write(redacted);
469
+ process.stdout.write(' (dry-run) Would register:\n');
470
+ const redactedEntry = buildProfileEntry(apiUrl, envVarName, null);
471
+ process.stdout.write(` ${JSON.stringify(redactedEntry, null, 2)}\n`);
478
472
  process.exit(0);
479
473
  return;
480
474
  }
481
- // Create ~/.claude with mode 0700 if absent.
475
+ // Register via `claude mcp add-json` — the only way Claude Code discovers MCP servers.
476
+ // Writing ~/.claude/mcp.json directly does NOT work (Claude Code ignores that file).
477
+ const jsonConfig = JSON.stringify(profileEntry);
478
+ const registered = await new Promise((resolve) => {
479
+ execFile('claude', ['mcp', 'add-json', '--scope', 'user', profile, jsonConfig], {
480
+ timeout: 15_000,
481
+ }, (err, stdout, stderr) => {
482
+ if (err) {
483
+ process.stderr.write(`\n Warning: could not register via "claude mcp add-json".\n`);
484
+ process.stderr.write(` ${stderr || err.message}\n`);
485
+ resolve(false);
486
+ }
487
+ else {
488
+ resolve(true);
489
+ }
490
+ });
491
+ });
492
+ // Fallback: also write ~/.claude/mcp.json for environments without `claude` CLI.
482
493
  const dir = claudeDir();
483
494
  if (!fs.existsSync(dir)) {
484
495
  fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
485
496
  }
497
+ const existing = readExistingConfig();
498
+ const merged = mergeConfig(existing, profile, profileEntry);
499
+ const output = configToBytes(merged);
486
500
  const dest = mcpJsonPath();
487
501
  fs.writeFileSync(dest, output, { encoding: 'utf-8', mode: 0o600 });
488
- // Ensure 0600 even when the file pre-existed with looser permissions.
489
502
  fs.chmodSync(dest, 0o600);
490
503
  // AC-12: write ~/.tacit/profiles/<profile>.json metadata (token NOT included).
491
504
  if (expiresAt) {
492
505
  writeProfileMetadata(profile, expiresAt, apiUrl);
493
506
  }
494
- if (resolvedToken) {
495
- process.stdout.write(`\nSetup complete. Your token has been saved to ~/.claude/mcp.json.\n` +
496
- `Start a new Claude Code session to connect.\n`);
507
+ if (registered) {
508
+ process.stdout.write(`\n Done! Start a new Claude Code session to connect.\n`);
509
+ }
510
+ else if (resolvedToken) {
511
+ process.stdout.write(`\n Config written to ~/.claude/mcp.json (fallback).\n` +
512
+ ` If Claude Code doesn't pick it up, run:\n` +
513
+ ` claude mcp add-json --scope user ${profile} '${jsonConfig}'\n` +
514
+ ` Then start a new Claude Code session.\n`);
497
515
  }
498
516
  else {
499
- process.stdout.write(`\nSetup complete. Add this to your shell profile:\n` +
500
- ` export ${envVarName}=<your-token>\n` +
501
- `\nThen start a new Claude Code session to connect.\n`);
517
+ process.stdout.write(`\n Setup complete. Add this to your shell profile:\n` +
518
+ ` export ${envVarName}=<your-token>\n` +
519
+ `\n Then start a new Claude Code session to connect.\n`);
502
520
  }
503
521
  if (opts.smoke) {
504
522
  await runSmoke(apiUrl, token);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tacitai/mcp-server",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "stdio MCP server wrapping Tacit /api/v1 REST/SSE API",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,