@contextstream/mcp-server 0.3.6 → 0.3.8

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/index.js +145 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4634,7 +4634,14 @@ var ContextStreamClient = class {
4634
4634
  }
4635
4635
  // Memory / Knowledge
4636
4636
  createMemoryEvent(body) {
4637
- return request(this.config, "/memory/events", { body: this.withDefaults(body) });
4637
+ const withDefaults = this.withDefaults(body);
4638
+ if (!withDefaults.workspace_id) {
4639
+ throw new Error("workspace_id is required for creating memory events. Set defaultWorkspaceId in config or provide workspace_id.");
4640
+ }
4641
+ if (!body.content || body.content.trim().length === 0) {
4642
+ throw new Error("content is required and cannot be empty");
4643
+ }
4644
+ return request(this.config, "/memory/events", { body: withDefaults });
4638
4645
  }
4639
4646
  bulkIngestEvents(body) {
4640
4647
  return request(this.config, "/memory/events/ingest", { body: this.withDefaults(body) });
@@ -4870,23 +4877,70 @@ var ContextStreamClient = class {
4870
4877
  context.workspace_source = resolved.source;
4871
4878
  context.workspace_resolved_from = resolved.source === "local_config" ? `${rootPath}/.contextstream/config.json` : "parent_folder_mapping";
4872
4879
  } else {
4880
+ const folderName = rootPath?.split("/").pop()?.toLowerCase() || "";
4873
4881
  try {
4874
4882
  const workspaces = await this.listWorkspaces({ page_size: 50 });
4875
4883
  if (workspaces.items && workspaces.items.length > 0) {
4876
- context.status = "requires_workspace_selection";
4877
- context.workspace_candidates = workspaces.items.map((w) => ({
4878
- id: w.id,
4879
- name: w.name,
4880
- description: w.description
4881
- }));
4882
- context.message = `New folder detected: "${rootPath?.split("/").pop()}". Please select which workspace this belongs to, or create a new one.`;
4883
- context.ide_roots = ideRoots;
4884
- context.folder_name = rootPath?.split("/").pop();
4885
- return context;
4884
+ let matchedWorkspace;
4885
+ let matchSource;
4886
+ matchedWorkspace = workspaces.items.find(
4887
+ (w) => w.name.toLowerCase() === folderName
4888
+ );
4889
+ if (matchedWorkspace) {
4890
+ matchSource = "workspace_name_exact";
4891
+ }
4892
+ if (!matchedWorkspace) {
4893
+ matchedWorkspace = workspaces.items.find(
4894
+ (w) => w.name.toLowerCase().includes(folderName) || folderName.includes(w.name.toLowerCase())
4895
+ );
4896
+ if (matchedWorkspace) {
4897
+ matchSource = "workspace_name_partial";
4898
+ }
4899
+ }
4900
+ if (!matchedWorkspace) {
4901
+ for (const ws of workspaces.items) {
4902
+ try {
4903
+ const projects = await this.listProjects({ workspace_id: ws.id, page_size: 50 });
4904
+ const matchingProject = projects.items?.find(
4905
+ (p) => p.name.toLowerCase() === folderName || p.name.toLowerCase().includes(folderName) || folderName.includes(p.name.toLowerCase())
4906
+ );
4907
+ if (matchingProject) {
4908
+ matchedWorkspace = ws;
4909
+ matchSource = "project_name_match";
4910
+ projectId = matchingProject.id;
4911
+ context.project_source = "matched_existing";
4912
+ break;
4913
+ }
4914
+ } catch {
4915
+ }
4916
+ }
4917
+ }
4918
+ if (matchedWorkspace) {
4919
+ workspaceId = matchedWorkspace.id;
4920
+ workspaceName = matchedWorkspace.name;
4921
+ context.workspace_source = matchSource;
4922
+ context.workspace_auto_matched = true;
4923
+ writeLocalConfig(rootPath, {
4924
+ workspace_id: matchedWorkspace.id,
4925
+ workspace_name: matchedWorkspace.name,
4926
+ associated_at: (/* @__PURE__ */ new Date()).toISOString()
4927
+ });
4928
+ } else {
4929
+ context.status = "requires_workspace_selection";
4930
+ context.workspace_candidates = workspaces.items.map((w) => ({
4931
+ id: w.id,
4932
+ name: w.name,
4933
+ description: w.description
4934
+ }));
4935
+ context.message = `New folder detected: "${rootPath?.split("/").pop()}". Please select which workspace this belongs to, or create a new one.`;
4936
+ context.ide_roots = ideRoots;
4937
+ context.folder_name = rootPath?.split("/").pop();
4938
+ return context;
4939
+ }
4886
4940
  } else {
4887
4941
  const newWorkspace = await this.createWorkspace({
4888
- name: "My Workspace",
4889
- description: "Default workspace created by ContextStream",
4942
+ name: folderName || "My Workspace",
4943
+ description: `Workspace created for ${rootPath}`,
4890
4944
  visibility: "private"
4891
4945
  });
4892
4946
  if (newWorkspace.id) {
@@ -4922,10 +4976,22 @@ var ContextStreamClient = class {
4922
4976
  const projectName = rootPath.split("/").pop() || "My Project";
4923
4977
  try {
4924
4978
  const projects = await this.listProjects({ workspace_id: workspaceId });
4925
- const existingProject = projects.items?.find((p) => p.name === projectName);
4979
+ const projectNameLower = projectName.toLowerCase();
4980
+ let existingProject = projects.items?.find((p) => p.name.toLowerCase() === projectNameLower);
4981
+ if (existingProject) {
4982
+ context.project_match_type = "exact";
4983
+ } else {
4984
+ existingProject = projects.items?.find(
4985
+ (p) => p.name.toLowerCase().includes(projectNameLower) || projectNameLower.includes(p.name.toLowerCase())
4986
+ );
4987
+ if (existingProject) {
4988
+ context.project_match_type = "partial";
4989
+ }
4990
+ }
4926
4991
  if (existingProject) {
4927
4992
  projectId = existingProject.id;
4928
4993
  context.project_source = "existing";
4994
+ context.matched_project_name = existingProject.name;
4929
4995
  } else {
4930
4996
  const newProject = await this.createProject({
4931
4997
  name: projectName,
@@ -6340,7 +6406,29 @@ Use this to persist decisions, insights, preferences, or important information.`
6340
6406
  })
6341
6407
  },
6342
6408
  async (input) => {
6343
- const result = await client.captureContext(input);
6409
+ let workspaceId = input.workspace_id;
6410
+ let projectId = input.project_id;
6411
+ if (!workspaceId && sessionManager) {
6412
+ const ctx = sessionManager.getContext();
6413
+ if (ctx) {
6414
+ workspaceId = ctx.workspace_id;
6415
+ projectId = projectId || ctx.project_id;
6416
+ }
6417
+ }
6418
+ if (!workspaceId) {
6419
+ return {
6420
+ content: [{
6421
+ type: "text",
6422
+ text: "Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly."
6423
+ }],
6424
+ isError: true
6425
+ };
6426
+ }
6427
+ const result = await client.captureContext({
6428
+ ...input,
6429
+ workspace_id: workspaceId,
6430
+ project_id: projectId
6431
+ });
6344
6432
  return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
6345
6433
  }
6346
6434
  );
@@ -6359,7 +6447,20 @@ Returns memory matches, relevant code, and related decisions in one call.`,
6359
6447
  })
6360
6448
  },
6361
6449
  async (input) => {
6362
- const result = await client.smartSearch(input);
6450
+ let workspaceId = input.workspace_id;
6451
+ let projectId = input.project_id;
6452
+ if (!workspaceId && sessionManager) {
6453
+ const ctx = sessionManager.getContext();
6454
+ if (ctx) {
6455
+ workspaceId = ctx.workspace_id;
6456
+ projectId = projectId || ctx.project_id;
6457
+ }
6458
+ }
6459
+ const result = await client.smartSearch({
6460
+ ...input,
6461
+ workspace_id: workspaceId,
6462
+ project_id: projectId
6463
+ });
6363
6464
  return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
6364
6465
  }
6365
6466
  );
@@ -6377,6 +6478,21 @@ Example: "Remember that I prefer TypeScript strict mode" or "Remember we decided
6377
6478
  })
6378
6479
  },
6379
6480
  async (input) => {
6481
+ let workspaceId = input.workspace_id;
6482
+ let projectId = input.project_id;
6483
+ if (!workspaceId && sessionManager) {
6484
+ const ctx = sessionManager.getContext();
6485
+ if (ctx) {
6486
+ workspaceId = ctx.workspace_id;
6487
+ projectId = projectId || ctx.project_id;
6488
+ }
6489
+ }
6490
+ if (!workspaceId) {
6491
+ return {
6492
+ content: [{ type: "text", text: "Error: workspace_id is required. Please call session_init first." }],
6493
+ isError: true
6494
+ };
6495
+ }
6380
6496
  const lowerContent = input.content.toLowerCase();
6381
6497
  let eventType = "insight";
6382
6498
  if (lowerContent.includes("prefer") || lowerContent.includes("like") || lowerContent.includes("always")) {
@@ -6387,8 +6503,8 @@ Example: "Remember that I prefer TypeScript strict mode" or "Remember we decided
6387
6503
  eventType = "task";
6388
6504
  }
6389
6505
  const result = await client.captureContext({
6390
- workspace_id: input.workspace_id,
6391
- project_id: input.project_id,
6506
+ workspace_id: workspaceId,
6507
+ project_id: projectId,
6392
6508
  event_type: eventType,
6393
6509
  title: input.content.slice(0, 100),
6394
6510
  content: input.content,
@@ -6410,10 +6526,19 @@ Example: "What were the auth decisions?" or "What are my TypeScript preferences?
6410
6526
  })
6411
6527
  },
6412
6528
  async (input) => {
6529
+ let workspaceId = input.workspace_id;
6530
+ let projectId = input.project_id;
6531
+ if (!workspaceId && sessionManager) {
6532
+ const ctx = sessionManager.getContext();
6533
+ if (ctx) {
6534
+ workspaceId = ctx.workspace_id;
6535
+ projectId = projectId || ctx.project_id;
6536
+ }
6537
+ }
6413
6538
  const result = await client.smartSearch({
6414
6539
  query: input.query,
6415
- workspace_id: input.workspace_id,
6416
- project_id: input.project_id,
6540
+ workspace_id: workspaceId,
6541
+ project_id: projectId,
6417
6542
  include_decisions: true
6418
6543
  });
6419
6544
  return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contextstream/mcp-server",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
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",