@contextstream/mcp-server 0.4.13 → 0.4.16

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 +81 -39
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7453,6 +7453,7 @@ W:${wsHint}
7453
7453
  */
7454
7454
  async updateTask(params) {
7455
7455
  uuidSchema.parse(params.task_id);
7456
+ if (params.plan_id) uuidSchema.parse(params.plan_id);
7456
7457
  const { task_id, ...updates } = params;
7457
7458
  return request(this.config, `/tasks/${task_id}`, { method: "PATCH", body: updates });
7458
7459
  }
@@ -7635,6 +7636,23 @@ Only after this preflight, proceed with search/analysis below.
7635
7636
 
7636
7637
  ---
7637
7638
 
7639
+ ### Plans & Tasks
7640
+
7641
+ When user asks to create a plan or implementation roadmap:
7642
+ 1. Create plan: \`session(action="capture_plan", title="Plan Title", description="...", goals=["goal1", "goal2"], steps=[{id: "1", title: "Step 1", order: 1}, ...])\`
7643
+ 2. Get plan_id from response, then create tasks: \`memory(action="create_task", title="Task Title", plan_id="<plan_id>", priority="high|medium|low", description="...")\`
7644
+
7645
+ To manage existing plans/tasks:
7646
+ - List plans: \`session(action="list_plans")\`
7647
+ - Get plan with tasks: \`session(action="get_plan", plan_id="<uuid>", include_tasks=true)\`
7648
+ - List tasks: \`memory(action="list_tasks", plan_id="<uuid>")\` or \`memory(action="list_tasks")\` for all
7649
+ - Update task status: \`memory(action="update_task", task_id="<uuid>", task_status="pending|in_progress|completed|blocked")\`
7650
+ - Link task to plan: \`memory(action="update_task", task_id="<uuid>", plan_id="<plan_uuid>")\`
7651
+ - Unlink task from plan: \`memory(action="update_task", task_id="<uuid>", plan_id=null)\`
7652
+ - Delete: \`memory(action="delete_task", task_id="<uuid>")\` or \`memory(action="delete_event", event_id="<plan_uuid>")\`
7653
+
7654
+ ---
7655
+
7638
7656
  ### Complete Action Reference
7639
7657
 
7640
7658
  **session actions:**
@@ -7702,6 +7720,21 @@ v0.4.x uses ~11 consolidated domain tools for ~75% token reduction vs previous v
7702
7720
  - **After completing work**: Always capture decisions/insights with \`session(action="capture")\`
7703
7721
  - **On mistakes/corrections**: Immediately capture lessons with \`session(action="capture_lesson")\`
7704
7722
 
7723
+ ### Plans & Tasks
7724
+
7725
+ When user asks to create a plan or implementation roadmap:
7726
+ 1. Create plan: \`session(action="capture_plan", title="Plan Title", description="...", goals=["goal1", "goal2"], steps=[{id: "1", title: "Step 1", order: 1}, ...])\`
7727
+ 2. Get plan_id from response, then create tasks: \`memory(action="create_task", title="Task Title", plan_id="<plan_id>", priority="high|medium|low", description="...")\`
7728
+
7729
+ To manage existing plans/tasks:
7730
+ - List plans: \`session(action="list_plans")\`
7731
+ - Get plan with tasks: \`session(action="get_plan", plan_id="<uuid>", include_tasks=true)\`
7732
+ - List tasks: \`memory(action="list_tasks", plan_id="<uuid>")\` or \`memory(action="list_tasks")\` for all
7733
+ - Update task status: \`memory(action="update_task", task_id="<uuid>", task_status="pending|in_progress|completed|blocked")\`
7734
+ - Link task to plan: \`memory(action="update_task", task_id="<uuid>", plan_id="<plan_uuid>")\`
7735
+ - Unlink task from plan: \`memory(action="update_task", task_id="<uuid>", plan_id=null)\`
7736
+ - Delete: \`memory(action="delete_task", task_id="<uuid>")\` or \`memory(action="delete_event", event_id="<plan_uuid>")\`
7737
+
7705
7738
  Full docs: https://contextstream.io/docs/mcp/tools
7706
7739
  `.trim();
7707
7740
  var TEMPLATES = {
@@ -9387,6 +9420,30 @@ Upgrade: ${upgradeUrl2}` : "";
9387
9420
  }
9388
9421
  return { ok: true, resolvedPath };
9389
9422
  }
9423
+ function startBackgroundIngest(projectId, resolvedPath, ingestOptions, options = {}) {
9424
+ (async () => {
9425
+ try {
9426
+ if (options.preflight) {
9427
+ const fileCheck = await countIndexableFiles(resolvedPath, { maxFiles: 1 });
9428
+ if (fileCheck.count === 0) {
9429
+ console.error(`[ContextStream] No indexable files found in ${resolvedPath}. Skipping ingest.`);
9430
+ return;
9431
+ }
9432
+ }
9433
+ let totalIndexed = 0;
9434
+ let batchCount = 0;
9435
+ console.error(`[ContextStream] Starting background ingestion for project ${projectId} from ${resolvedPath}`);
9436
+ for await (const batch of readAllFilesInBatches(resolvedPath, { batchSize: 50 })) {
9437
+ const result = await client.ingestFiles(projectId, batch, ingestOptions);
9438
+ totalIndexed += result.data?.files_indexed ?? batch.length;
9439
+ batchCount++;
9440
+ }
9441
+ console.error(`[ContextStream] Completed background ingestion: ${totalIndexed} files in ${batchCount} batches`);
9442
+ } catch (error) {
9443
+ console.error(`[ContextStream] Ingestion failed:`, error);
9444
+ }
9445
+ })();
9446
+ }
9390
9447
  registerTool(
9391
9448
  "mcp_server_version",
9392
9449
  {
@@ -10323,7 +10380,8 @@ ${formatContent(result)}`
10323
10380
  title: "Ingest local files",
10324
10381
  description: `Read ALL files from a local directory and ingest them for indexing.
10325
10382
  This indexes your entire project by reading files in batches.
10326
- Automatically detects code files and skips ignored directories like node_modules, target, dist, etc.`,
10383
+ Automatically detects code files and skips ignored directories like node_modules, target, dist, etc.
10384
+ Runs in the background and returns immediately; use 'projects_index_status' to monitor progress.`,
10327
10385
  inputSchema: external_exports.object({
10328
10386
  project_id: external_exports.string().uuid().optional().describe("Project to ingest files into (defaults to current session project)"),
10329
10387
  path: external_exports.string().describe("Local directory path to read files from"),
@@ -10340,31 +10398,11 @@ Automatically detects code files and skips ignored directories like node_modules
10340
10398
  if (!pathCheck.ok) {
10341
10399
  return errorResult(pathCheck.error);
10342
10400
  }
10343
- const fileCheck = await countIndexableFiles(pathCheck.resolvedPath, { maxFiles: 1 });
10344
- if (fileCheck.count === 0) {
10345
- return errorResult(
10346
- `Error: no indexable files found in directory: ${input.path}. The directory may be empty or contain only ignored files/directories. Supported file types include: .ts, .js, .py, .rs, .go, .java, .md, .json, etc.`
10347
- );
10348
- }
10349
10401
  const ingestOptions = {
10350
10402
  ...input.write_to_disk !== void 0 && { write_to_disk: input.write_to_disk },
10351
10403
  ...input.overwrite !== void 0 && { overwrite: input.overwrite }
10352
10404
  };
10353
- (async () => {
10354
- try {
10355
- let totalIndexed = 0;
10356
- let batchCount = 0;
10357
- console.error(`[ContextStream] Starting background ingestion for project ${projectId} from ${pathCheck.resolvedPath}`);
10358
- for await (const batch of readAllFilesInBatches(pathCheck.resolvedPath, { batchSize: 50 })) {
10359
- const result = await client.ingestFiles(projectId, batch, ingestOptions);
10360
- totalIndexed += result.data?.files_indexed ?? batch.length;
10361
- batchCount++;
10362
- }
10363
- console.error(`[ContextStream] Completed background ingestion: ${totalIndexed} files in ${batchCount} batches`);
10364
- } catch (error) {
10365
- console.error(`[ContextStream] Ingestion failed:`, error);
10366
- }
10367
- })();
10405
+ startBackgroundIngest(projectId, pathCheck.resolvedPath, ingestOptions, { preflight: true });
10368
10406
  const summary = {
10369
10407
  status: "started",
10370
10408
  message: "Ingestion running in background",
@@ -12864,7 +12902,7 @@ Use this to remove a reminder that is no longer relevant.`,
12864
12902
  "memory",
12865
12903
  {
12866
12904
  title: "Memory",
12867
- description: `Memory operations for events and nodes. Event actions: create_event, get_event, update_event, delete_event, list_events, distill_event. Node actions: create_node, get_node, update_node, delete_node, list_nodes, supersede_node. Query actions: search, decisions, timeline, summary. Task actions: create_task (create task, optionally linked to plan), get_task, update_task, delete_task, list_tasks, reorder_tasks.`,
12905
+ description: `Memory operations for events and nodes. Event actions: create_event, get_event, update_event, delete_event, list_events, distill_event. Node actions: create_node, get_node, update_node, delete_node, list_nodes, supersede_node. Query actions: search, decisions, timeline, summary. Task actions: create_task (create task, optionally linked to plan), get_task, update_task (can link/unlink task to plan via plan_id), delete_task, list_tasks, reorder_tasks.`,
12868
12906
  inputSchema: external_exports.object({
12869
12907
  action: external_exports.enum([
12870
12908
  "create_event",
@@ -12928,7 +12966,7 @@ Use this to remove a reminder that is no longer relevant.`,
12928
12966
  })).optional(),
12929
12967
  // Task-specific params
12930
12968
  task_id: external_exports.string().uuid().optional().describe("Task ID for get_task/update_task/delete_task"),
12931
- plan_id: external_exports.string().uuid().optional().describe("Parent plan ID for create_task/list_tasks"),
12969
+ plan_id: external_exports.string().uuid().nullable().optional().describe("Plan ID: for create_task (link to plan), update_task (set UUID to link, null to unlink), list_tasks (filter by plan)"),
12932
12970
  plan_step_id: external_exports.string().optional().describe("Which plan step this task implements"),
12933
12971
  description: external_exports.string().optional().describe("Description for task"),
12934
12972
  task_status: external_exports.enum(["pending", "in_progress", "completed", "blocked", "cancelled"]).optional().describe("Task status"),
@@ -13135,6 +13173,7 @@ Use this to remove a reminder that is no longer relevant.`,
13135
13173
  status: input.task_status,
13136
13174
  priority: input.priority,
13137
13175
  order: input.order,
13176
+ plan_id: input.plan_id,
13138
13177
  plan_step_id: input.plan_step_id,
13139
13178
  code_refs: input.code_refs,
13140
13179
  tags: input.tags,
@@ -13455,24 +13494,27 @@ Use this to remove a reminder that is no longer relevant.`,
13455
13494
  if (!validPath.ok) {
13456
13495
  return errorResult(validPath.error);
13457
13496
  }
13458
- let totalFiles = 0;
13459
- let batches = 0;
13460
- for await (const batch of readAllFilesInBatches(validPath.resolvedPath, { batchSize: 50 })) {
13461
- if (batch.length === 0) continue;
13462
- await client.ingestFiles(projectId, batch, {
13463
- overwrite: input.overwrite,
13464
- write_to_disk: input.write_to_disk
13465
- });
13466
- totalFiles += batch.length;
13467
- batches += 1;
13468
- }
13497
+ const ingestOptions = {
13498
+ ...input.write_to_disk !== void 0 && { write_to_disk: input.write_to_disk },
13499
+ ...input.overwrite !== void 0 && { overwrite: input.overwrite }
13500
+ };
13501
+ startBackgroundIngest(projectId, validPath.resolvedPath, ingestOptions);
13469
13502
  const result = {
13503
+ status: "started",
13504
+ message: "Ingestion running in background",
13470
13505
  project_id: projectId,
13471
- files_ingested: totalFiles,
13472
- batches,
13473
- path: validPath.resolvedPath
13506
+ path: validPath.resolvedPath,
13507
+ ...input.write_to_disk !== void 0 && { write_to_disk: input.write_to_disk },
13508
+ ...input.overwrite !== void 0 && { overwrite: input.overwrite },
13509
+ note: "Use 'project' with action 'index_status' to monitor progress."
13510
+ };
13511
+ return {
13512
+ content: [{
13513
+ type: "text",
13514
+ text: `Ingestion started in background for directory: ${validPath.resolvedPath}. Use 'project' with action 'index_status' to monitor progress.`
13515
+ }],
13516
+ structuredContent: toStructured(result)
13474
13517
  };
13475
- return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
13476
13518
  }
13477
13519
  default:
13478
13520
  return errorResult(`Unknown action: ${input.action}`);
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.13",
4
+ "version": "0.4.16",
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",