@contextstream/mcp-server 0.3.47 → 0.3.49

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
@@ -69,6 +69,16 @@ npm install -g @contextstream/mcp-server
69
69
  contextstream-mcp
70
70
  ```
71
71
 
72
+ ### Keeping updated
73
+
74
+ To get the latest features and bug fixes, update periodically:
75
+
76
+ ```bash
77
+ npm update -g @contextstream/mcp-server
78
+ ```
79
+
80
+ The MCP server will warn you when a newer version is available. After updating, restart your AI tool to use the new version.
81
+
72
82
  ## Configure your MCP client
73
83
 
74
84
  ### Manual setup
package/dist/index.js CHANGED
@@ -4698,6 +4698,9 @@ var globalCache = new MemoryCache();
4698
4698
 
4699
4699
  // src/version.ts
4700
4700
  import { createRequire } from "module";
4701
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
4702
+ import { homedir } from "os";
4703
+ import { join as join3 } from "path";
4701
4704
  function getVersion() {
4702
4705
  try {
4703
4706
  const require2 = createRequire(import.meta.url);
@@ -4709,6 +4712,86 @@ function getVersion() {
4709
4712
  return "unknown";
4710
4713
  }
4711
4714
  var VERSION = getVersion();
4715
+ function compareVersions(v1, v2) {
4716
+ const parts1 = v1.split(".").map(Number);
4717
+ const parts2 = v2.split(".").map(Number);
4718
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
4719
+ const p1 = parts1[i] ?? 0;
4720
+ const p2 = parts2[i] ?? 0;
4721
+ if (p1 < p2) return -1;
4722
+ if (p1 > p2) return 1;
4723
+ }
4724
+ return 0;
4725
+ }
4726
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
4727
+ function getCacheFilePath() {
4728
+ return join3(homedir(), ".contextstream", "version-cache.json");
4729
+ }
4730
+ function readCache() {
4731
+ try {
4732
+ const cacheFile = getCacheFilePath();
4733
+ if (!existsSync2(cacheFile)) return null;
4734
+ const data = JSON.parse(readFileSync2(cacheFile, "utf-8"));
4735
+ if (Date.now() - data.checkedAt > CACHE_TTL_MS) return null;
4736
+ return data;
4737
+ } catch {
4738
+ return null;
4739
+ }
4740
+ }
4741
+ function writeCache(latestVersion) {
4742
+ try {
4743
+ const configDir = join3(homedir(), ".contextstream");
4744
+ if (!existsSync2(configDir)) {
4745
+ mkdirSync2(configDir, { recursive: true });
4746
+ }
4747
+ const cacheFile = getCacheFilePath();
4748
+ writeFileSync2(cacheFile, JSON.stringify({
4749
+ latestVersion,
4750
+ checkedAt: Date.now()
4751
+ }));
4752
+ } catch {
4753
+ }
4754
+ }
4755
+ async function checkForUpdates() {
4756
+ const currentVersion = VERSION;
4757
+ if (currentVersion === "unknown") return;
4758
+ try {
4759
+ const cached = readCache();
4760
+ if (cached) {
4761
+ if (compareVersions(currentVersion, cached.latestVersion) < 0) {
4762
+ showUpdateWarning(currentVersion, cached.latestVersion);
4763
+ }
4764
+ return;
4765
+ }
4766
+ const controller = new AbortController();
4767
+ const timeout = setTimeout(() => controller.abort(), 5e3);
4768
+ const response = await fetch("https://registry.npmjs.org/@contextstream/mcp-server/latest", {
4769
+ signal: controller.signal,
4770
+ headers: { "Accept": "application/json" }
4771
+ });
4772
+ clearTimeout(timeout);
4773
+ if (!response.ok) return;
4774
+ const data = await response.json();
4775
+ const latestVersion = data.version;
4776
+ if (typeof latestVersion !== "string") return;
4777
+ writeCache(latestVersion);
4778
+ if (compareVersions(currentVersion, latestVersion) < 0) {
4779
+ showUpdateWarning(currentVersion, latestVersion);
4780
+ }
4781
+ } catch {
4782
+ }
4783
+ }
4784
+ function showUpdateWarning(currentVersion, latestVersion) {
4785
+ console.error("");
4786
+ console.error("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
4787
+ console.error(`\u26A0\uFE0F Update available: v${currentVersion} \u2192 v${latestVersion}`);
4788
+ console.error("");
4789
+ console.error(" Run: npm update -g @contextstream/mcp-server");
4790
+ console.error("");
4791
+ console.error(" Then restart your AI tool to use the new version.");
4792
+ console.error("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
4793
+ console.error("");
4794
+ }
4712
4795
 
4713
4796
  // src/client.ts
4714
4797
  var uuidSchema = external_exports.string().uuid();
@@ -7594,7 +7677,48 @@ function getCoreToolsHint() {
7594
7677
  // src/tools.ts
7595
7678
  var LESSON_DEDUP_WINDOW_MS = 2 * 60 * 1e3;
7596
7679
  var recentLessonCaptures = /* @__PURE__ */ new Map();
7597
- var CORE_TOOLSET = /* @__PURE__ */ new Set([
7680
+ var LIGHT_TOOLSET = /* @__PURE__ */ new Set([
7681
+ // Core session tools (13)
7682
+ "session_init",
7683
+ "session_tools",
7684
+ "context_smart",
7685
+ "session_summary",
7686
+ "session_capture",
7687
+ "session_capture_lesson",
7688
+ "session_get_lessons",
7689
+ "session_recall",
7690
+ "session_remember",
7691
+ "session_get_user_context",
7692
+ "session_smart_search",
7693
+ "session_compress",
7694
+ "session_delta",
7695
+ // Setup and configuration (3)
7696
+ "generate_editor_rules",
7697
+ "workspace_associate",
7698
+ "workspace_bootstrap",
7699
+ // Project management (5)
7700
+ "projects_create",
7701
+ "projects_list",
7702
+ "projects_get",
7703
+ "projects_overview",
7704
+ "projects_statistics",
7705
+ // Project indexing (4)
7706
+ "projects_ingest_local",
7707
+ "projects_index",
7708
+ "projects_index_status",
7709
+ "projects_files",
7710
+ // Memory basics (2)
7711
+ "memory_search",
7712
+ "memory_decisions",
7713
+ // Graph basics (2)
7714
+ "graph_related",
7715
+ "graph_decisions",
7716
+ // Utility (2)
7717
+ "auth_me",
7718
+ "mcp_server_version"
7719
+ ]);
7720
+ var STANDARD_TOOLSET = /* @__PURE__ */ new Set([
7721
+ // Core session tools (13)
7598
7722
  "session_init",
7599
7723
  "session_tools",
7600
7724
  "context_smart",
@@ -7608,18 +7732,64 @@ var CORE_TOOLSET = /* @__PURE__ */ new Set([
7608
7732
  "session_smart_search",
7609
7733
  "session_compress",
7610
7734
  "session_delta",
7735
+ // Setup and configuration (3)
7611
7736
  "generate_editor_rules",
7612
7737
  "workspace_associate",
7613
7738
  "workspace_bootstrap",
7739
+ // Workspace management (2)
7740
+ "workspaces_list",
7741
+ "workspaces_get",
7742
+ // Project management (6)
7614
7743
  "projects_create",
7615
7744
  "projects_list",
7745
+ "projects_get",
7746
+ "projects_overview",
7747
+ "projects_statistics",
7748
+ "projects_update",
7749
+ // Project indexing (4)
7750
+ "projects_ingest_local",
7751
+ "projects_index",
7752
+ "projects_index_status",
7753
+ "projects_files",
7754
+ // Memory events (6)
7755
+ "memory_search",
7756
+ "memory_decisions",
7757
+ "memory_create_event",
7758
+ "memory_list_events",
7759
+ "memory_timeline",
7760
+ "memory_summary",
7761
+ // Memory nodes (2)
7762
+ "memory_create_node",
7763
+ "memory_list_nodes",
7764
+ // Knowledge graph analysis (8)
7765
+ "graph_related",
7766
+ "graph_decisions",
7767
+ "graph_path",
7768
+ "graph_dependencies",
7769
+ "graph_call_path",
7770
+ "graph_impact",
7771
+ "graph_circular_dependencies",
7772
+ "graph_unused_code",
7773
+ // Search (3)
7774
+ "search_semantic",
7775
+ "search_hybrid",
7776
+ "search_keyword",
7777
+ // Utility (2)
7616
7778
  "auth_me",
7617
7779
  "mcp_server_version"
7618
7780
  ]);
7619
7781
  var TOOLSET_ALIASES = {
7620
- core: CORE_TOOLSET,
7621
- minimal: CORE_TOOLSET,
7622
- essential: CORE_TOOLSET
7782
+ // Light mode - minimal, fastest
7783
+ light: LIGHT_TOOLSET,
7784
+ minimal: LIGHT_TOOLSET,
7785
+ // Standard mode - balanced (default)
7786
+ standard: STANDARD_TOOLSET,
7787
+ core: STANDARD_TOOLSET,
7788
+ essential: STANDARD_TOOLSET,
7789
+ // Complete mode - all tools
7790
+ complete: null,
7791
+ full: null,
7792
+ all: null
7623
7793
  };
7624
7794
  function parseToolList(raw) {
7625
7795
  return new Set(
@@ -7627,30 +7797,29 @@ function parseToolList(raw) {
7627
7797
  );
7628
7798
  }
7629
7799
  function resolveToolFilter() {
7630
- const defaultToolset = CORE_TOOLSET;
7631
7800
  const allowlistRaw = process.env.CONTEXTSTREAM_TOOL_ALLOWLIST;
7632
7801
  if (allowlistRaw) {
7633
7802
  const allowlist = parseToolList(allowlistRaw);
7634
7803
  if (allowlist.size === 0) {
7635
- console.error("[ContextStream] CONTEXTSTREAM_TOOL_ALLOWLIST is empty; using core tool list.");
7636
- return { allowlist: defaultToolset, source: "core" };
7804
+ console.error("[ContextStream] CONTEXTSTREAM_TOOL_ALLOWLIST is empty; using standard toolset.");
7805
+ return { allowlist: STANDARD_TOOLSET, source: "standard" };
7637
7806
  }
7638
7807
  return { allowlist, source: "allowlist" };
7639
7808
  }
7640
7809
  const toolsetRaw = process.env.CONTEXTSTREAM_TOOLSET;
7641
7810
  if (!toolsetRaw) {
7642
- return { allowlist: defaultToolset, source: "core" };
7811
+ return { allowlist: STANDARD_TOOLSET, source: "standard" };
7643
7812
  }
7644
7813
  const key = toolsetRaw.trim().toLowerCase();
7645
- if (!key || key === "full" || key === "all") {
7646
- return { allowlist: null, source: "full" };
7647
- }
7648
- const resolved = TOOLSET_ALIASES[key];
7649
- if (resolved) {
7814
+ if (key in TOOLSET_ALIASES) {
7815
+ const resolved = TOOLSET_ALIASES[key];
7816
+ if (resolved === null) {
7817
+ return { allowlist: null, source: "complete" };
7818
+ }
7650
7819
  return { allowlist: resolved, source: key };
7651
7820
  }
7652
- console.error(`[ContextStream] Unknown CONTEXTSTREAM_TOOLSET "${toolsetRaw}". Using core tool list.`);
7653
- return { allowlist: defaultToolset, source: "core" };
7821
+ console.error(`[ContextStream] Unknown CONTEXTSTREAM_TOOLSET "${toolsetRaw}". Using standard toolset.`);
7822
+ return { allowlist: STANDARD_TOOLSET, source: "standard" };
7654
7823
  }
7655
7824
  function formatContent(data) {
7656
7825
  return JSON.stringify(data, null, 2);
@@ -7695,9 +7864,11 @@ function registerTools(server, client, sessionManager) {
7695
7864
  const toolFilter = resolveToolFilter();
7696
7865
  const toolAllowlist = toolFilter.allowlist;
7697
7866
  if (toolAllowlist) {
7698
- const source = toolFilter.source ?? "custom";
7699
- const hint = source === "core" ? " Set CONTEXTSTREAM_TOOLSET=full to expose all tools." : "";
7700
- console.error(`[ContextStream] Toolset limited (${source}): ${toolAllowlist.size} tools.${hint}`);
7867
+ const source = toolFilter.source;
7868
+ const hint = source === "light" ? " Set CONTEXTSTREAM_TOOLSET=standard or complete for more tools." : source === "standard" ? " Set CONTEXTSTREAM_TOOLSET=complete for all tools." : "";
7869
+ console.error(`[ContextStream] Toolset: ${source} (${toolAllowlist.size} tools).${hint}`);
7870
+ } else {
7871
+ console.error(`[ContextStream] Toolset: complete (all tools).`);
7701
7872
  }
7702
7873
  const defaultProTools = /* @__PURE__ */ new Set([
7703
7874
  // AI endpoints (typically paid/credit-metered)
@@ -10770,26 +10941,26 @@ var SessionManager = class {
10770
10941
  };
10771
10942
 
10772
10943
  // src/index.ts
10773
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
10774
- import { homedir as homedir3 } from "os";
10775
- import { join as join7 } from "path";
10944
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
10945
+ import { homedir as homedir4 } from "os";
10946
+ import { join as join8 } from "path";
10776
10947
 
10777
10948
  // src/setup.ts
10778
10949
  import * as fs5 from "node:fs/promises";
10779
10950
  import * as path6 from "node:path";
10780
- import { homedir as homedir2 } from "node:os";
10951
+ import { homedir as homedir3 } from "node:os";
10781
10952
  import { stdin, stdout } from "node:process";
10782
10953
  import { createInterface } from "node:readline/promises";
10783
10954
 
10784
10955
  // src/credentials.ts
10785
10956
  import * as fs4 from "node:fs/promises";
10786
10957
  import * as path5 from "node:path";
10787
- import { homedir } from "node:os";
10958
+ import { homedir as homedir2 } from "node:os";
10788
10959
  function normalizeApiUrl(input) {
10789
10960
  return String(input ?? "").trim().replace(/\/+$/, "");
10790
10961
  }
10791
10962
  function credentialsFilePath() {
10792
- return path5.join(homedir(), ".contextstream", "credentials.json");
10963
+ return path5.join(homedir2(), ".contextstream", "credentials.json");
10793
10964
  }
10794
10965
  function isRecord(value) {
10795
10966
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -10887,21 +11058,42 @@ async function fileExists(filePath) {
10887
11058
  return false;
10888
11059
  }
10889
11060
  }
10890
- async function upsertTextFile(filePath, content, marker) {
11061
+ var CONTEXTSTREAM_START_MARKER = "<!-- BEGIN ContextStream -->";
11062
+ var CONTEXTSTREAM_END_MARKER = "<!-- END ContextStream -->";
11063
+ function wrapWithMarkers(content) {
11064
+ return `${CONTEXTSTREAM_START_MARKER}
11065
+ ${content.trim()}
11066
+ ${CONTEXTSTREAM_END_MARKER}`;
11067
+ }
11068
+ async function upsertTextFile(filePath, content, _marker) {
10891
11069
  await fs5.mkdir(path6.dirname(filePath), { recursive: true });
10892
11070
  const exists = await fileExists(filePath);
11071
+ const wrappedContent = wrapWithMarkers(content);
10893
11072
  if (!exists) {
10894
- await fs5.writeFile(filePath, content, "utf8");
11073
+ await fs5.writeFile(filePath, wrappedContent + "\n", "utf8");
10895
11074
  return "created";
10896
11075
  }
10897
11076
  const existing = await fs5.readFile(filePath, "utf8").catch(() => "");
10898
- if (existing.includes(marker)) return "skipped";
10899
- const joined = existing.trimEnd() + "\n\n" + content.trim() + "\n";
11077
+ const startIdx = existing.indexOf(CONTEXTSTREAM_START_MARKER);
11078
+ const endIdx = existing.indexOf(CONTEXTSTREAM_END_MARKER);
11079
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
11080
+ const before = existing.substring(0, startIdx);
11081
+ const after = existing.substring(endIdx + CONTEXTSTREAM_END_MARKER.length);
11082
+ const updated = before.trimEnd() + "\n\n" + wrappedContent + "\n" + after.trimStart();
11083
+ await fs5.writeFile(filePath, updated.trim() + "\n", "utf8");
11084
+ return "updated";
11085
+ }
11086
+ if (existing.includes("ContextStream")) {
11087
+ const joined2 = existing.trimEnd() + "\n\n" + wrappedContent + "\n";
11088
+ await fs5.writeFile(filePath, joined2, "utf8");
11089
+ return "updated";
11090
+ }
11091
+ const joined = existing.trimEnd() + "\n\n" + wrappedContent + "\n";
10900
11092
  await fs5.writeFile(filePath, joined, "utf8");
10901
11093
  return "appended";
10902
11094
  }
10903
11095
  function globalRulesPathForEditor(editor) {
10904
- const home = homedir2();
11096
+ const home = homedir3();
10905
11097
  switch (editor) {
10906
11098
  case "codex":
10907
11099
  return path6.join(home, ".codex", "AGENTS.md");
@@ -11009,7 +11201,7 @@ async function upsertJsonVsCodeMcpConfig(filePath, server) {
11009
11201
  return before === after ? "skipped" : "updated";
11010
11202
  }
11011
11203
  function claudeDesktopConfigPath() {
11012
- const home = homedir2();
11204
+ const home = homedir3();
11013
11205
  if (process.platform === "darwin") {
11014
11206
  return path6.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
11015
11207
  }
@@ -11307,16 +11499,16 @@ Created API key: ${maskApiKey(apiKey)}
11307
11499
  const modeChoice = normalizeInput(await rl.question("Choose [1/2] (default 1): ")) || "1";
11308
11500
  const mode = modeChoice === "2" ? "full" : "minimal";
11309
11501
  console.log("\nMCP toolset (which tools to expose to the AI):");
11310
- console.log(" 1) Core (recommended) \u2014 essential session/context tools (~17 tools, lower token overhead)");
11311
- console.log(" Best for: most users, Claude Code, Claude Desktop (avoids large-context warnings)");
11312
- console.log(" 2) Full \u2014 all tools including workspaces, projects, search, memory, graph, AI, integrations (~86 tools)");
11313
- console.log(" Best for: power users needing direct access to all workspace/project/graph/AI tools");
11314
- console.log(" Note: Claude Code/Desktop may warn about large tool lists when using full toolset.");
11502
+ console.log(" 1) Light \u2014 core session, project, and basic memory/graph tools (~30 tools)");
11503
+ console.log(" Best for: faster responses, simpler workflows, resource-constrained environments");
11504
+ console.log(" 2) Standard (recommended) \u2014 adds workspace, memory CRUD, graph analysis, search (~50 tools)");
11505
+ console.log(" Best for: most users, full development workflow with memory and code analysis");
11506
+ console.log(" 3) Complete \u2014 all tools including AI, GitHub, Slack integrations (~86 tools)");
11507
+ console.log(" Best for: power users needing integrations and advanced features");
11315
11508
  console.log("");
11316
- console.log(" Tip: You can switch toolsets later by editing the MCP config and setting CONTEXTSTREAM_TOOLSET=full");
11317
- console.log(" See https://contextstream.io/docs/mcp/tools for the full tool catalog.");
11318
- const toolsetChoice = normalizeInput(await rl.question("Choose [1/2] (default 1): ")) || "1";
11319
- const toolset = toolsetChoice === "2" ? "full" : "core";
11509
+ console.log(" Tip: Change later by setting CONTEXTSTREAM_TOOLSET=light|standard|complete");
11510
+ const toolsetChoice = normalizeInput(await rl.question("Choose [1/2/3] (default 2): ")) || "2";
11511
+ const toolset = toolsetChoice === "1" ? "light" : toolsetChoice === "3" ? "complete" : "standard";
11320
11512
  const editors = ["codex", "claude", "cursor", "windsurf", "cline", "kilo", "roo", "aider"];
11321
11513
  console.log('\nSelect editors to configure (comma-separated numbers, or "all"):');
11322
11514
  editors.forEach((e, i) => console.log(` ${i + 1}) ${EDITOR_LABELS[e]}`));
@@ -11347,9 +11539,9 @@ Created API key: ${maskApiKey(apiKey)}
11347
11539
  const mcpChoiceDefault = hasCodex && !hasProjectMcpEditors ? "1" : "3";
11348
11540
  const mcpChoice = normalizeInput(await rl.question(`Choose [${hasCodex && !hasProjectMcpEditors ? "1/2" : "1/2/3/4"}] (default ${mcpChoiceDefault}): `)) || mcpChoiceDefault;
11349
11541
  const mcpScope = mcpChoice === "2" && hasCodex && !hasProjectMcpEditors ? "skip" : mcpChoice === "4" ? "skip" : mcpChoice === "1" ? "global" : mcpChoice === "2" ? "project" : "both";
11350
- const mcpServer = toolset === "full" ? buildContextStreamMcpServer({ apiUrl, apiKey, toolset: "full" }) : buildContextStreamMcpServer({ apiUrl, apiKey });
11542
+ const mcpServer = toolset === "complete" ? buildContextStreamMcpServer({ apiUrl, apiKey, toolset: "complete" }) : buildContextStreamMcpServer({ apiUrl, apiKey });
11351
11543
  const mcpServerClaude = buildContextStreamMcpServer({ apiUrl, apiKey, toolset });
11352
- const vsCodeServer = toolset === "full" ? buildContextStreamVsCodeServer({ apiUrl, apiKey, toolset: "full" }) : buildContextStreamVsCodeServer({ apiUrl, apiKey });
11544
+ const vsCodeServer = toolset === "complete" ? buildContextStreamVsCodeServer({ apiUrl, apiKey, toolset: "complete" }) : buildContextStreamVsCodeServer({ apiUrl, apiKey });
11353
11545
  const needsGlobalMcpConfig = mcpScope === "global" || mcpScope === "both" || mcpScope === "project" && hasCodex;
11354
11546
  if (needsGlobalMcpConfig) {
11355
11547
  console.log("\nInstalling global MCP config...");
@@ -11357,20 +11549,20 @@ Created API key: ${maskApiKey(apiKey)}
11357
11549
  if (mcpScope === "project" && editor !== "codex") continue;
11358
11550
  try {
11359
11551
  if (editor === "codex") {
11360
- const filePath = path6.join(homedir2(), ".codex", "config.toml");
11552
+ const filePath = path6.join(homedir3(), ".codex", "config.toml");
11361
11553
  if (dryRun) {
11362
11554
  writeActions.push({ kind: "mcp-config", target: filePath, status: "dry-run" });
11363
11555
  console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
11364
11556
  continue;
11365
11557
  }
11366
- const codexParams = toolset === "full" ? { apiUrl, apiKey, toolset: "full" } : { apiUrl, apiKey };
11558
+ const codexParams = toolset === "complete" ? { apiUrl, apiKey, toolset: "complete" } : { apiUrl, apiKey };
11367
11559
  const status = await upsertCodexTomlConfig(filePath, codexParams);
11368
11560
  writeActions.push({ kind: "mcp-config", target: filePath, status });
11369
11561
  console.log(`- ${EDITOR_LABELS[editor]}: ${status} ${filePath}`);
11370
11562
  continue;
11371
11563
  }
11372
11564
  if (editor === "windsurf") {
11373
- const filePath = path6.join(homedir2(), ".codeium", "windsurf", "mcp_config.json");
11565
+ const filePath = path6.join(homedir3(), ".codeium", "windsurf", "mcp_config.json");
11374
11566
  if (dryRun) {
11375
11567
  writeActions.push({ kind: "mcp-config", target: filePath, status: "dry-run" });
11376
11568
  console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
@@ -11402,7 +11594,7 @@ Created API key: ${maskApiKey(apiKey)}
11402
11594
  continue;
11403
11595
  }
11404
11596
  if (editor === "cursor") {
11405
- const filePath = path6.join(homedir2(), ".cursor", "mcp.json");
11597
+ const filePath = path6.join(homedir3(), ".cursor", "mcp.json");
11406
11598
  if (dryRun) {
11407
11599
  writeActions.push({ kind: "mcp-config", target: filePath, status: "dry-run" });
11408
11600
  console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
@@ -11600,14 +11792,15 @@ Applying to ${projects.length} project(s)...`);
11600
11792
  const skipped = writeActions.filter((a) => a.status === "skipped").length;
11601
11793
  const dry = writeActions.filter((a) => a.status === "dry-run").length;
11602
11794
  console.log(`Summary: ${created} created, ${updated} updated, ${appended} appended, ${skipped} skipped, ${dry} dry-run.`);
11603
- console.log(`Toolset: ${toolset} (${toolset === "full" ? "~86 tools" : "~17 core tools"})`);
11795
+ const toolsetDesc = toolset === "light" ? "~30 tools" : toolset === "complete" ? "~86 tools" : "~50 tools";
11796
+ console.log(`Toolset: ${toolset} (${toolsetDesc})`);
11604
11797
  }
11605
11798
  console.log("\nNext steps:");
11606
11799
  console.log("- Restart your editor/CLI after changing MCP config or rules.");
11607
11800
  console.log("- Prefer ContextStream search first: use session_smart_search (or mcp__contextstream__session_smart_search) before raw repo scans (rg/ls/find).");
11608
11801
  console.log("- If any tools require UI-based MCP setup (e.g. Cline/Kilo/Roo global), follow https://contextstream.io/docs/mcp.");
11609
- if (toolset === "full") {
11610
- console.log("- Note: Claude Code/Desktop may warn about large tool contexts. This is expected with the full toolset.");
11802
+ if (toolset === "complete") {
11803
+ console.log("- Note: Claude Code/Desktop may warn about large tool contexts. This is expected with the complete toolset.");
11611
11804
  }
11612
11805
  } finally {
11613
11806
  rl.close();
@@ -11616,14 +11809,14 @@ Applying to ${projects.length} project(s)...`);
11616
11809
 
11617
11810
  // src/index.ts
11618
11811
  function showFirstRunMessage() {
11619
- const configDir = join7(homedir3(), ".contextstream");
11620
- const starShownFile = join7(configDir, ".star-shown");
11621
- if (existsSync3(starShownFile)) {
11812
+ const configDir = join8(homedir4(), ".contextstream");
11813
+ const starShownFile = join8(configDir, ".star-shown");
11814
+ if (existsSync4(starShownFile)) {
11622
11815
  return;
11623
11816
  }
11624
- if (!existsSync3(configDir)) {
11817
+ if (!existsSync4(configDir)) {
11625
11818
  try {
11626
- mkdirSync3(configDir, { recursive: true });
11819
+ mkdirSync4(configDir, { recursive: true });
11627
11820
  } catch {
11628
11821
  return;
11629
11822
  }
@@ -11636,7 +11829,7 @@ function showFirstRunMessage() {
11636
11829
  console.error("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
11637
11830
  console.error("");
11638
11831
  try {
11639
- writeFileSync3(starShownFile, (/* @__PURE__ */ new Date()).toISOString());
11832
+ writeFileSync4(starShownFile, (/* @__PURE__ */ new Date()).toISOString());
11640
11833
  } catch {
11641
11834
  }
11642
11835
  }
@@ -11657,7 +11850,7 @@ Environment variables:
11657
11850
  CONTEXTSTREAM_JWT JWT for authentication (alternative to API key)
11658
11851
  CONTEXTSTREAM_WORKSPACE_ID Optional default workspace ID
11659
11852
  CONTEXTSTREAM_PROJECT_ID Optional default project ID
11660
- CONTEXTSTREAM_TOOLSET Optional tool bundle (core|full). Defaults to core to reduce tool context size.
11853
+ CONTEXTSTREAM_TOOLSET Tool mode: light|standard|complete (default: standard)
11661
11854
  CONTEXTSTREAM_TOOL_ALLOWLIST Optional comma-separated tool names to expose (overrides toolset)
11662
11855
  CONTEXTSTREAM_PRO_TOOLS Optional comma-separated PRO tool names (default: AI tools)
11663
11856
  CONTEXTSTREAM_UPGRADE_URL Optional upgrade URL shown for PRO tools on Free plan
@@ -11706,6 +11899,8 @@ async function main() {
11706
11899
  await server.connect(transport);
11707
11900
  console.error("ContextStream MCP server connected and ready");
11708
11901
  showFirstRunMessage();
11902
+ checkForUpdates().catch(() => {
11903
+ });
11709
11904
  }
11710
11905
  main().catch((err) => {
11711
11906
  console.error("ContextStream MCP server failed to start:", err?.message || err);
@@ -4093,6 +4093,7 @@ function getVersion() {
4093
4093
  return "unknown";
4094
4094
  }
4095
4095
  var VERSION = getVersion();
4096
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
4096
4097
 
4097
4098
  // src/test-server.ts
4098
4099
  var PORT = parseInt(process.env.MCP_TEST_PORT || "3099", 10);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contextstream/mcp-server",
3
- "version": "0.3.47",
3
+ "version": "0.3.49",
4
4
  "description": "MCP server exposing ContextStream public API - code context, memory, search, and AI tools for developers",
5
5
  "type": "module",
6
6
  "license": "MIT",