@contextstream/mcp-server 0.3.22 → 0.3.24
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/dist/index.js +95 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4629,6 +4629,14 @@ var globalCache = new MemoryCache();
|
|
|
4629
4629
|
|
|
4630
4630
|
// src/client.ts
|
|
4631
4631
|
var uuidSchema = external_exports.string().uuid();
|
|
4632
|
+
function unwrapApiResponse(result) {
|
|
4633
|
+
if (!result || typeof result !== "object") return result;
|
|
4634
|
+
const maybe = result;
|
|
4635
|
+
if (typeof maybe.success === "boolean" && "data" in maybe) {
|
|
4636
|
+
return maybe.data;
|
|
4637
|
+
}
|
|
4638
|
+
return result;
|
|
4639
|
+
}
|
|
4632
4640
|
var ContextStreamClient = class {
|
|
4633
4641
|
constructor(config) {
|
|
4634
4642
|
this.config = config;
|
|
@@ -4696,8 +4704,9 @@ var ContextStreamClient = class {
|
|
|
4696
4704
|
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
4697
4705
|
return request(this.config, `/workspaces${suffix}`);
|
|
4698
4706
|
}
|
|
4699
|
-
createWorkspace(input) {
|
|
4700
|
-
|
|
4707
|
+
async createWorkspace(input) {
|
|
4708
|
+
const result = await request(this.config, "/workspaces", { body: input });
|
|
4709
|
+
return unwrapApiResponse(result);
|
|
4701
4710
|
}
|
|
4702
4711
|
updateWorkspace(workspaceId, input) {
|
|
4703
4712
|
uuidSchema.parse(workspaceId);
|
|
@@ -4716,9 +4725,10 @@ var ContextStreamClient = class {
|
|
|
4716
4725
|
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
4717
4726
|
return request(this.config, `/projects${suffix}`);
|
|
4718
4727
|
}
|
|
4719
|
-
createProject(input) {
|
|
4728
|
+
async createProject(input) {
|
|
4720
4729
|
const payload = this.withDefaults(input);
|
|
4721
|
-
|
|
4730
|
+
const result = await request(this.config, "/projects", { body: payload });
|
|
4731
|
+
return unwrapApiResponse(result);
|
|
4722
4732
|
}
|
|
4723
4733
|
updateProject(projectId, input) {
|
|
4724
4734
|
uuidSchema.parse(projectId);
|
|
@@ -5102,6 +5112,38 @@ var ContextStreamClient = class {
|
|
|
5102
5112
|
context.workspace_error = String(e);
|
|
5103
5113
|
}
|
|
5104
5114
|
}
|
|
5115
|
+
if (!workspaceId && !params.allow_no_workspace) {
|
|
5116
|
+
const folderDisplayName = rootPath?.split("/").pop() || "this folder";
|
|
5117
|
+
context.ide_roots = ideRoots;
|
|
5118
|
+
context.folder_name = folderDisplayName;
|
|
5119
|
+
if (rootPath) {
|
|
5120
|
+
context.folder_path = rootPath;
|
|
5121
|
+
}
|
|
5122
|
+
context.suggested_project_name = folderDisplayName;
|
|
5123
|
+
try {
|
|
5124
|
+
const workspaces = await this.listWorkspaces({ page_size: 50 });
|
|
5125
|
+
const items = Array.isArray(workspaces.items) ? workspaces.items : [];
|
|
5126
|
+
if (items.length > 0) {
|
|
5127
|
+
context.status = "requires_workspace_selection";
|
|
5128
|
+
context.workspace_candidates = items.map((w) => ({
|
|
5129
|
+
id: w.id,
|
|
5130
|
+
name: w.name,
|
|
5131
|
+
description: w.description
|
|
5132
|
+
}));
|
|
5133
|
+
context.message = `This folder is not associated with a workspace yet. Please select which workspace to use, or create a new one.`;
|
|
5134
|
+
return context;
|
|
5135
|
+
}
|
|
5136
|
+
context.status = "requires_workspace_name";
|
|
5137
|
+
context.workspace_source = "none_found";
|
|
5138
|
+
context.message = `No workspaces found for this account. Ask the user for a name for a new workspace, then create a project for "${folderDisplayName}".`;
|
|
5139
|
+
return context;
|
|
5140
|
+
} catch (e) {
|
|
5141
|
+
context.status = "requires_workspace_selection";
|
|
5142
|
+
context.workspace_error = String(e);
|
|
5143
|
+
context.message = `Unable to resolve a workspace automatically (${String(e)}). Please provide workspace_id, or create one with workspace_bootstrap.`;
|
|
5144
|
+
return context;
|
|
5145
|
+
}
|
|
5146
|
+
}
|
|
5105
5147
|
if (!projectId && workspaceId && rootPath && params.auto_index !== false) {
|
|
5106
5148
|
const projectName = rootPath.split("/").pop() || "My Project";
|
|
5107
5149
|
try {
|
|
@@ -5171,6 +5213,9 @@ var ContextStreamClient = class {
|
|
|
5171
5213
|
context.workspace_name = workspaceName;
|
|
5172
5214
|
context.project_id = projectId;
|
|
5173
5215
|
context.ide_roots = ideRoots;
|
|
5216
|
+
if (!workspaceId) {
|
|
5217
|
+
context.workspace_warning = "No workspace was resolved for this session. Workspace-level tools (memory/search/graph) may not work until you associate this folder with a workspace.";
|
|
5218
|
+
}
|
|
5174
5219
|
if (workspaceId) {
|
|
5175
5220
|
try {
|
|
5176
5221
|
const batchedContext = await this._fetchSessionContextBatched({
|
|
@@ -6548,8 +6593,11 @@ Access: ${accessLabel}${accessLabel === "PRO" ? ` (upgrade: ${upgradeUrl2})` : "
|
|
|
6548
6593
|
const errorMessage = error?.message || String(error);
|
|
6549
6594
|
const errorDetails = error?.body || error?.details || null;
|
|
6550
6595
|
const errorCode = error?.code || error?.status || "UNKNOWN_ERROR";
|
|
6596
|
+
const isPlanLimit = String(errorCode).toUpperCase() === "FORBIDDEN" && String(errorMessage).toLowerCase().includes("plan limit reached");
|
|
6597
|
+
const upgradeHint = isPlanLimit ? `
|
|
6598
|
+
Upgrade: ${upgradeUrl2}` : "";
|
|
6551
6599
|
const serializedError = new Error(
|
|
6552
|
-
`[${errorCode}] ${errorMessage}${errorDetails ? `: ${JSON.stringify(errorDetails)}` : ""}`
|
|
6600
|
+
`[${errorCode}] ${errorMessage}${upgradeHint}${errorDetails ? `: ${JSON.stringify(errorDetails)}` : ""}`
|
|
6553
6601
|
);
|
|
6554
6602
|
throw serializedError;
|
|
6555
6603
|
}
|
|
@@ -7482,7 +7530,8 @@ This does semantic search on the first message. You only need context_smart on s
|
|
|
7482
7530
|
context_hint: external_exports.string().optional().describe("RECOMMENDED: Pass the user's first message here for semantic search. This finds relevant context from ANY time, not just recent items."),
|
|
7483
7531
|
include_recent_memory: external_exports.boolean().optional().describe("Include recent memory events (default: true)"),
|
|
7484
7532
|
include_decisions: external_exports.boolean().optional().describe("Include recent decisions (default: true)"),
|
|
7485
|
-
auto_index: external_exports.boolean().optional().describe("Automatically create and index project from IDE workspace (default: true)")
|
|
7533
|
+
auto_index: external_exports.boolean().optional().describe("Automatically create and index project from IDE workspace (default: true)"),
|
|
7534
|
+
allow_no_workspace: external_exports.boolean().optional().describe("If true, allow session_init to return connected even if no workspace is resolved (workspace-level tools may not work).")
|
|
7486
7535
|
})
|
|
7487
7536
|
},
|
|
7488
7537
|
async (input) => {
|
|
@@ -7501,7 +7550,46 @@ This does semantic search on the first message. You only need context_smart on s
|
|
|
7501
7550
|
if (sessionManager) {
|
|
7502
7551
|
sessionManager.markInitialized(result);
|
|
7503
7552
|
}
|
|
7504
|
-
|
|
7553
|
+
const status = typeof result.status === "string" ? result.status : "";
|
|
7554
|
+
const workspaceWarning = typeof result.workspace_warning === "string" ? result.workspace_warning : "";
|
|
7555
|
+
let text = formatContent(result);
|
|
7556
|
+
if (status === "requires_workspace_name") {
|
|
7557
|
+
const folderPath = typeof result.folder_path === "string" ? result.folder_path : typeof input.folder_path === "string" ? input.folder_path : "";
|
|
7558
|
+
text = [
|
|
7559
|
+
"Action required: no workspaces found for this account.",
|
|
7560
|
+
"Ask the user for a name for the new workspace, then run `workspace_bootstrap`.",
|
|
7561
|
+
folderPath ? `Recommended: workspace_bootstrap(workspace_name: "<name>", folder_path: "${folderPath}")` : 'Recommended: workspace_bootstrap(workspace_name: "<name>", folder_path: "<your repo folder>")',
|
|
7562
|
+
"",
|
|
7563
|
+
"--- Raw Response ---",
|
|
7564
|
+
"",
|
|
7565
|
+
formatContent(result)
|
|
7566
|
+
].join("\n");
|
|
7567
|
+
} else if (status === "requires_workspace_selection") {
|
|
7568
|
+
const folderName = typeof result.folder_name === "string" ? result.folder_name : typeof input.folder_path === "string" ? input.folder_path.split("/").pop() || "this folder" : "this folder";
|
|
7569
|
+
const candidates = Array.isArray(result.workspace_candidates) ? result.workspace_candidates : [];
|
|
7570
|
+
const lines = [];
|
|
7571
|
+
lines.push(`Action required: select a workspace for "${folderName}" (or create a new one).`);
|
|
7572
|
+
if (candidates.length > 0) {
|
|
7573
|
+
lines.push("");
|
|
7574
|
+
lines.push("Available workspaces:");
|
|
7575
|
+
candidates.slice(0, 25).forEach((w, i) => {
|
|
7576
|
+
const name = w.name || "Untitled";
|
|
7577
|
+
const id = w.id ? ` (${w.id})` : "";
|
|
7578
|
+
const desc = w.description ? ` - ${w.description}` : "";
|
|
7579
|
+
lines.push(` ${i + 1}. ${name}${id}${desc}`);
|
|
7580
|
+
});
|
|
7581
|
+
}
|
|
7582
|
+
lines.push("");
|
|
7583
|
+
lines.push("Then run `workspace_associate` with the selected workspace_id and your folder_path.");
|
|
7584
|
+
lines.push("");
|
|
7585
|
+
lines.push("--- Raw Response ---");
|
|
7586
|
+
lines.push("");
|
|
7587
|
+
lines.push(formatContent(result));
|
|
7588
|
+
text = lines.join("\n");
|
|
7589
|
+
} else if (workspaceWarning) {
|
|
7590
|
+
text = [`Warning: ${workspaceWarning}`, "", formatContent(result)].join("\n");
|
|
7591
|
+
}
|
|
7592
|
+
return { content: [{ type: "text", text }], structuredContent: toStructured(result) };
|
|
7505
7593
|
}
|
|
7506
7594
|
);
|
|
7507
7595
|
registerTool(
|
package/package.json
CHANGED