@contextstream/mcp-server 0.3.46 → 0.3.48
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 +10 -0
- package/dist/index.js +216 -58
- package/dist/test-server.js +1 -0
- package/package.json +1 -1
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();
|
|
@@ -4775,10 +4858,12 @@ var ContextStreamClient = class {
|
|
|
4775
4858
|
}
|
|
4776
4859
|
withDefaults(input) {
|
|
4777
4860
|
const { defaultWorkspaceId, defaultProjectId } = this.config;
|
|
4861
|
+
const workspaceId = input.workspace_id || defaultWorkspaceId;
|
|
4862
|
+
const useDefaultProject = !input.project_id && (!input.workspace_id || input.workspace_id === defaultWorkspaceId);
|
|
4778
4863
|
return {
|
|
4779
4864
|
...input,
|
|
4780
|
-
workspace_id:
|
|
4781
|
-
project_id: input.project_id || defaultProjectId
|
|
4865
|
+
workspace_id: workspaceId,
|
|
4866
|
+
project_id: input.project_id || (useDefaultProject ? defaultProjectId : void 0)
|
|
4782
4867
|
};
|
|
4783
4868
|
}
|
|
4784
4869
|
coerceUuid(value) {
|
|
@@ -5626,6 +5711,29 @@ var ContextStreamClient = class {
|
|
|
5626
5711
|
});
|
|
5627
5712
|
if (batchedContext.workspace) {
|
|
5628
5713
|
context.workspace = batchedContext.workspace;
|
|
5714
|
+
if (batchedContext.workspace.id && batchedContext.workspace.id !== workspaceId) {
|
|
5715
|
+
console.error(`[ContextStream] Workspace mismatch: config=${workspaceId}, API returned=${batchedContext.workspace.id}. Using API workspace.`);
|
|
5716
|
+
const oldWorkspaceId = workspaceId;
|
|
5717
|
+
workspaceId = batchedContext.workspace.id;
|
|
5718
|
+
workspaceName = batchedContext.workspace.name;
|
|
5719
|
+
context.workspace_id = workspaceId;
|
|
5720
|
+
context.workspace_name = workspaceName;
|
|
5721
|
+
context.workspace_source = "api_fallback";
|
|
5722
|
+
context.workspace_mismatch_warning = `Config had workspace ${oldWorkspaceId} but you don't have access. Using ${workspaceId} instead.`;
|
|
5723
|
+
projectId = batchedContext.project?.id;
|
|
5724
|
+
context.project_id = projectId;
|
|
5725
|
+
this.config.defaultProjectId = projectId;
|
|
5726
|
+
if (rootPath) {
|
|
5727
|
+
writeLocalConfig(rootPath, {
|
|
5728
|
+
workspace_id: workspaceId,
|
|
5729
|
+
workspace_name: workspaceName,
|
|
5730
|
+
project_id: projectId,
|
|
5731
|
+
// Use API-returned project or undefined
|
|
5732
|
+
associated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5733
|
+
});
|
|
5734
|
+
console.error(`[ContextStream] Updated local config with accessible workspace: ${workspaceId}`);
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5629
5737
|
}
|
|
5630
5738
|
if (batchedContext.project) {
|
|
5631
5739
|
context.project = batchedContext.project;
|
|
@@ -7569,7 +7677,17 @@ function getCoreToolsHint() {
|
|
|
7569
7677
|
// src/tools.ts
|
|
7570
7678
|
var LESSON_DEDUP_WINDOW_MS = 2 * 60 * 1e3;
|
|
7571
7679
|
var recentLessonCaptures = /* @__PURE__ */ new Map();
|
|
7572
|
-
var
|
|
7680
|
+
var LIGHT_TOOLSET = /* @__PURE__ */ new Set([
|
|
7681
|
+
"session_init",
|
|
7682
|
+
"context_smart",
|
|
7683
|
+
"session_capture",
|
|
7684
|
+
"session_recall",
|
|
7685
|
+
"session_remember",
|
|
7686
|
+
"auth_me",
|
|
7687
|
+
"mcp_server_version"
|
|
7688
|
+
]);
|
|
7689
|
+
var STANDARD_TOOLSET = /* @__PURE__ */ new Set([
|
|
7690
|
+
// Core session tools
|
|
7573
7691
|
"session_init",
|
|
7574
7692
|
"session_tools",
|
|
7575
7693
|
"context_smart",
|
|
@@ -7583,18 +7701,33 @@ var CORE_TOOLSET = /* @__PURE__ */ new Set([
|
|
|
7583
7701
|
"session_smart_search",
|
|
7584
7702
|
"session_compress",
|
|
7585
7703
|
"session_delta",
|
|
7704
|
+
// Setup and configuration
|
|
7586
7705
|
"generate_editor_rules",
|
|
7587
7706
|
"workspace_associate",
|
|
7588
7707
|
"workspace_bootstrap",
|
|
7589
7708
|
"projects_create",
|
|
7590
7709
|
"projects_list",
|
|
7710
|
+
// Project indexing - essential for code context
|
|
7711
|
+
"projects_ingest_local",
|
|
7712
|
+
"projects_index",
|
|
7713
|
+
"projects_index_status",
|
|
7714
|
+
"projects_files",
|
|
7715
|
+
// Utility
|
|
7591
7716
|
"auth_me",
|
|
7592
7717
|
"mcp_server_version"
|
|
7593
7718
|
]);
|
|
7594
7719
|
var TOOLSET_ALIASES = {
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7720
|
+
// Light mode - minimal, fastest
|
|
7721
|
+
light: LIGHT_TOOLSET,
|
|
7722
|
+
minimal: LIGHT_TOOLSET,
|
|
7723
|
+
// Standard mode - balanced (default)
|
|
7724
|
+
standard: STANDARD_TOOLSET,
|
|
7725
|
+
core: STANDARD_TOOLSET,
|
|
7726
|
+
essential: STANDARD_TOOLSET,
|
|
7727
|
+
// Complete mode - all tools
|
|
7728
|
+
complete: null,
|
|
7729
|
+
full: null,
|
|
7730
|
+
all: null
|
|
7598
7731
|
};
|
|
7599
7732
|
function parseToolList(raw) {
|
|
7600
7733
|
return new Set(
|
|
@@ -7602,30 +7735,29 @@ function parseToolList(raw) {
|
|
|
7602
7735
|
);
|
|
7603
7736
|
}
|
|
7604
7737
|
function resolveToolFilter() {
|
|
7605
|
-
const defaultToolset = CORE_TOOLSET;
|
|
7606
7738
|
const allowlistRaw = process.env.CONTEXTSTREAM_TOOL_ALLOWLIST;
|
|
7607
7739
|
if (allowlistRaw) {
|
|
7608
7740
|
const allowlist = parseToolList(allowlistRaw);
|
|
7609
7741
|
if (allowlist.size === 0) {
|
|
7610
|
-
console.error("[ContextStream] CONTEXTSTREAM_TOOL_ALLOWLIST is empty; using
|
|
7611
|
-
return { allowlist:
|
|
7742
|
+
console.error("[ContextStream] CONTEXTSTREAM_TOOL_ALLOWLIST is empty; using standard toolset.");
|
|
7743
|
+
return { allowlist: STANDARD_TOOLSET, source: "standard" };
|
|
7612
7744
|
}
|
|
7613
7745
|
return { allowlist, source: "allowlist" };
|
|
7614
7746
|
}
|
|
7615
7747
|
const toolsetRaw = process.env.CONTEXTSTREAM_TOOLSET;
|
|
7616
7748
|
if (!toolsetRaw) {
|
|
7617
|
-
return { allowlist:
|
|
7749
|
+
return { allowlist: STANDARD_TOOLSET, source: "standard" };
|
|
7618
7750
|
}
|
|
7619
7751
|
const key = toolsetRaw.trim().toLowerCase();
|
|
7620
|
-
if (
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7752
|
+
if (key in TOOLSET_ALIASES) {
|
|
7753
|
+
const resolved = TOOLSET_ALIASES[key];
|
|
7754
|
+
if (resolved === null) {
|
|
7755
|
+
return { allowlist: null, source: "complete" };
|
|
7756
|
+
}
|
|
7625
7757
|
return { allowlist: resolved, source: key };
|
|
7626
7758
|
}
|
|
7627
|
-
console.error(`[ContextStream] Unknown CONTEXTSTREAM_TOOLSET "${toolsetRaw}". Using
|
|
7628
|
-
return { allowlist:
|
|
7759
|
+
console.error(`[ContextStream] Unknown CONTEXTSTREAM_TOOLSET "${toolsetRaw}". Using standard toolset.`);
|
|
7760
|
+
return { allowlist: STANDARD_TOOLSET, source: "standard" };
|
|
7629
7761
|
}
|
|
7630
7762
|
function formatContent(data) {
|
|
7631
7763
|
return JSON.stringify(data, null, 2);
|
|
@@ -7670,9 +7802,11 @@ function registerTools(server, client, sessionManager) {
|
|
|
7670
7802
|
const toolFilter = resolveToolFilter();
|
|
7671
7803
|
const toolAllowlist = toolFilter.allowlist;
|
|
7672
7804
|
if (toolAllowlist) {
|
|
7673
|
-
const source = toolFilter.source
|
|
7674
|
-
const hint = source === "
|
|
7675
|
-
console.error(`[ContextStream] Toolset
|
|
7805
|
+
const source = toolFilter.source;
|
|
7806
|
+
const hint = source === "light" ? " Set CONTEXTSTREAM_TOOLSET=standard or complete for more tools." : source === "standard" ? " Set CONTEXTSTREAM_TOOLSET=complete for all tools." : "";
|
|
7807
|
+
console.error(`[ContextStream] Toolset: ${source} (${toolAllowlist.size} tools).${hint}`);
|
|
7808
|
+
} else {
|
|
7809
|
+
console.error(`[ContextStream] Toolset: complete (all tools).`);
|
|
7676
7810
|
}
|
|
7677
7811
|
const defaultProTools = /* @__PURE__ */ new Set([
|
|
7678
7812
|
// AI endpoints (typically paid/credit-metered)
|
|
@@ -8008,7 +8142,7 @@ Access: Free`,
|
|
|
8008
8142
|
}
|
|
8009
8143
|
}
|
|
8010
8144
|
const response = {
|
|
8011
|
-
...result,
|
|
8145
|
+
...result && typeof result === "object" ? result : {},
|
|
8012
8146
|
folder_path: input.folder_path,
|
|
8013
8147
|
config_written: input.folder_path ? true : void 0,
|
|
8014
8148
|
editor_rules_generated: rulesGenerated.length > 0 ? rulesGenerated : void 0
|
|
@@ -10745,26 +10879,26 @@ var SessionManager = class {
|
|
|
10745
10879
|
};
|
|
10746
10880
|
|
|
10747
10881
|
// src/index.ts
|
|
10748
|
-
import { existsSync as
|
|
10749
|
-
import { homedir as
|
|
10750
|
-
import { join as
|
|
10882
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
10883
|
+
import { homedir as homedir4 } from "os";
|
|
10884
|
+
import { join as join8 } from "path";
|
|
10751
10885
|
|
|
10752
10886
|
// src/setup.ts
|
|
10753
10887
|
import * as fs5 from "node:fs/promises";
|
|
10754
10888
|
import * as path6 from "node:path";
|
|
10755
|
-
import { homedir as
|
|
10889
|
+
import { homedir as homedir3 } from "node:os";
|
|
10756
10890
|
import { stdin, stdout } from "node:process";
|
|
10757
10891
|
import { createInterface } from "node:readline/promises";
|
|
10758
10892
|
|
|
10759
10893
|
// src/credentials.ts
|
|
10760
10894
|
import * as fs4 from "node:fs/promises";
|
|
10761
10895
|
import * as path5 from "node:path";
|
|
10762
|
-
import { homedir } from "node:os";
|
|
10896
|
+
import { homedir as homedir2 } from "node:os";
|
|
10763
10897
|
function normalizeApiUrl(input) {
|
|
10764
10898
|
return String(input ?? "").trim().replace(/\/+$/, "");
|
|
10765
10899
|
}
|
|
10766
10900
|
function credentialsFilePath() {
|
|
10767
|
-
return path5.join(
|
|
10901
|
+
return path5.join(homedir2(), ".contextstream", "credentials.json");
|
|
10768
10902
|
}
|
|
10769
10903
|
function isRecord(value) {
|
|
10770
10904
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -10862,21 +10996,42 @@ async function fileExists(filePath) {
|
|
|
10862
10996
|
return false;
|
|
10863
10997
|
}
|
|
10864
10998
|
}
|
|
10865
|
-
|
|
10999
|
+
var CONTEXTSTREAM_START_MARKER = "<!-- BEGIN ContextStream -->";
|
|
11000
|
+
var CONTEXTSTREAM_END_MARKER = "<!-- END ContextStream -->";
|
|
11001
|
+
function wrapWithMarkers(content) {
|
|
11002
|
+
return `${CONTEXTSTREAM_START_MARKER}
|
|
11003
|
+
${content.trim()}
|
|
11004
|
+
${CONTEXTSTREAM_END_MARKER}`;
|
|
11005
|
+
}
|
|
11006
|
+
async function upsertTextFile(filePath, content, _marker) {
|
|
10866
11007
|
await fs5.mkdir(path6.dirname(filePath), { recursive: true });
|
|
10867
11008
|
const exists = await fileExists(filePath);
|
|
11009
|
+
const wrappedContent = wrapWithMarkers(content);
|
|
10868
11010
|
if (!exists) {
|
|
10869
|
-
await fs5.writeFile(filePath,
|
|
11011
|
+
await fs5.writeFile(filePath, wrappedContent + "\n", "utf8");
|
|
10870
11012
|
return "created";
|
|
10871
11013
|
}
|
|
10872
11014
|
const existing = await fs5.readFile(filePath, "utf8").catch(() => "");
|
|
10873
|
-
|
|
10874
|
-
const
|
|
11015
|
+
const startIdx = existing.indexOf(CONTEXTSTREAM_START_MARKER);
|
|
11016
|
+
const endIdx = existing.indexOf(CONTEXTSTREAM_END_MARKER);
|
|
11017
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
11018
|
+
const before = existing.substring(0, startIdx);
|
|
11019
|
+
const after = existing.substring(endIdx + CONTEXTSTREAM_END_MARKER.length);
|
|
11020
|
+
const updated = before.trimEnd() + "\n\n" + wrappedContent + "\n" + after.trimStart();
|
|
11021
|
+
await fs5.writeFile(filePath, updated.trim() + "\n", "utf8");
|
|
11022
|
+
return "updated";
|
|
11023
|
+
}
|
|
11024
|
+
if (existing.includes("ContextStream")) {
|
|
11025
|
+
const joined2 = existing.trimEnd() + "\n\n" + wrappedContent + "\n";
|
|
11026
|
+
await fs5.writeFile(filePath, joined2, "utf8");
|
|
11027
|
+
return "updated";
|
|
11028
|
+
}
|
|
11029
|
+
const joined = existing.trimEnd() + "\n\n" + wrappedContent + "\n";
|
|
10875
11030
|
await fs5.writeFile(filePath, joined, "utf8");
|
|
10876
11031
|
return "appended";
|
|
10877
11032
|
}
|
|
10878
11033
|
function globalRulesPathForEditor(editor) {
|
|
10879
|
-
const home =
|
|
11034
|
+
const home = homedir3();
|
|
10880
11035
|
switch (editor) {
|
|
10881
11036
|
case "codex":
|
|
10882
11037
|
return path6.join(home, ".codex", "AGENTS.md");
|
|
@@ -10984,7 +11139,7 @@ async function upsertJsonVsCodeMcpConfig(filePath, server) {
|
|
|
10984
11139
|
return before === after ? "skipped" : "updated";
|
|
10985
11140
|
}
|
|
10986
11141
|
function claudeDesktopConfigPath() {
|
|
10987
|
-
const home =
|
|
11142
|
+
const home = homedir3();
|
|
10988
11143
|
if (process.platform === "darwin") {
|
|
10989
11144
|
return path6.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
10990
11145
|
}
|
|
@@ -11282,16 +11437,16 @@ Created API key: ${maskApiKey(apiKey)}
|
|
|
11282
11437
|
const modeChoice = normalizeInput(await rl.question("Choose [1/2] (default 1): ")) || "1";
|
|
11283
11438
|
const mode = modeChoice === "2" ? "full" : "minimal";
|
|
11284
11439
|
console.log("\nMCP toolset (which tools to expose to the AI):");
|
|
11285
|
-
console.log(" 1)
|
|
11286
|
-
console.log(" Best for:
|
|
11287
|
-
console.log(" 2)
|
|
11288
|
-
console.log(" Best for:
|
|
11289
|
-
console.log("
|
|
11440
|
+
console.log(" 1) Light \u2014 minimal essential tools for fastest responses (~7 tools)");
|
|
11441
|
+
console.log(" Best for: simple tasks, resource-constrained environments");
|
|
11442
|
+
console.log(" 2) Standard (recommended) \u2014 balanced set of session and context tools (~20 tools)");
|
|
11443
|
+
console.log(" Best for: most users, balances speed with capabilities");
|
|
11444
|
+
console.log(" 3) Complete \u2014 all tools including memory, knowledge graph, AI, integrations (~86 tools)");
|
|
11445
|
+
console.log(" Best for: power users needing full workspace/project/graph capabilities");
|
|
11290
11446
|
console.log("");
|
|
11291
|
-
console.log(" Tip:
|
|
11292
|
-
|
|
11293
|
-
const
|
|
11294
|
-
const toolset = toolsetChoice === "2" ? "full" : "core";
|
|
11447
|
+
console.log(" Tip: Change later by setting CONTEXTSTREAM_TOOLSET=light|standard|complete");
|
|
11448
|
+
const toolsetChoice = normalizeInput(await rl.question("Choose [1/2/3] (default 2): ")) || "2";
|
|
11449
|
+
const toolset = toolsetChoice === "1" ? "light" : toolsetChoice === "3" ? "complete" : "standard";
|
|
11295
11450
|
const editors = ["codex", "claude", "cursor", "windsurf", "cline", "kilo", "roo", "aider"];
|
|
11296
11451
|
console.log('\nSelect editors to configure (comma-separated numbers, or "all"):');
|
|
11297
11452
|
editors.forEach((e, i) => console.log(` ${i + 1}) ${EDITOR_LABELS[e]}`));
|
|
@@ -11322,9 +11477,9 @@ Created API key: ${maskApiKey(apiKey)}
|
|
|
11322
11477
|
const mcpChoiceDefault = hasCodex && !hasProjectMcpEditors ? "1" : "3";
|
|
11323
11478
|
const mcpChoice = normalizeInput(await rl.question(`Choose [${hasCodex && !hasProjectMcpEditors ? "1/2" : "1/2/3/4"}] (default ${mcpChoiceDefault}): `)) || mcpChoiceDefault;
|
|
11324
11479
|
const mcpScope = mcpChoice === "2" && hasCodex && !hasProjectMcpEditors ? "skip" : mcpChoice === "4" ? "skip" : mcpChoice === "1" ? "global" : mcpChoice === "2" ? "project" : "both";
|
|
11325
|
-
const mcpServer = toolset === "
|
|
11480
|
+
const mcpServer = toolset === "complete" ? buildContextStreamMcpServer({ apiUrl, apiKey, toolset: "complete" }) : buildContextStreamMcpServer({ apiUrl, apiKey });
|
|
11326
11481
|
const mcpServerClaude = buildContextStreamMcpServer({ apiUrl, apiKey, toolset });
|
|
11327
|
-
const vsCodeServer = toolset === "
|
|
11482
|
+
const vsCodeServer = toolset === "complete" ? buildContextStreamVsCodeServer({ apiUrl, apiKey, toolset: "complete" }) : buildContextStreamVsCodeServer({ apiUrl, apiKey });
|
|
11328
11483
|
const needsGlobalMcpConfig = mcpScope === "global" || mcpScope === "both" || mcpScope === "project" && hasCodex;
|
|
11329
11484
|
if (needsGlobalMcpConfig) {
|
|
11330
11485
|
console.log("\nInstalling global MCP config...");
|
|
@@ -11332,20 +11487,20 @@ Created API key: ${maskApiKey(apiKey)}
|
|
|
11332
11487
|
if (mcpScope === "project" && editor !== "codex") continue;
|
|
11333
11488
|
try {
|
|
11334
11489
|
if (editor === "codex") {
|
|
11335
|
-
const filePath = path6.join(
|
|
11490
|
+
const filePath = path6.join(homedir3(), ".codex", "config.toml");
|
|
11336
11491
|
if (dryRun) {
|
|
11337
11492
|
writeActions.push({ kind: "mcp-config", target: filePath, status: "dry-run" });
|
|
11338
11493
|
console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
|
|
11339
11494
|
continue;
|
|
11340
11495
|
}
|
|
11341
|
-
const codexParams = toolset === "
|
|
11496
|
+
const codexParams = toolset === "complete" ? { apiUrl, apiKey, toolset: "complete" } : { apiUrl, apiKey };
|
|
11342
11497
|
const status = await upsertCodexTomlConfig(filePath, codexParams);
|
|
11343
11498
|
writeActions.push({ kind: "mcp-config", target: filePath, status });
|
|
11344
11499
|
console.log(`- ${EDITOR_LABELS[editor]}: ${status} ${filePath}`);
|
|
11345
11500
|
continue;
|
|
11346
11501
|
}
|
|
11347
11502
|
if (editor === "windsurf") {
|
|
11348
|
-
const filePath = path6.join(
|
|
11503
|
+
const filePath = path6.join(homedir3(), ".codeium", "windsurf", "mcp_config.json");
|
|
11349
11504
|
if (dryRun) {
|
|
11350
11505
|
writeActions.push({ kind: "mcp-config", target: filePath, status: "dry-run" });
|
|
11351
11506
|
console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
|
|
@@ -11377,7 +11532,7 @@ Created API key: ${maskApiKey(apiKey)}
|
|
|
11377
11532
|
continue;
|
|
11378
11533
|
}
|
|
11379
11534
|
if (editor === "cursor") {
|
|
11380
|
-
const filePath = path6.join(
|
|
11535
|
+
const filePath = path6.join(homedir3(), ".cursor", "mcp.json");
|
|
11381
11536
|
if (dryRun) {
|
|
11382
11537
|
writeActions.push({ kind: "mcp-config", target: filePath, status: "dry-run" });
|
|
11383
11538
|
console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
|
|
@@ -11575,14 +11730,15 @@ Applying to ${projects.length} project(s)...`);
|
|
|
11575
11730
|
const skipped = writeActions.filter((a) => a.status === "skipped").length;
|
|
11576
11731
|
const dry = writeActions.filter((a) => a.status === "dry-run").length;
|
|
11577
11732
|
console.log(`Summary: ${created} created, ${updated} updated, ${appended} appended, ${skipped} skipped, ${dry} dry-run.`);
|
|
11578
|
-
|
|
11733
|
+
const toolsetDesc = toolset === "light" ? "~7 tools" : toolset === "complete" ? "~86 tools" : "~20 tools";
|
|
11734
|
+
console.log(`Toolset: ${toolset} (${toolsetDesc})`);
|
|
11579
11735
|
}
|
|
11580
11736
|
console.log("\nNext steps:");
|
|
11581
11737
|
console.log("- Restart your editor/CLI after changing MCP config or rules.");
|
|
11582
11738
|
console.log("- Prefer ContextStream search first: use session_smart_search (or mcp__contextstream__session_smart_search) before raw repo scans (rg/ls/find).");
|
|
11583
11739
|
console.log("- If any tools require UI-based MCP setup (e.g. Cline/Kilo/Roo global), follow https://contextstream.io/docs/mcp.");
|
|
11584
|
-
if (toolset === "
|
|
11585
|
-
console.log("- Note: Claude Code/Desktop may warn about large tool contexts. This is expected with the
|
|
11740
|
+
if (toolset === "complete") {
|
|
11741
|
+
console.log("- Note: Claude Code/Desktop may warn about large tool contexts. This is expected with the complete toolset.");
|
|
11586
11742
|
}
|
|
11587
11743
|
} finally {
|
|
11588
11744
|
rl.close();
|
|
@@ -11591,14 +11747,14 @@ Applying to ${projects.length} project(s)...`);
|
|
|
11591
11747
|
|
|
11592
11748
|
// src/index.ts
|
|
11593
11749
|
function showFirstRunMessage() {
|
|
11594
|
-
const configDir =
|
|
11595
|
-
const starShownFile =
|
|
11596
|
-
if (
|
|
11750
|
+
const configDir = join8(homedir4(), ".contextstream");
|
|
11751
|
+
const starShownFile = join8(configDir, ".star-shown");
|
|
11752
|
+
if (existsSync4(starShownFile)) {
|
|
11597
11753
|
return;
|
|
11598
11754
|
}
|
|
11599
|
-
if (!
|
|
11755
|
+
if (!existsSync4(configDir)) {
|
|
11600
11756
|
try {
|
|
11601
|
-
|
|
11757
|
+
mkdirSync4(configDir, { recursive: true });
|
|
11602
11758
|
} catch {
|
|
11603
11759
|
return;
|
|
11604
11760
|
}
|
|
@@ -11611,7 +11767,7 @@ function showFirstRunMessage() {
|
|
|
11611
11767
|
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");
|
|
11612
11768
|
console.error("");
|
|
11613
11769
|
try {
|
|
11614
|
-
|
|
11770
|
+
writeFileSync4(starShownFile, (/* @__PURE__ */ new Date()).toISOString());
|
|
11615
11771
|
} catch {
|
|
11616
11772
|
}
|
|
11617
11773
|
}
|
|
@@ -11632,7 +11788,7 @@ Environment variables:
|
|
|
11632
11788
|
CONTEXTSTREAM_JWT JWT for authentication (alternative to API key)
|
|
11633
11789
|
CONTEXTSTREAM_WORKSPACE_ID Optional default workspace ID
|
|
11634
11790
|
CONTEXTSTREAM_PROJECT_ID Optional default project ID
|
|
11635
|
-
CONTEXTSTREAM_TOOLSET
|
|
11791
|
+
CONTEXTSTREAM_TOOLSET Tool mode: light|standard|complete (default: standard)
|
|
11636
11792
|
CONTEXTSTREAM_TOOL_ALLOWLIST Optional comma-separated tool names to expose (overrides toolset)
|
|
11637
11793
|
CONTEXTSTREAM_PRO_TOOLS Optional comma-separated PRO tool names (default: AI tools)
|
|
11638
11794
|
CONTEXTSTREAM_UPGRADE_URL Optional upgrade URL shown for PRO tools on Free plan
|
|
@@ -11681,6 +11837,8 @@ async function main() {
|
|
|
11681
11837
|
await server.connect(transport);
|
|
11682
11838
|
console.error("ContextStream MCP server connected and ready");
|
|
11683
11839
|
showFirstRunMessage();
|
|
11840
|
+
checkForUpdates().catch(() => {
|
|
11841
|
+
});
|
|
11684
11842
|
}
|
|
11685
11843
|
main().catch((err) => {
|
|
11686
11844
|
console.error("ContextStream MCP server failed to start:", err?.message || err);
|
package/dist/test-server.js
CHANGED
package/package.json
CHANGED