@contextstream/mcp-server 0.4.26 → 0.4.28

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 (3) hide show
  1. package/README.md +13 -4
  2. package/dist/index.js +84 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,10 +1,19 @@
1
1
  # ContextStream MCP Server
2
2
 
3
- Persistent memory, semantic search, and code intelligence for any MCP-compatible AI tool (Cursor, Claude Code, Windsurf, VS Code, Claude Desktop, Codex CLI, etc.).
3
+ **Get set up in 30 seconds (recommended):**
4
4
 
5
- ContextStream is a shared "brain" for AI-assisted development. It stores decisions, preferences, lessons, tasks, and project context — and lets your AI tools search and analyze your codebase with consistent context across sessions.
5
+ ```bash
6
+ npx -y @contextstream/mcp-server setup
7
+ ```
8
+
9
+ This wizard authenticates you, creates/stores an API key, installs editor rules, and writes MCP config files.
10
+
11
+ Persistent memory, semantic search, and code intelligence for any MCP-compatible AI tool (Cursor, Claude Code, Windsurf, VS Code, Claude Desktop, Codex CLI, etc.).
6
12
 
7
- **v0.4.x:** Consolidated domain tools (~11 tools) for **~75% lower tool-registry token overhead** vs previous versions.
13
+ **At a glance:**
14
+ - Shared "brain" for decisions, preferences, notes (including implementation notes), lessons, tasks, and project context.
15
+ - Search + analysis across sessions with consistent context (semantic/hybrid/keyword + graph tools).
16
+ - v0.4.x consolidated domain tools (~11 tools) for ~75% lower tool-registry token overhead vs previous versions.
8
17
 
9
18
  ---
10
19
 
@@ -45,7 +54,7 @@ MCP clients often inject the tool catalog into the model context. v0.4.x is desi
45
54
 
46
55
  - **Consolidated domain tools** (v0.4.x): short tool list with action/mode dispatch
47
56
  - Session-aware context loading (`session_init`, `context_smart`)
48
- - Memory capture + recall (decisions, preferences, lessons, tasks, bugs)
57
+ - Memory capture + recall (decisions, preferences, notes, implementation notes, lessons, tasks, bugs)
49
58
  - Code search (semantic, hybrid, keyword, pattern)
50
59
  - Knowledge graph + code analysis (dependencies, impact, call paths, circular deps, unused code)
51
60
  - Graph ingestion for full graph builds (`graph(action="ingest")`)
package/dist/index.js CHANGED
@@ -5191,6 +5191,21 @@ var ContextStreamClient = class {
5191
5191
  }
5192
5192
  });
5193
5193
  }
5194
+ /**
5195
+ * Refactor search optimized for find-replace operations.
5196
+ * Uses word-boundary matching for precise symbol renaming.
5197
+ * Returns matches grouped by file with line/col positions.
5198
+ */
5199
+ searchRefactor(body) {
5200
+ return request(this.config, "/search/refactor", {
5201
+ body: {
5202
+ ...this.withDefaults(body),
5203
+ search_type: "refactor",
5204
+ output_format: body.output_format,
5205
+ filters: body.workspace_id ? {} : { file_types: [], languages: [], file_paths: [], exclude_paths: [], content_types: [], tags: [] }
5206
+ }
5207
+ });
5208
+ }
5194
5209
  // Memory / Knowledge
5195
5210
  createMemoryEvent(body) {
5196
5211
  const withDefaults = this.withDefaults(body);
@@ -6241,6 +6256,8 @@ var ContextStreamClient = class {
6241
6256
  case "decision":
6242
6257
  case "insight":
6243
6258
  case "preference":
6259
+ case "note":
6260
+ case "implementation":
6244
6261
  apiEventType = "manual_note";
6245
6262
  tags.push(params.event_type);
6246
6263
  break;
@@ -7781,6 +7798,16 @@ function applyMcpToolPrefix(markdown, toolPrefix) {
7781
7798
  return markdown.replace(toolRegex, `${toolPrefix}$1`);
7782
7799
  }
7783
7800
  var CONTEXTSTREAM_RULES_FULL = `
7801
+ ## \u{1F6A8} CRITICAL RULE - READ EVERY TURN \u{1F6A8}
7802
+
7803
+ **BEFORE using Glob, Grep, Search, Read (for discovery), or Explore:**
7804
+ \`\`\`
7805
+ STOP \u2192 Call search(mode="hybrid", query="...") FIRST
7806
+ \`\`\`
7807
+ Only use local tools if ContextStream returns 0 results. This applies to EVERY search throughout the ENTIRE conversation, not just the first message.
7808
+
7809
+ ---
7810
+
7784
7811
  ## ContextStream v0.4.x Integration (Enhanced)
7785
7812
 
7786
7813
  You have access to ContextStream MCP tools for persistent memory and context.
@@ -7793,6 +7820,7 @@ Rules Version: ${RULES_VERSION}
7793
7820
  |---------|--------------|
7794
7821
  | **1st message** | \`session_init(folder_path="...", context_hint="<user's message>")\`, then \`context_smart(user_message="<user's message>", format="minified", max_tokens=400)\` |
7795
7822
  | **2nd+ messages** | \`context_smart(user_message="<user's message>", format="minified", max_tokens=400)\` |
7823
+ | **\u{1F50D} ANY code search** | \`search(mode="hybrid", query="...")\` \u2014 ALWAYS before Glob/Grep/Search/Read |
7796
7824
  | **Before risky/non-trivial work** | \`session(action="get_lessons", query="<topic>")\` |
7797
7825
  | **After completing task** | \`session(action="capture", event_type="decision", ...)\` - MUST capture |
7798
7826
  | **User frustration/correction** | \`session(action="capture_lesson", ...)\` - MUST capture lessons |
@@ -7919,7 +7947,8 @@ search(mode="hybrid", query="function implementation") \u2192 done (results incl
7919
7947
  | Find code by meaning | \`hybrid\` | "authentication logic", "error handling" |
7920
7948
  | Exact string/symbol | \`keyword\` | "UserAuthService", "API_KEY" |
7921
7949
  | File patterns | \`pattern\` | "*.sql", "test_*.py" |
7922
- | ALL matches (refactoring) | \`exhaustive\` | "oldFunctionName" (rename across codebase) |
7950
+ | ALL matches (grep-like) | \`exhaustive\` | "TODO", "FIXME" (find all occurrences) |
7951
+ | Symbol renaming | \`refactor\` | "oldFunctionName" (word-boundary matching) |
7923
7952
  | Conceptual search | \`semantic\` | "how does caching work" |
7924
7953
 
7925
7954
  **Token Efficiency:** Use \`output_format\` to reduce response size:
@@ -7928,6 +7957,11 @@ search(mode="hybrid", query="function implementation") \u2192 done (results incl
7928
7957
  - \`minimal\`: Compact format (60% savings) - use for refactoring
7929
7958
  - \`count\`: Match counts only (90% savings) - use for quick checks
7930
7959
 
7960
+ **When to use \`output_format=count\`:**
7961
+ - User asks "how many X" or "count of X" \u2192 \`search(..., output_format="count")\`
7962
+ - Checking if something exists \u2192 count > 0 is sufficient
7963
+ - Large exhaustive searches \u2192 get count first, then fetch if needed
7964
+
7931
7965
  **Search defaults:** \`search\` returns the top 3 results with compact snippets. Use \`limit\` + \`offset\` for pagination, and \`content_max_chars\` to expand snippets when needed.
7932
7966
 
7933
7967
  If ContextStream returns results, stop and use them. NEVER use local Search/Explore/Read unless you need exact code edits or ContextStream returned 0 results.
@@ -8007,6 +8041,16 @@ To manage existing plans/tasks:
8007
8041
  See full documentation: https://contextstream.io/docs/mcp/tools
8008
8042
  `.trim();
8009
8043
  var CONTEXTSTREAM_RULES_MINIMAL = `
8044
+ ## \u{1F6A8} CRITICAL RULE - READ EVERY TURN \u{1F6A8}
8045
+
8046
+ **BEFORE using Glob, Grep, Search, Read (for discovery), or Explore:**
8047
+ \`\`\`
8048
+ STOP \u2192 Call search(mode="hybrid", query="...") FIRST
8049
+ \`\`\`
8050
+ Only use local tools if ContextStream returns 0 results. This applies to EVERY search throughout the ENTIRE conversation, not just the first message.
8051
+
8052
+ ---
8053
+
8010
8054
  ## ContextStream v0.4.x (Consolidated Domain Tools)
8011
8055
 
8012
8056
  v0.4.x uses ~11 consolidated domain tools for ~75% token reduction vs previous versions.
@@ -8018,6 +8062,7 @@ Rules Version: ${RULES_VERSION}
8018
8062
  |---------|--------------|
8019
8063
  | **1st message** | \`session_init(folder_path="<cwd>", context_hint="<user_message>")\`, then \`context_smart(user_message="<user_message>", format="minified", max_tokens=400)\` |
8020
8064
  | **2nd+ messages** | \`context_smart(user_message="<user_message>", format="minified", max_tokens=400)\` |
8065
+ | **\u{1F50D} ANY code search** | \`search(mode="hybrid", query="...")\` \u2014 ALWAYS before Glob/Grep/Search/Read |
8021
8066
  | **Capture decisions** | \`session(action="capture", event_type="decision", title="...", content="...")\` |
8022
8067
  | **Before risky work** | \`session(action="get_lessons", query="<topic>")\` |
8023
8068
  | **On user frustration** | \`session(action="capture_lesson", title="...", trigger="...", impact="...", prevention="...")\` |
@@ -8074,7 +8119,8 @@ search(mode="hybrid", query="function implementation") \u2192 done (results incl
8074
8119
  | Find code by meaning | \`hybrid\` | "authentication logic", "error handling" |
8075
8120
  | Exact string/symbol | \`keyword\` | "UserAuthService", "API_KEY" |
8076
8121
  | File patterns | \`pattern\` | "*.sql", "test_*.py" |
8077
- | ALL matches (refactoring) | \`exhaustive\` | "oldFunctionName" (rename across codebase) |
8122
+ | ALL matches (grep-like) | \`exhaustive\` | "TODO", "FIXME" (find all occurrences) |
8123
+ | Symbol renaming | \`refactor\` | "oldFunctionName" (word-boundary matching) |
8078
8124
  | Conceptual search | \`semantic\` | "how does caching work" |
8079
8125
 
8080
8126
  ### Token Efficiency
@@ -8085,6 +8131,14 @@ Use \`output_format\` to reduce response size:
8085
8131
  - \`minimal\`: Compact format (60% savings) - use for refactoring
8086
8132
  - \`count\`: Match counts only (90% savings) - use for quick checks
8087
8133
 
8134
+ **When to use \`output_format=count\`:**
8135
+ - User asks "how many X" or "count of X" \u2192 \`search(..., output_format="count")\`
8136
+ - Checking if something exists \u2192 count > 0 is sufficient
8137
+ - Large exhaustive searches \u2192 get count first, then fetch if needed
8138
+
8139
+ **Example:** User asks "how many TODO comments?" \u2192
8140
+ \`search(mode="exhaustive", query="TODO", output_format="count")\` returns \`{total: 47}\` (not 47 full results)
8141
+
8088
8142
  ### Plans & Tasks
8089
8143
 
8090
8144
  When user asks to create a plan or implementation roadmap:
@@ -8410,6 +8464,8 @@ function normalizeUuid(value) {
8410
8464
  }
8411
8465
  var RULES_NOTICE_CACHE_TTL_MS = 10 * 60 * 1e3;
8412
8466
  var RULES_VERSION_REGEX = /Rules Version:\s*([0-9][0-9A-Za-z.\-]*)/i;
8467
+ var CONTEXTSTREAM_START_MARKER = "<!-- BEGIN ContextStream -->";
8468
+ var CONTEXTSTREAM_END_MARKER = "<!-- END ContextStream -->";
8413
8469
  var RULES_PROJECT_FILES = {
8414
8470
  codex: "AGENTS.md",
8415
8471
  claude: "CLAUDE.md",
@@ -8438,9 +8494,25 @@ function compareVersions2(v1, v2) {
8438
8494
  }
8439
8495
  return 0;
8440
8496
  }
8497
+ function extractRulesVersions(content) {
8498
+ const regex = new RegExp(RULES_VERSION_REGEX.source, "gi");
8499
+ return Array.from(content.matchAll(regex)).map((match) => match[1]?.trim()).filter((version) => Boolean(version));
8500
+ }
8501
+ function extractContextStreamMarkerBlock(content) {
8502
+ const startIdx = content.indexOf(CONTEXTSTREAM_START_MARKER);
8503
+ const endIdx = content.indexOf(CONTEXTSTREAM_END_MARKER);
8504
+ if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) {
8505
+ return null;
8506
+ }
8507
+ return content.slice(startIdx + CONTEXTSTREAM_START_MARKER.length, endIdx).trim();
8508
+ }
8441
8509
  function extractRulesVersion(content) {
8442
- const match = content.match(RULES_VERSION_REGEX);
8443
- return match?.[1]?.trim() ?? null;
8510
+ const markerBlock = extractContextStreamMarkerBlock(content);
8511
+ const candidates = markerBlock ? extractRulesVersions(markerBlock) : extractRulesVersions(content);
8512
+ if (candidates.length === 0) {
8513
+ return null;
8514
+ }
8515
+ return candidates.sort(compareVersions2).at(-1) ?? null;
8444
8516
  }
8445
8517
  function detectEditorFromClientName(clientName) {
8446
8518
  if (!clientName) return null;
@@ -8571,8 +8643,6 @@ function getRulesNotice(folderPath, clientName) {
8571
8643
  rulesNoticeCache.set(cacheKey, { checkedAt: Date.now(), notice });
8572
8644
  return notice;
8573
8645
  }
8574
- var CONTEXTSTREAM_START_MARKER = "<!-- BEGIN ContextStream -->";
8575
- var CONTEXTSTREAM_END_MARKER = "<!-- END ContextStream -->";
8576
8646
  var LEGACY_CONTEXTSTREAM_HINTS = [
8577
8647
  "contextstream integration",
8578
8648
  "contextstream v0.4",
@@ -11909,6 +11979,8 @@ Use this to persist decisions, insights, preferences, or important information.`
11909
11979
  "decision",
11910
11980
  "insight",
11911
11981
  "preference",
11982
+ "note",
11983
+ "implementation",
11912
11984
  "task",
11913
11985
  "bug",
11914
11986
  "feature",
@@ -13496,11 +13568,11 @@ Use this to remove a reminder that is no longer relevant.`,
13496
13568
  "search",
13497
13569
  {
13498
13570
  title: "Search",
13499
- description: `Search workspace memory and knowledge. Modes: semantic (meaning-based), hybrid (semantic + keyword), keyword (exact match), pattern (regex), exhaustive (all matches like grep).
13571
+ description: `Search workspace memory and knowledge. Modes: semantic (meaning-based), hybrid (semantic + keyword), keyword (exact match), pattern (regex), exhaustive (all matches like grep), refactor (word-boundary matching for symbol renaming).
13500
13572
 
13501
13573
  Output formats: full (default, includes content), paths (file paths only - 80% token savings), minimal (compact - 60% savings), count (match counts only - 90% savings).`,
13502
13574
  inputSchema: external_exports.object({
13503
- mode: external_exports.enum(["semantic", "hybrid", "keyword", "pattern", "exhaustive"]).describe("Search mode"),
13575
+ mode: external_exports.enum(["semantic", "hybrid", "keyword", "pattern", "exhaustive", "refactor"]).describe("Search mode"),
13504
13576
  query: external_exports.string().describe("Search query"),
13505
13577
  workspace_id: external_exports.string().uuid().optional(),
13506
13578
  project_id: external_exports.string().uuid().optional(),
@@ -13531,6 +13603,9 @@ Output formats: full (default, includes content), paths (file paths only - 80% t
13531
13603
  case "exhaustive":
13532
13604
  result = await client.searchExhaustive(params);
13533
13605
  break;
13606
+ case "refactor":
13607
+ result = await client.searchRefactor(params);
13608
+ break;
13534
13609
  }
13535
13610
  return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
13536
13611
  }
@@ -13565,7 +13640,7 @@ Output formats: full (default, includes content), paths (file paths only - 80% t
13565
13640
  query: external_exports.string().optional().describe("Query for recall/search/lessons/decision_trace"),
13566
13641
  content: external_exports.string().optional().describe("Content for capture/remember/compress"),
13567
13642
  title: external_exports.string().optional().describe("Title for capture/capture_lesson/capture_plan"),
13568
- event_type: external_exports.enum(["decision", "preference", "insight", "task", "bug", "feature", "plan", "correction", "lesson", "warning", "frustration", "conversation"]).optional().describe("Event type for capture"),
13643
+ event_type: external_exports.enum(["decision", "preference", "insight", "note", "implementation", "task", "bug", "feature", "plan", "correction", "lesson", "warning", "frustration", "conversation"]).optional().describe("Event type for capture"),
13569
13644
  importance: external_exports.enum(["low", "medium", "high", "critical"]).optional(),
13570
13645
  tags: external_exports.array(external_exports.string()).optional(),
13571
13646
  // Lesson-specific
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@contextstream/mcp-server",
3
3
  "mcpName": "io.github.contextstreamio/mcp-server",
4
- "version": "0.4.26",
4
+ "version": "0.4.28",
5
5
  "description": "ContextStream MCP server - v0.4.x with consolidated domain tools (~11 tools, ~75% token reduction). Code context, memory, search, and AI tools.",
6
6
  "type": "module",
7
7
  "license": "MIT",