@contextstream/mcp-server 0.4.9 → 0.4.11
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 +4 -3
- package/dist/index.js +458 -27
- package/dist/test-server.js +14 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -323,9 +323,10 @@ Set **one** of:
|
|
|
323
323
|
|
|
324
324
|
| Variable | Description |
|
|
325
325
|
|----------|-------------|
|
|
326
|
-
| `CONTEXTSTREAM_CONSOLIDATED` | `true` (default in v0.4.x) uses consolidated domain tools |
|
|
327
|
-
| `CONTEXTSTREAM_PROGRESSIVE_MODE` | Enables Router mode (~2 meta-tools) |
|
|
328
|
-
| `
|
|
326
|
+
| `CONTEXTSTREAM_CONSOLIDATED` | `true` (default in v0.4.x) uses consolidated domain tools |
|
|
327
|
+
| `CONTEXTSTREAM_PROGRESSIVE_MODE` | Enables Router mode (~2 meta-tools) |
|
|
328
|
+
| `CONTEXTSTREAM_CONTEXT_PACK` | Enable Context Pack for `context_smart` (code + graph + distill). Defaults to `true` |
|
|
329
|
+
| `CONTEXTSTREAM_TOOLSET` | Legacy granular tool bundle: `light` / `standard` / `complete` (only when consolidated is off) |
|
|
329
330
|
| `CONTEXTSTREAM_TOOL_ALLOWLIST` | Comma-separated tool names to expose (legacy granular mode) |
|
|
330
331
|
| `CONTEXTSTREAM_SCHEMA_MODE` | Reduce schema verbosity; e.g., `compact` |
|
|
331
332
|
| `CONTEXTSTREAM_OUTPUT_FORMAT` | Output formatting; e.g., `compact` / `pretty` |
|
package/dist/index.js
CHANGED
|
@@ -4052,6 +4052,13 @@ var NEVER = INVALID;
|
|
|
4052
4052
|
|
|
4053
4053
|
// src/config.ts
|
|
4054
4054
|
var DEFAULT_API_URL = "https://api.contextstream.io";
|
|
4055
|
+
function parseBooleanEnv(value) {
|
|
4056
|
+
if (value === void 0) return void 0;
|
|
4057
|
+
const normalized = value.trim().toLowerCase();
|
|
4058
|
+
if (["1", "true", "yes", "on"].includes(normalized)) return true;
|
|
4059
|
+
if (["0", "false", "no", "off"].includes(normalized)) return false;
|
|
4060
|
+
return void 0;
|
|
4061
|
+
}
|
|
4055
4062
|
var configSchema = external_exports.object({
|
|
4056
4063
|
apiUrl: external_exports.string().url().default(DEFAULT_API_URL),
|
|
4057
4064
|
apiKey: external_exports.string().min(1).optional(),
|
|
@@ -4059,7 +4066,8 @@ var configSchema = external_exports.object({
|
|
|
4059
4066
|
defaultWorkspaceId: external_exports.string().uuid().optional(),
|
|
4060
4067
|
defaultProjectId: external_exports.string().uuid().optional(),
|
|
4061
4068
|
userAgent: external_exports.string().default("contextstream-mcp/0.1.0"),
|
|
4062
|
-
allowHeaderAuth: external_exports.boolean().optional()
|
|
4069
|
+
allowHeaderAuth: external_exports.boolean().optional(),
|
|
4070
|
+
contextPackEnabled: external_exports.boolean().default(true)
|
|
4063
4071
|
});
|
|
4064
4072
|
var MISSING_CREDENTIALS_ERROR = "Set CONTEXTSTREAM_API_KEY or CONTEXTSTREAM_JWT for authentication (or CONTEXTSTREAM_ALLOW_HEADER_AUTH=true for header-based auth).";
|
|
4065
4073
|
function isMissingCredentialsError(err) {
|
|
@@ -4070,6 +4078,9 @@ function isMissingCredentialsError(err) {
|
|
|
4070
4078
|
}
|
|
4071
4079
|
function loadConfig() {
|
|
4072
4080
|
const allowHeaderAuth = process.env.CONTEXTSTREAM_ALLOW_HEADER_AUTH === "1" || process.env.CONTEXTSTREAM_ALLOW_HEADER_AUTH === "true" || process.env.CONTEXTSTREAM_ALLOW_HEADER_AUTH === "yes";
|
|
4081
|
+
const contextPackEnabled = parseBooleanEnv(
|
|
4082
|
+
process.env.CONTEXTSTREAM_CONTEXT_PACK ?? process.env.CONTEXTSTREAM_CONTEXT_PACK_ENABLED
|
|
4083
|
+
);
|
|
4073
4084
|
const parsed = configSchema.safeParse({
|
|
4074
4085
|
apiUrl: process.env.CONTEXTSTREAM_API_URL,
|
|
4075
4086
|
apiKey: process.env.CONTEXTSTREAM_API_KEY,
|
|
@@ -4077,7 +4088,8 @@ function loadConfig() {
|
|
|
4077
4088
|
defaultWorkspaceId: process.env.CONTEXTSTREAM_WORKSPACE_ID,
|
|
4078
4089
|
defaultProjectId: process.env.CONTEXTSTREAM_PROJECT_ID,
|
|
4079
4090
|
userAgent: process.env.CONTEXTSTREAM_USER_AGENT,
|
|
4080
|
-
allowHeaderAuth
|
|
4091
|
+
allowHeaderAuth,
|
|
4092
|
+
contextPackEnabled
|
|
4081
4093
|
});
|
|
4082
4094
|
if (!parsed.success) {
|
|
4083
4095
|
const missing = parsed.error.errors.map((e) => e.path.join(".")).join(", ");
|
|
@@ -6552,6 +6564,8 @@ var ContextStreamClient = class {
|
|
|
6552
6564
|
const withDefaults = this.withDefaults(params);
|
|
6553
6565
|
const maxTokens = params.max_tokens || 800;
|
|
6554
6566
|
const format = params.format || "minified";
|
|
6567
|
+
const usePackDefault = this.config.contextPackEnabled !== false && !!withDefaults.project_id;
|
|
6568
|
+
const mode = params.mode || (usePackDefault ? "pack" : "standard");
|
|
6555
6569
|
if (!withDefaults.workspace_id) {
|
|
6556
6570
|
return {
|
|
6557
6571
|
context: "[NO_WORKSPACE]",
|
|
@@ -6560,6 +6574,38 @@ var ContextStreamClient = class {
|
|
|
6560
6574
|
sources_used: 0
|
|
6561
6575
|
};
|
|
6562
6576
|
}
|
|
6577
|
+
try {
|
|
6578
|
+
const apiResult = await request(this.config, "/context/smart", {
|
|
6579
|
+
body: {
|
|
6580
|
+
user_message: params.user_message,
|
|
6581
|
+
workspace_id: withDefaults.workspace_id,
|
|
6582
|
+
project_id: withDefaults.project_id,
|
|
6583
|
+
max_tokens: maxTokens,
|
|
6584
|
+
format,
|
|
6585
|
+
mode,
|
|
6586
|
+
distill: params.distill
|
|
6587
|
+
}
|
|
6588
|
+
});
|
|
6589
|
+
const data = unwrapApiResponse(apiResult);
|
|
6590
|
+
let versionNotice2 = null;
|
|
6591
|
+
try {
|
|
6592
|
+
versionNotice2 = await getUpdateNotice();
|
|
6593
|
+
} catch {
|
|
6594
|
+
}
|
|
6595
|
+
return {
|
|
6596
|
+
context: String(data?.context ?? ""),
|
|
6597
|
+
token_estimate: Number(data?.token_estimate ?? Math.ceil(String(data?.context ?? "").length / 4)),
|
|
6598
|
+
format: String(data?.format ?? format),
|
|
6599
|
+
sources_used: Number(data?.sources_used ?? 0),
|
|
6600
|
+
workspace_id: withDefaults.workspace_id,
|
|
6601
|
+
project_id: withDefaults.project_id,
|
|
6602
|
+
...versionNotice2 ? { version_notice: versionNotice2 } : {},
|
|
6603
|
+
...Array.isArray(data?.errors) ? { errors: data.errors } : {}
|
|
6604
|
+
};
|
|
6605
|
+
} catch (err) {
|
|
6606
|
+
const message2 = err instanceof Error ? err.message : String(err);
|
|
6607
|
+
console.warn(`[ContextStream] context_smart remote failed, using local fallback: ${message2}`);
|
|
6608
|
+
}
|
|
6563
6609
|
const message = params.user_message.toLowerCase();
|
|
6564
6610
|
const keywords = this.extractKeywords(message);
|
|
6565
6611
|
const items = [];
|
|
@@ -7288,6 +7334,131 @@ W:${wsHint}
|
|
|
7288
7334
|
uuidSchema.parse(params.reminder_id);
|
|
7289
7335
|
return request(this.config, `/reminders/${params.reminder_id}`, { method: "DELETE" });
|
|
7290
7336
|
}
|
|
7337
|
+
// ============================================
|
|
7338
|
+
// Plans & Tasks
|
|
7339
|
+
// ============================================
|
|
7340
|
+
/**
|
|
7341
|
+
* Create a new implementation plan
|
|
7342
|
+
*/
|
|
7343
|
+
async createPlan(params) {
|
|
7344
|
+
const withDefaults = this.withDefaults(params);
|
|
7345
|
+
if (!withDefaults.workspace_id) {
|
|
7346
|
+
throw new Error("workspace_id is required for creating plans");
|
|
7347
|
+
}
|
|
7348
|
+
return request(this.config, "/plans", { body: withDefaults });
|
|
7349
|
+
}
|
|
7350
|
+
/**
|
|
7351
|
+
* List plans with optional filters
|
|
7352
|
+
*/
|
|
7353
|
+
async listPlans(params) {
|
|
7354
|
+
const withDefaults = this.withDefaults(params || {});
|
|
7355
|
+
const query = new URLSearchParams();
|
|
7356
|
+
if (withDefaults.workspace_id) query.set("workspace_id", withDefaults.workspace_id);
|
|
7357
|
+
if (withDefaults.project_id) query.set("project_id", withDefaults.project_id);
|
|
7358
|
+
if (params?.status) query.set("status", params.status);
|
|
7359
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
7360
|
+
if (params?.offset) query.set("offset", String(params.offset));
|
|
7361
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
7362
|
+
return request(this.config, `/plans${suffix}`, { method: "GET" });
|
|
7363
|
+
}
|
|
7364
|
+
/**
|
|
7365
|
+
* Get a plan by ID, optionally including its tasks
|
|
7366
|
+
*/
|
|
7367
|
+
async getPlan(params) {
|
|
7368
|
+
uuidSchema.parse(params.plan_id);
|
|
7369
|
+
const query = new URLSearchParams();
|
|
7370
|
+
if (params.include_tasks !== false) query.set("include_tasks", "true");
|
|
7371
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
7372
|
+
return request(this.config, `/plans/${params.plan_id}${suffix}`, { method: "GET" });
|
|
7373
|
+
}
|
|
7374
|
+
/**
|
|
7375
|
+
* Update an existing plan
|
|
7376
|
+
*/
|
|
7377
|
+
async updatePlan(params) {
|
|
7378
|
+
uuidSchema.parse(params.plan_id);
|
|
7379
|
+
const { plan_id, ...updates } = params;
|
|
7380
|
+
return request(this.config, `/plans/${plan_id}`, { method: "PATCH", body: updates });
|
|
7381
|
+
}
|
|
7382
|
+
/**
|
|
7383
|
+
* Delete a plan
|
|
7384
|
+
*/
|
|
7385
|
+
async deletePlan(params) {
|
|
7386
|
+
uuidSchema.parse(params.plan_id);
|
|
7387
|
+
return request(this.config, `/plans/${params.plan_id}`, { method: "DELETE" });
|
|
7388
|
+
}
|
|
7389
|
+
/**
|
|
7390
|
+
* Get tasks for a specific plan
|
|
7391
|
+
*/
|
|
7392
|
+
async getPlanTasks(params) {
|
|
7393
|
+
uuidSchema.parse(params.plan_id);
|
|
7394
|
+
return request(this.config, `/plans/${params.plan_id}/tasks`, { method: "GET" });
|
|
7395
|
+
}
|
|
7396
|
+
/**
|
|
7397
|
+
* Create a task within a plan
|
|
7398
|
+
*/
|
|
7399
|
+
async createPlanTask(params) {
|
|
7400
|
+
uuidSchema.parse(params.plan_id);
|
|
7401
|
+
const { plan_id, ...taskData } = params;
|
|
7402
|
+
return request(this.config, `/plans/${plan_id}/tasks`, { body: taskData });
|
|
7403
|
+
}
|
|
7404
|
+
/**
|
|
7405
|
+
* Reorder tasks within a plan
|
|
7406
|
+
*/
|
|
7407
|
+
async reorderPlanTasks(params) {
|
|
7408
|
+
uuidSchema.parse(params.plan_id);
|
|
7409
|
+
return request(this.config, `/plans/${params.plan_id}/tasks/reorder`, {
|
|
7410
|
+
method: "PATCH",
|
|
7411
|
+
body: { task_ids: params.task_ids }
|
|
7412
|
+
});
|
|
7413
|
+
}
|
|
7414
|
+
/**
|
|
7415
|
+
* Create a standalone task (optionally linked to a plan)
|
|
7416
|
+
*/
|
|
7417
|
+
async createTask(params) {
|
|
7418
|
+
const withDefaults = this.withDefaults(params);
|
|
7419
|
+
if (!withDefaults.workspace_id) {
|
|
7420
|
+
throw new Error("workspace_id is required for creating tasks");
|
|
7421
|
+
}
|
|
7422
|
+
return request(this.config, "/tasks", { body: withDefaults });
|
|
7423
|
+
}
|
|
7424
|
+
/**
|
|
7425
|
+
* List tasks with optional filters
|
|
7426
|
+
*/
|
|
7427
|
+
async listTasks(params) {
|
|
7428
|
+
const withDefaults = this.withDefaults(params || {});
|
|
7429
|
+
const query = new URLSearchParams();
|
|
7430
|
+
if (withDefaults.workspace_id) query.set("workspace_id", withDefaults.workspace_id);
|
|
7431
|
+
if (withDefaults.project_id) query.set("project_id", withDefaults.project_id);
|
|
7432
|
+
if (params?.plan_id) query.set("plan_id", params.plan_id);
|
|
7433
|
+
if (params?.status) query.set("status", params.status);
|
|
7434
|
+
if (params?.priority) query.set("priority", params.priority);
|
|
7435
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
7436
|
+
if (params?.offset) query.set("offset", String(params.offset));
|
|
7437
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
7438
|
+
return request(this.config, `/tasks${suffix}`, { method: "GET" });
|
|
7439
|
+
}
|
|
7440
|
+
/**
|
|
7441
|
+
* Get a task by ID
|
|
7442
|
+
*/
|
|
7443
|
+
async getTask(params) {
|
|
7444
|
+
uuidSchema.parse(params.task_id);
|
|
7445
|
+
return request(this.config, `/tasks/${params.task_id}`, { method: "GET" });
|
|
7446
|
+
}
|
|
7447
|
+
/**
|
|
7448
|
+
* Update an existing task
|
|
7449
|
+
*/
|
|
7450
|
+
async updateTask(params) {
|
|
7451
|
+
uuidSchema.parse(params.task_id);
|
|
7452
|
+
const { task_id, ...updates } = params;
|
|
7453
|
+
return request(this.config, `/tasks/${task_id}`, { method: "PATCH", body: updates });
|
|
7454
|
+
}
|
|
7455
|
+
/**
|
|
7456
|
+
* Delete a task
|
|
7457
|
+
*/
|
|
7458
|
+
async deleteTask(params) {
|
|
7459
|
+
uuidSchema.parse(params.task_id);
|
|
7460
|
+
return request(this.config, `/tasks/${params.task_id}`, { method: "DELETE" });
|
|
7461
|
+
}
|
|
7291
7462
|
};
|
|
7292
7463
|
|
|
7293
7464
|
// src/tools.ts
|
|
@@ -7345,6 +7516,8 @@ v0.4.x uses **~11 consolidated domain tools** for ~75% token reduction vs previo
|
|
|
7345
7516
|
|
|
7346
7517
|
**NO EXCEPTIONS.** Do not skip even if you think you have enough context.
|
|
7347
7518
|
|
|
7519
|
+
**Context Pack (Pro+):** If enabled, use \`context_smart(..., mode="pack", distill=true)\` for code/file queries. If unavailable, omit \`mode\` and use standard \`context_smart\`.
|
|
7520
|
+
|
|
7348
7521
|
---
|
|
7349
7522
|
|
|
7350
7523
|
## Consolidated Domain Tools Architecture
|
|
@@ -7408,6 +7581,18 @@ If context still feels missing, use \`session(action="recall", query="...")\` fo
|
|
|
7408
7581
|
|
|
7409
7582
|
---
|
|
7410
7583
|
|
|
7584
|
+
### Index & Graph Preflight (REQUIRED for code/file search)
|
|
7585
|
+
|
|
7586
|
+
Before searching files or code, confirm the project is indexed and the graph is available:
|
|
7587
|
+
|
|
7588
|
+
1. \`project(action="index_status")\` for the current project
|
|
7589
|
+
2. If missing/stale:
|
|
7590
|
+
- Local repo: \`project(action="ingest_local", path="<cwd>")\`
|
|
7591
|
+
- Otherwise: \`project(action="index")\`
|
|
7592
|
+
3. If graph queries are empty/unavailable: \`graph(action="ingest")\`
|
|
7593
|
+
|
|
7594
|
+
Only after this preflight, proceed with search/analysis below.
|
|
7595
|
+
|
|
7411
7596
|
### Search & Code Intelligence (ContextStream-first)
|
|
7412
7597
|
|
|
7413
7598
|
**Search order:**
|
|
@@ -7488,6 +7673,8 @@ v0.4.x uses ~11 consolidated domain tools for ~75% token reduction vs previous v
|
|
|
7488
7673
|
| **Before risky work** | \`session(action="get_lessons", query="<topic>")\` |
|
|
7489
7674
|
| **On user frustration** | \`session(action="capture_lesson", title="...", trigger="...", impact="...", prevention="...")\` |
|
|
7490
7675
|
|
|
7676
|
+
**Context Pack (Pro+):** If enabled, use \`context_smart(..., mode="pack", distill=true)\` for code/file queries. If unavailable, omit \`mode\`.
|
|
7677
|
+
|
|
7491
7678
|
### Quick Reference: Domain Tools
|
|
7492
7679
|
|
|
7493
7680
|
| Tool | Common Usage |
|
|
@@ -7505,6 +7692,7 @@ v0.4.x uses ~11 consolidated domain tools for ~75% token reduction vs previous v
|
|
|
7505
7692
|
|
|
7506
7693
|
- **First message**: Always call \`session_init\` with context_hint
|
|
7507
7694
|
- **Every message after**: Always call \`context_smart\` BEFORE responding (semantic search for relevant context)
|
|
7695
|
+
- **Before searching files/code**: Check \`project(action="index_status")\`; if missing/stale run \`project(action="ingest_local", path="<cwd>")\` or \`project(action="index")\`, and use \`graph(action="ingest")\` if needed
|
|
7508
7696
|
- **For discovery**: Use \`session(action="smart_search")\` or \`search(mode="hybrid")\` before local repo scans
|
|
7509
7697
|
- **For code analysis**: Use \`graph(action="dependencies")\` or \`graph(action="impact")\` for call/dependency analysis
|
|
7510
7698
|
- **After completing work**: Always capture decisions/insights with \`session(action="capture")\`
|
|
@@ -7630,7 +7818,12 @@ var TOOL_CATALOG = [
|
|
|
7630
7818
|
{ name: "get_lessons", hint: "learn" },
|
|
7631
7819
|
{ name: "capture_lesson", hint: "mistake" },
|
|
7632
7820
|
{ name: "get_user_context", hint: "prefs" },
|
|
7633
|
-
{ name: "smart_search", hint: "deep-find" }
|
|
7821
|
+
{ name: "smart_search", hint: "deep-find" },
|
|
7822
|
+
// Plan actions
|
|
7823
|
+
{ name: "capture_plan", hint: "save-plan" },
|
|
7824
|
+
{ name: "get_plan", hint: "get-plan" },
|
|
7825
|
+
{ name: "update_plan", hint: "edit-plan" },
|
|
7826
|
+
{ name: "list_plans", hint: "list-plans" }
|
|
7634
7827
|
]
|
|
7635
7828
|
},
|
|
7636
7829
|
{
|
|
@@ -7653,7 +7846,14 @@ var TOOL_CATALOG = [
|
|
|
7653
7846
|
{ name: "search", hint: "find" },
|
|
7654
7847
|
{ name: "decisions", hint: "choices" },
|
|
7655
7848
|
{ name: "timeline", hint: "history" },
|
|
7656
|
-
{ name: "distill_event", hint: "extract" }
|
|
7849
|
+
{ name: "distill_event", hint: "extract" },
|
|
7850
|
+
// Task actions
|
|
7851
|
+
{ name: "create_task", hint: "new-task" },
|
|
7852
|
+
{ name: "get_task", hint: "get-task" },
|
|
7853
|
+
{ name: "update_task", hint: "edit-task" },
|
|
7854
|
+
{ name: "delete_task", hint: "rm-task" },
|
|
7855
|
+
{ name: "list_tasks", hint: "list-tasks" },
|
|
7856
|
+
{ name: "reorder_tasks", hint: "sort-tasks" }
|
|
7657
7857
|
]
|
|
7658
7858
|
},
|
|
7659
7859
|
{
|
|
@@ -11478,6 +11678,9 @@ Format options:
|
|
|
11478
11678
|
|
|
11479
11679
|
Type codes: W=Workspace, P=Project, D=Decision, M=Memory, I=Insight, T=Task, L=Lesson
|
|
11480
11680
|
|
|
11681
|
+
Context Pack:
|
|
11682
|
+
- mode='pack' adds code context + distillation (higher credit cost)
|
|
11683
|
+
|
|
11481
11684
|
Example usage:
|
|
11482
11685
|
1. User asks "how should I implement auth?"
|
|
11483
11686
|
2. AI calls context_smart(user_message="how should I implement auth?")
|
|
@@ -11490,7 +11693,9 @@ This saves ~80% tokens compared to including full chat history.`,
|
|
|
11490
11693
|
workspace_id: external_exports.string().uuid().optional(),
|
|
11491
11694
|
project_id: external_exports.string().uuid().optional(),
|
|
11492
11695
|
max_tokens: external_exports.number().optional().describe("Maximum tokens for context (default: 800)"),
|
|
11493
|
-
format: external_exports.enum(["minified", "readable", "structured"]).optional().describe("Context format (default: minified)")
|
|
11696
|
+
format: external_exports.enum(["minified", "readable", "structured"]).optional().describe("Context format (default: minified)"),
|
|
11697
|
+
mode: external_exports.enum(["standard", "pack"]).optional().describe("Context pack mode (default: pack when enabled)"),
|
|
11698
|
+
distill: external_exports.boolean().optional().describe("Use distillation for context pack (default: true)")
|
|
11494
11699
|
})
|
|
11495
11700
|
},
|
|
11496
11701
|
async (input) => {
|
|
@@ -11511,7 +11716,9 @@ This saves ~80% tokens compared to including full chat history.`,
|
|
|
11511
11716
|
workspace_id: workspaceId,
|
|
11512
11717
|
project_id: projectId,
|
|
11513
11718
|
max_tokens: input.max_tokens,
|
|
11514
|
-
format: input.format
|
|
11719
|
+
format: input.format,
|
|
11720
|
+
mode: input.mode,
|
|
11721
|
+
distill: input.distill
|
|
11515
11722
|
});
|
|
11516
11723
|
const footer = `
|
|
11517
11724
|
---
|
|
@@ -12344,7 +12551,7 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12344
12551
|
"session",
|
|
12345
12552
|
{
|
|
12346
12553
|
title: "Session",
|
|
12347
|
-
description: `Session management operations. Actions: capture (save decision/insight), capture_lesson (save lesson from mistake), get_lessons (retrieve lessons), recall (natural language recall), remember (quick save), user_context (get preferences), summary (workspace summary), compress (compress chat), delta (changes since timestamp), smart_search (context-enriched search), decision_trace (trace decision provenance).`,
|
|
12554
|
+
description: `Session management operations. Actions: capture (save decision/insight), capture_lesson (save lesson from mistake), get_lessons (retrieve lessons), recall (natural language recall), remember (quick save), user_context (get preferences), summary (workspace summary), compress (compress chat), delta (changes since timestamp), smart_search (context-enriched search), decision_trace (trace decision provenance). Plan actions: capture_plan (save implementation plan), get_plan (retrieve plan with tasks), update_plan (modify plan), list_plans (list all plans).`,
|
|
12348
12555
|
inputSchema: external_exports.object({
|
|
12349
12556
|
action: external_exports.enum([
|
|
12350
12557
|
"capture",
|
|
@@ -12357,14 +12564,19 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12357
12564
|
"compress",
|
|
12358
12565
|
"delta",
|
|
12359
12566
|
"smart_search",
|
|
12360
|
-
"decision_trace"
|
|
12567
|
+
"decision_trace",
|
|
12568
|
+
// Plan actions
|
|
12569
|
+
"capture_plan",
|
|
12570
|
+
"get_plan",
|
|
12571
|
+
"update_plan",
|
|
12572
|
+
"list_plans"
|
|
12361
12573
|
]).describe("Action to perform"),
|
|
12362
12574
|
workspace_id: external_exports.string().uuid().optional(),
|
|
12363
12575
|
project_id: external_exports.string().uuid().optional(),
|
|
12364
12576
|
// Content params
|
|
12365
12577
|
query: external_exports.string().optional().describe("Query for recall/search/lessons/decision_trace"),
|
|
12366
12578
|
content: external_exports.string().optional().describe("Content for capture/remember/compress"),
|
|
12367
|
-
title: external_exports.string().optional().describe("Title for capture/capture_lesson"),
|
|
12579
|
+
title: external_exports.string().optional().describe("Title for capture/capture_lesson/capture_plan"),
|
|
12368
12580
|
event_type: external_exports.enum(["decision", "preference", "insight", "task", "bug", "feature", "correction", "lesson", "warning", "frustration", "conversation"]).optional().describe("Event type for capture"),
|
|
12369
12581
|
importance: external_exports.enum(["low", "medium", "high", "critical"]).optional(),
|
|
12370
12582
|
tags: external_exports.array(external_exports.string()).optional(),
|
|
@@ -12395,7 +12607,22 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12395
12607
|
pr_url: external_exports.string().url().optional(),
|
|
12396
12608
|
issue_url: external_exports.string().url().optional(),
|
|
12397
12609
|
slack_thread_url: external_exports.string().url().optional()
|
|
12398
|
-
}).optional()
|
|
12610
|
+
}).optional(),
|
|
12611
|
+
// Plan-specific params
|
|
12612
|
+
plan_id: external_exports.string().uuid().optional().describe("Plan ID for get_plan/update_plan"),
|
|
12613
|
+
description: external_exports.string().optional().describe("Description for capture_plan"),
|
|
12614
|
+
goals: external_exports.array(external_exports.string()).optional().describe("Goals for capture_plan"),
|
|
12615
|
+
steps: external_exports.array(external_exports.object({
|
|
12616
|
+
id: external_exports.string(),
|
|
12617
|
+
title: external_exports.string(),
|
|
12618
|
+
description: external_exports.string().optional(),
|
|
12619
|
+
order: external_exports.number(),
|
|
12620
|
+
estimated_effort: external_exports.enum(["small", "medium", "large"]).optional()
|
|
12621
|
+
})).optional().describe("Implementation steps for capture_plan"),
|
|
12622
|
+
status: external_exports.enum(["draft", "active", "completed", "archived", "abandoned"]).optional().describe("Plan status"),
|
|
12623
|
+
due_at: external_exports.string().optional().describe("Due date for plan (ISO timestamp)"),
|
|
12624
|
+
source_tool: external_exports.string().optional().describe("Tool that generated this plan"),
|
|
12625
|
+
include_tasks: external_exports.boolean().optional().describe("Include tasks when getting plan")
|
|
12399
12626
|
})
|
|
12400
12627
|
},
|
|
12401
12628
|
async (input) => {
|
|
@@ -12559,6 +12786,68 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12559
12786
|
});
|
|
12560
12787
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
12561
12788
|
}
|
|
12789
|
+
// Plan actions
|
|
12790
|
+
case "capture_plan": {
|
|
12791
|
+
if (!input.title) {
|
|
12792
|
+
return errorResult("capture_plan requires: title");
|
|
12793
|
+
}
|
|
12794
|
+
if (!workspaceId) {
|
|
12795
|
+
return errorResult("capture_plan requires workspace_id. Call session_init first.");
|
|
12796
|
+
}
|
|
12797
|
+
const result = await client.createPlan({
|
|
12798
|
+
workspace_id: workspaceId,
|
|
12799
|
+
project_id: projectId,
|
|
12800
|
+
title: input.title,
|
|
12801
|
+
content: input.content,
|
|
12802
|
+
description: input.description,
|
|
12803
|
+
goals: input.goals,
|
|
12804
|
+
steps: input.steps,
|
|
12805
|
+
status: input.status || "draft",
|
|
12806
|
+
tags: input.tags,
|
|
12807
|
+
due_at: input.due_at,
|
|
12808
|
+
source_tool: input.source_tool || "mcp"
|
|
12809
|
+
});
|
|
12810
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
12811
|
+
}
|
|
12812
|
+
case "get_plan": {
|
|
12813
|
+
if (!input.plan_id) {
|
|
12814
|
+
return errorResult("get_plan requires: plan_id");
|
|
12815
|
+
}
|
|
12816
|
+
const result = await client.getPlan({
|
|
12817
|
+
plan_id: input.plan_id,
|
|
12818
|
+
include_tasks: input.include_tasks !== false
|
|
12819
|
+
});
|
|
12820
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
12821
|
+
}
|
|
12822
|
+
case "update_plan": {
|
|
12823
|
+
if (!input.plan_id) {
|
|
12824
|
+
return errorResult("update_plan requires: plan_id");
|
|
12825
|
+
}
|
|
12826
|
+
const result = await client.updatePlan({
|
|
12827
|
+
plan_id: input.plan_id,
|
|
12828
|
+
title: input.title,
|
|
12829
|
+
content: input.content,
|
|
12830
|
+
description: input.description,
|
|
12831
|
+
goals: input.goals,
|
|
12832
|
+
steps: input.steps,
|
|
12833
|
+
status: input.status,
|
|
12834
|
+
tags: input.tags,
|
|
12835
|
+
due_at: input.due_at
|
|
12836
|
+
});
|
|
12837
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
12838
|
+
}
|
|
12839
|
+
case "list_plans": {
|
|
12840
|
+
if (!workspaceId) {
|
|
12841
|
+
return errorResult("list_plans requires workspace_id. Call session_init first.");
|
|
12842
|
+
}
|
|
12843
|
+
const result = await client.listPlans({
|
|
12844
|
+
workspace_id: workspaceId,
|
|
12845
|
+
project_id: projectId,
|
|
12846
|
+
status: input.status,
|
|
12847
|
+
limit: input.limit
|
|
12848
|
+
});
|
|
12849
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
12850
|
+
}
|
|
12562
12851
|
default:
|
|
12563
12852
|
return errorResult(`Unknown action: ${input.action}`);
|
|
12564
12853
|
}
|
|
@@ -12568,7 +12857,7 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12568
12857
|
"memory",
|
|
12569
12858
|
{
|
|
12570
12859
|
title: "Memory",
|
|
12571
|
-
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.`,
|
|
12860
|
+
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.`,
|
|
12572
12861
|
inputSchema: external_exports.object({
|
|
12573
12862
|
action: external_exports.enum([
|
|
12574
12863
|
"create_event",
|
|
@@ -12586,7 +12875,14 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12586
12875
|
"search",
|
|
12587
12876
|
"decisions",
|
|
12588
12877
|
"timeline",
|
|
12589
|
-
"summary"
|
|
12878
|
+
"summary",
|
|
12879
|
+
// Task actions
|
|
12880
|
+
"create_task",
|
|
12881
|
+
"get_task",
|
|
12882
|
+
"update_task",
|
|
12883
|
+
"delete_task",
|
|
12884
|
+
"list_tasks",
|
|
12885
|
+
"reorder_tasks"
|
|
12590
12886
|
]).describe("Action to perform"),
|
|
12591
12887
|
workspace_id: external_exports.string().uuid().optional(),
|
|
12592
12888
|
project_id: external_exports.string().uuid().optional(),
|
|
@@ -12622,7 +12918,18 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12622
12918
|
file_path: external_exports.string(),
|
|
12623
12919
|
symbol_id: external_exports.string().optional(),
|
|
12624
12920
|
symbol_name: external_exports.string().optional()
|
|
12625
|
-
})).optional()
|
|
12921
|
+
})).optional(),
|
|
12922
|
+
// Task-specific params
|
|
12923
|
+
task_id: external_exports.string().uuid().optional().describe("Task ID for get_task/update_task/delete_task"),
|
|
12924
|
+
plan_id: external_exports.string().uuid().optional().describe("Parent plan ID for create_task/list_tasks"),
|
|
12925
|
+
plan_step_id: external_exports.string().optional().describe("Which plan step this task implements"),
|
|
12926
|
+
description: external_exports.string().optional().describe("Description for task"),
|
|
12927
|
+
task_status: external_exports.enum(["pending", "in_progress", "completed", "blocked", "cancelled"]).optional().describe("Task status"),
|
|
12928
|
+
priority: external_exports.enum(["low", "medium", "high", "urgent"]).optional().describe("Task priority"),
|
|
12929
|
+
order: external_exports.number().optional().describe("Task order within plan"),
|
|
12930
|
+
task_ids: external_exports.array(external_exports.string().uuid()).optional().describe("Task IDs for reorder_tasks"),
|
|
12931
|
+
blocked_reason: external_exports.string().optional().describe("Reason when task is blocked"),
|
|
12932
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Tags for task")
|
|
12626
12933
|
})
|
|
12627
12934
|
},
|
|
12628
12935
|
async (input) => {
|
|
@@ -12776,6 +13083,94 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
12776
13083
|
});
|
|
12777
13084
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
12778
13085
|
}
|
|
13086
|
+
// Task actions
|
|
13087
|
+
case "create_task": {
|
|
13088
|
+
if (!input.title) {
|
|
13089
|
+
return errorResult("create_task requires: title");
|
|
13090
|
+
}
|
|
13091
|
+
if (!workspaceId) {
|
|
13092
|
+
return errorResult("create_task requires workspace_id. Call session_init first.");
|
|
13093
|
+
}
|
|
13094
|
+
const result = await client.createTask({
|
|
13095
|
+
workspace_id: workspaceId,
|
|
13096
|
+
project_id: projectId,
|
|
13097
|
+
title: input.title,
|
|
13098
|
+
content: input.content,
|
|
13099
|
+
description: input.description,
|
|
13100
|
+
plan_id: input.plan_id,
|
|
13101
|
+
plan_step_id: input.plan_step_id,
|
|
13102
|
+
status: input.task_status,
|
|
13103
|
+
priority: input.priority,
|
|
13104
|
+
order: input.order,
|
|
13105
|
+
code_refs: input.code_refs,
|
|
13106
|
+
tags: input.tags
|
|
13107
|
+
});
|
|
13108
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13109
|
+
}
|
|
13110
|
+
case "get_task": {
|
|
13111
|
+
if (!input.task_id) {
|
|
13112
|
+
return errorResult("get_task requires: task_id");
|
|
13113
|
+
}
|
|
13114
|
+
const result = await client.getTask({
|
|
13115
|
+
task_id: input.task_id
|
|
13116
|
+
});
|
|
13117
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13118
|
+
}
|
|
13119
|
+
case "update_task": {
|
|
13120
|
+
if (!input.task_id) {
|
|
13121
|
+
return errorResult("update_task requires: task_id");
|
|
13122
|
+
}
|
|
13123
|
+
const result = await client.updateTask({
|
|
13124
|
+
task_id: input.task_id,
|
|
13125
|
+
title: input.title,
|
|
13126
|
+
content: input.content,
|
|
13127
|
+
description: input.description,
|
|
13128
|
+
status: input.task_status,
|
|
13129
|
+
priority: input.priority,
|
|
13130
|
+
order: input.order,
|
|
13131
|
+
plan_step_id: input.plan_step_id,
|
|
13132
|
+
code_refs: input.code_refs,
|
|
13133
|
+
tags: input.tags,
|
|
13134
|
+
blocked_reason: input.blocked_reason
|
|
13135
|
+
});
|
|
13136
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13137
|
+
}
|
|
13138
|
+
case "delete_task": {
|
|
13139
|
+
if (!input.task_id) {
|
|
13140
|
+
return errorResult("delete_task requires: task_id");
|
|
13141
|
+
}
|
|
13142
|
+
const result = await client.deleteTask({
|
|
13143
|
+
task_id: input.task_id
|
|
13144
|
+
});
|
|
13145
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13146
|
+
}
|
|
13147
|
+
case "list_tasks": {
|
|
13148
|
+
if (!workspaceId) {
|
|
13149
|
+
return errorResult("list_tasks requires workspace_id. Call session_init first.");
|
|
13150
|
+
}
|
|
13151
|
+
const result = await client.listTasks({
|
|
13152
|
+
workspace_id: workspaceId,
|
|
13153
|
+
project_id: projectId,
|
|
13154
|
+
plan_id: input.plan_id,
|
|
13155
|
+
status: input.task_status,
|
|
13156
|
+
priority: input.priority,
|
|
13157
|
+
limit: input.limit
|
|
13158
|
+
});
|
|
13159
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13160
|
+
}
|
|
13161
|
+
case "reorder_tasks": {
|
|
13162
|
+
if (!input.plan_id) {
|
|
13163
|
+
return errorResult("reorder_tasks requires: plan_id");
|
|
13164
|
+
}
|
|
13165
|
+
if (!input.task_ids || input.task_ids.length === 0) {
|
|
13166
|
+
return errorResult("reorder_tasks requires: task_ids (array of task IDs in new order)");
|
|
13167
|
+
}
|
|
13168
|
+
const result = await client.reorderPlanTasks({
|
|
13169
|
+
plan_id: input.plan_id,
|
|
13170
|
+
task_ids: input.task_ids
|
|
13171
|
+
});
|
|
13172
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13173
|
+
}
|
|
12779
13174
|
default:
|
|
12780
13175
|
return errorResult(`Unknown action: ${input.action}`);
|
|
12781
13176
|
}
|
|
@@ -13046,19 +13441,30 @@ Use this to remove a reminder that is no longer relevant.`,
|
|
|
13046
13441
|
if (!input.path) {
|
|
13047
13442
|
return errorResult("ingest_local requires: path");
|
|
13048
13443
|
}
|
|
13444
|
+
if (!projectId) {
|
|
13445
|
+
return errorResult("ingest_local requires: project_id");
|
|
13446
|
+
}
|
|
13049
13447
|
const validPath = await validateReadableDirectory(input.path);
|
|
13050
13448
|
if (!validPath.ok) {
|
|
13051
13449
|
return errorResult(validPath.error);
|
|
13052
13450
|
}
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13451
|
+
let totalFiles = 0;
|
|
13452
|
+
let batches = 0;
|
|
13453
|
+
for await (const batch of readAllFilesInBatches(validPath.resolvedPath, { batchSize: 50 })) {
|
|
13454
|
+
if (batch.length === 0) continue;
|
|
13455
|
+
await client.ingestFiles(projectId, batch, {
|
|
13057
13456
|
overwrite: input.overwrite,
|
|
13058
13457
|
write_to_disk: input.write_to_disk
|
|
13059
13458
|
});
|
|
13060
|
-
|
|
13061
|
-
|
|
13459
|
+
totalFiles += batch.length;
|
|
13460
|
+
batches += 1;
|
|
13461
|
+
}
|
|
13462
|
+
const result = {
|
|
13463
|
+
project_id: projectId,
|
|
13464
|
+
files_ingested: totalFiles,
|
|
13465
|
+
batches,
|
|
13466
|
+
path: validPath.resolvedPath
|
|
13467
|
+
};
|
|
13062
13468
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
13063
13469
|
}
|
|
13064
13470
|
default:
|
|
@@ -15231,6 +15637,7 @@ function buildContextStreamMcpServer(params) {
|
|
|
15231
15637
|
if (params.toolset === "router") {
|
|
15232
15638
|
env.CONTEXTSTREAM_PROGRESSIVE_MODE = "true";
|
|
15233
15639
|
}
|
|
15640
|
+
env.CONTEXTSTREAM_CONTEXT_PACK = params.contextPackEnabled === false ? "false" : "true";
|
|
15234
15641
|
if (IS_WINDOWS) {
|
|
15235
15642
|
return {
|
|
15236
15643
|
command: "cmd",
|
|
@@ -15252,6 +15659,7 @@ function buildContextStreamVsCodeServer(params) {
|
|
|
15252
15659
|
if (params.toolset === "router") {
|
|
15253
15660
|
env.CONTEXTSTREAM_PROGRESSIVE_MODE = "true";
|
|
15254
15661
|
}
|
|
15662
|
+
env.CONTEXTSTREAM_CONTEXT_PACK = params.contextPackEnabled === false ? "false" : "true";
|
|
15255
15663
|
if (IS_WINDOWS) {
|
|
15256
15664
|
return {
|
|
15257
15665
|
type: "stdio",
|
|
@@ -15342,6 +15750,8 @@ async function upsertCodexTomlConfig(filePath, params) {
|
|
|
15342
15750
|
const envMarker = "[mcp_servers.contextstream.env]";
|
|
15343
15751
|
const toolsetLine = params.toolset === "router" ? `CONTEXTSTREAM_PROGRESSIVE_MODE = "true"
|
|
15344
15752
|
` : "";
|
|
15753
|
+
const contextPackLine = `CONTEXTSTREAM_CONTEXT_PACK = "${params.contextPackEnabled === false ? "false" : "true"}"
|
|
15754
|
+
`;
|
|
15345
15755
|
const commandLine = IS_WINDOWS ? `command = "cmd"
|
|
15346
15756
|
args = ["/c", "npx", "-y", "@contextstream/mcp-server"]
|
|
15347
15757
|
` : `command = "npx"
|
|
@@ -15355,7 +15765,7 @@ args = ["-y", "@contextstream/mcp-server"]
|
|
|
15355
15765
|
[mcp_servers.contextstream.env]
|
|
15356
15766
|
CONTEXTSTREAM_API_URL = "${params.apiUrl}"
|
|
15357
15767
|
CONTEXTSTREAM_API_KEY = "${params.apiKey}"
|
|
15358
|
-
` + toolsetLine;
|
|
15768
|
+
` + toolsetLine + contextPackLine;
|
|
15359
15769
|
if (!exists) {
|
|
15360
15770
|
await fs5.writeFile(filePath, block.trimStart(), "utf8");
|
|
15361
15771
|
return "created";
|
|
@@ -15365,10 +15775,14 @@ CONTEXTSTREAM_API_KEY = "${params.apiKey}"
|
|
|
15365
15775
|
return "updated";
|
|
15366
15776
|
}
|
|
15367
15777
|
if (!existing.includes(envMarker)) {
|
|
15368
|
-
await fs5.writeFile(
|
|
15778
|
+
await fs5.writeFile(
|
|
15779
|
+
filePath,
|
|
15780
|
+
existing.trimEnd() + "\n\n" + envMarker + `
|
|
15369
15781
|
CONTEXTSTREAM_API_URL = "${params.apiUrl}"
|
|
15370
15782
|
CONTEXTSTREAM_API_KEY = "${params.apiKey}"
|
|
15371
|
-
|
|
15783
|
+
` + toolsetLine + contextPackLine,
|
|
15784
|
+
"utf8"
|
|
15785
|
+
);
|
|
15372
15786
|
return "updated";
|
|
15373
15787
|
}
|
|
15374
15788
|
const lines = existing.split(/\r?\n/);
|
|
@@ -15376,12 +15790,14 @@ CONTEXTSTREAM_API_KEY = "${params.apiKey}"
|
|
|
15376
15790
|
let inEnv = false;
|
|
15377
15791
|
let sawUrl = false;
|
|
15378
15792
|
let sawKey = false;
|
|
15793
|
+
let sawContextPack = false;
|
|
15379
15794
|
for (const line of lines) {
|
|
15380
15795
|
const trimmed = line.trim();
|
|
15381
15796
|
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
15382
15797
|
if (inEnv && trimmed !== envMarker) {
|
|
15383
15798
|
if (!sawUrl) out.push(`CONTEXTSTREAM_API_URL = "${params.apiUrl}"`);
|
|
15384
15799
|
if (!sawKey) out.push(`CONTEXTSTREAM_API_KEY = "${params.apiKey}"`);
|
|
15800
|
+
if (!sawContextPack) out.push(`CONTEXTSTREAM_CONTEXT_PACK = "${params.contextPackEnabled === false ? "false" : "true"}"`);
|
|
15385
15801
|
inEnv = false;
|
|
15386
15802
|
}
|
|
15387
15803
|
if (trimmed === envMarker) inEnv = true;
|
|
@@ -15398,11 +15814,17 @@ CONTEXTSTREAM_API_KEY = "${params.apiKey}"
|
|
|
15398
15814
|
sawKey = true;
|
|
15399
15815
|
continue;
|
|
15400
15816
|
}
|
|
15817
|
+
if (inEnv && /^\s*CONTEXTSTREAM_CONTEXT_PACK\s*=/.test(line)) {
|
|
15818
|
+
out.push(`CONTEXTSTREAM_CONTEXT_PACK = "${params.contextPackEnabled === false ? "false" : "true"}"`);
|
|
15819
|
+
sawContextPack = true;
|
|
15820
|
+
continue;
|
|
15821
|
+
}
|
|
15401
15822
|
out.push(line);
|
|
15402
15823
|
}
|
|
15403
15824
|
if (inEnv) {
|
|
15404
15825
|
if (!sawUrl) out.push(`CONTEXTSTREAM_API_URL = "${params.apiUrl}"`);
|
|
15405
15826
|
if (!sawKey) out.push(`CONTEXTSTREAM_API_KEY = "${params.apiKey}"`);
|
|
15827
|
+
if (!sawContextPack) out.push(`CONTEXTSTREAM_CONTEXT_PACK = "${params.contextPackEnabled === false ? "false" : "true"}"`);
|
|
15406
15828
|
}
|
|
15407
15829
|
const updated = out.join("\n");
|
|
15408
15830
|
if (updated === existing) return "skipped";
|
|
@@ -15643,6 +16065,11 @@ Detected plan: ${planLabel} (graph: ${graphTierLabel})`);
|
|
|
15643
16065
|
console.log(" Tip: Change later by setting CONTEXTSTREAM_CONSOLIDATED=true|false");
|
|
15644
16066
|
const toolsetChoice = normalizeInput(await rl.question("Choose [1/2] (default 1): ")) || "1";
|
|
15645
16067
|
const toolset = toolsetChoice === "2" ? "router" : "consolidated";
|
|
16068
|
+
console.log("\nContext Pack (Pro+ plans):");
|
|
16069
|
+
console.log(" Fast indexed code + graph context with optional distillation.");
|
|
16070
|
+
console.log(" Uses more operations/credits; can be disabled in settings or via env.");
|
|
16071
|
+
const contextPackChoice = normalizeInput(await rl.question("Enable Context Pack? [Y/n]: "));
|
|
16072
|
+
const contextPackEnabled = !(contextPackChoice.toLowerCase() === "n" || contextPackChoice.toLowerCase() === "no");
|
|
15646
16073
|
const editors = ["codex", "claude", "cursor", "windsurf", "cline", "kilo", "roo", "aider"];
|
|
15647
16074
|
console.log('\nSelect editors to configure (comma-separated numbers, or "all"):');
|
|
15648
16075
|
editors.forEach((e, i) => console.log(` ${i + 1}) ${EDITOR_LABELS[e]}`));
|
|
@@ -15699,9 +16126,9 @@ Detected plan: ${planLabel} (graph: ${graphTierLabel})`);
|
|
|
15699
16126
|
const mcpChoiceDefault = hasCodex && !hasProjectMcpEditors ? "1" : "3";
|
|
15700
16127
|
const mcpChoice = normalizeInput(await rl.question(`Choose [${hasCodex && !hasProjectMcpEditors ? "1/2" : "1/2/3/4"}] (default ${mcpChoiceDefault}): `)) || mcpChoiceDefault;
|
|
15701
16128
|
const mcpScope = mcpChoice === "2" && hasCodex && !hasProjectMcpEditors ? "skip" : mcpChoice === "4" ? "skip" : mcpChoice === "1" ? "global" : mcpChoice === "2" ? "project" : "both";
|
|
15702
|
-
const mcpServer = buildContextStreamMcpServer({ apiUrl, apiKey, toolset });
|
|
15703
|
-
const mcpServerClaude = buildContextStreamMcpServer({ apiUrl, apiKey, toolset });
|
|
15704
|
-
const vsCodeServer = buildContextStreamVsCodeServer({ apiUrl, apiKey, toolset });
|
|
16129
|
+
const mcpServer = buildContextStreamMcpServer({ apiUrl, apiKey, toolset, contextPackEnabled });
|
|
16130
|
+
const mcpServerClaude = buildContextStreamMcpServer({ apiUrl, apiKey, toolset, contextPackEnabled });
|
|
16131
|
+
const vsCodeServer = buildContextStreamVsCodeServer({ apiUrl, apiKey, toolset, contextPackEnabled });
|
|
15705
16132
|
const needsGlobalMcpConfig = mcpScope === "global" || mcpScope === "both" || mcpScope === "project" && hasCodex;
|
|
15706
16133
|
if (needsGlobalMcpConfig) {
|
|
15707
16134
|
console.log("\nInstalling global MCP config...");
|
|
@@ -15715,7 +16142,7 @@ Detected plan: ${planLabel} (graph: ${graphTierLabel})`);
|
|
|
15715
16142
|
console.log(`- ${EDITOR_LABELS[editor]}: would update ${filePath}`);
|
|
15716
16143
|
continue;
|
|
15717
16144
|
}
|
|
15718
|
-
const status = await upsertCodexTomlConfig(filePath, { apiUrl, apiKey, toolset });
|
|
16145
|
+
const status = await upsertCodexTomlConfig(filePath, { apiUrl, apiKey, toolset, contextPackEnabled });
|
|
15719
16146
|
writeActions.push({ kind: "mcp-config", target: filePath, status });
|
|
15720
16147
|
console.log(`- ${EDITOR_LABELS[editor]}: ${status} ${filePath}`);
|
|
15721
16148
|
continue;
|
|
@@ -15749,7 +16176,8 @@ Detected plan: ${planLabel} (graph: ${graphTierLabel})`);
|
|
|
15749
16176
|
}
|
|
15750
16177
|
console.log("- Claude Code: global MCP config is best done via `claude mcp add --transport stdio ...` (see docs).");
|
|
15751
16178
|
const envHint = toolset === "router" ? " --env CONTEXTSTREAM_PROGRESSIVE_MODE=true" : "";
|
|
15752
|
-
|
|
16179
|
+
const packHint = contextPackEnabled === false ? " --env CONTEXTSTREAM_CONTEXT_PACK=false" : " --env CONTEXTSTREAM_CONTEXT_PACK=true";
|
|
16180
|
+
console.log(` macOS/Linux: claude mcp add --transport stdio contextstream --scope user --env CONTEXTSTREAM_API_URL=... --env CONTEXTSTREAM_API_KEY=...${envHint}${packHint} -- npx -y @contextstream/mcp-server`);
|
|
15753
16181
|
console.log(" Windows (native): use `cmd /c npx -y @contextstream/mcp-server` after `--` if `npx` is not found.");
|
|
15754
16182
|
continue;
|
|
15755
16183
|
}
|
|
@@ -15956,6 +16384,7 @@ Applying to ${projects.length} project(s)...`);
|
|
|
15956
16384
|
const toolsetDesc = toolset === "router" ? "~2 meta-tools (router mode)" : "~11 domain tools (consolidated)";
|
|
15957
16385
|
console.log(`Toolset: ${toolset} (${toolsetDesc})`);
|
|
15958
16386
|
console.log(`Token reduction: ~75% compared to previous versions.`);
|
|
16387
|
+
console.log(`Context Pack: ${contextPackEnabled ? "enabled" : "disabled"}`);
|
|
15959
16388
|
}
|
|
15960
16389
|
console.log("\nNext steps:");
|
|
15961
16390
|
console.log("- Restart your editor/CLI after changing MCP config or rules.");
|
|
@@ -15964,6 +16393,7 @@ Applying to ${projects.length} project(s)...`);
|
|
|
15964
16393
|
if (toolset === "router") {
|
|
15965
16394
|
console.log("- Router mode uses 2 meta-tools (session_init + context_smart) for ultra-minimal token usage.");
|
|
15966
16395
|
}
|
|
16396
|
+
console.log("- Toggle Context Pack with CONTEXTSTREAM_CONTEXT_PACK=true|false (and in dashboard settings).");
|
|
15967
16397
|
console.log("");
|
|
15968
16398
|
console.log("You're set up! Now try these prompts in your AI tool:");
|
|
15969
16399
|
console.log(' 1) "session summary"');
|
|
@@ -16032,6 +16462,7 @@ Environment variables:
|
|
|
16032
16462
|
CONTEXTSTREAM_ROUTER_MODE Router pattern: true|false (default: false, exposes only 2 meta-tools)
|
|
16033
16463
|
CONTEXTSTREAM_OUTPUT_FORMAT Output verbosity: compact|pretty (default: compact, ~30% fewer tokens)
|
|
16034
16464
|
CONTEXTSTREAM_CONSOLIDATED Consolidated domain tools: true|false (default: true in v0.4.x, ~75% token reduction)
|
|
16465
|
+
CONTEXTSTREAM_CONTEXT_PACK Enable Context Pack in context_smart: true|false (default: true)
|
|
16035
16466
|
CONTEXTSTREAM_PRO_TOOLS Optional comma-separated PRO tool names (default: AI tools)
|
|
16036
16467
|
CONTEXTSTREAM_UPGRADE_URL Optional upgrade URL shown for PRO tools on Free plan
|
|
16037
16468
|
CONTEXTSTREAM_ENABLE_PROMPTS Enable MCP prompts list (default: true)
|
package/dist/test-server.js
CHANGED
|
@@ -4052,6 +4052,13 @@ var NEVER = INVALID;
|
|
|
4052
4052
|
|
|
4053
4053
|
// src/config.ts
|
|
4054
4054
|
var DEFAULT_API_URL = "https://api.contextstream.io";
|
|
4055
|
+
function parseBooleanEnv(value) {
|
|
4056
|
+
if (value === void 0) return void 0;
|
|
4057
|
+
const normalized = value.trim().toLowerCase();
|
|
4058
|
+
if (["1", "true", "yes", "on"].includes(normalized)) return true;
|
|
4059
|
+
if (["0", "false", "no", "off"].includes(normalized)) return false;
|
|
4060
|
+
return void 0;
|
|
4061
|
+
}
|
|
4055
4062
|
var configSchema = external_exports.object({
|
|
4056
4063
|
apiUrl: external_exports.string().url().default(DEFAULT_API_URL),
|
|
4057
4064
|
apiKey: external_exports.string().min(1).optional(),
|
|
@@ -4059,11 +4066,15 @@ var configSchema = external_exports.object({
|
|
|
4059
4066
|
defaultWorkspaceId: external_exports.string().uuid().optional(),
|
|
4060
4067
|
defaultProjectId: external_exports.string().uuid().optional(),
|
|
4061
4068
|
userAgent: external_exports.string().default("contextstream-mcp/0.1.0"),
|
|
4062
|
-
allowHeaderAuth: external_exports.boolean().optional()
|
|
4069
|
+
allowHeaderAuth: external_exports.boolean().optional(),
|
|
4070
|
+
contextPackEnabled: external_exports.boolean().default(true)
|
|
4063
4071
|
});
|
|
4064
4072
|
var MISSING_CREDENTIALS_ERROR = "Set CONTEXTSTREAM_API_KEY or CONTEXTSTREAM_JWT for authentication (or CONTEXTSTREAM_ALLOW_HEADER_AUTH=true for header-based auth).";
|
|
4065
4073
|
function loadConfig() {
|
|
4066
4074
|
const allowHeaderAuth = process.env.CONTEXTSTREAM_ALLOW_HEADER_AUTH === "1" || process.env.CONTEXTSTREAM_ALLOW_HEADER_AUTH === "true" || process.env.CONTEXTSTREAM_ALLOW_HEADER_AUTH === "yes";
|
|
4075
|
+
const contextPackEnabled = parseBooleanEnv(
|
|
4076
|
+
process.env.CONTEXTSTREAM_CONTEXT_PACK ?? process.env.CONTEXTSTREAM_CONTEXT_PACK_ENABLED
|
|
4077
|
+
);
|
|
4067
4078
|
const parsed = configSchema.safeParse({
|
|
4068
4079
|
apiUrl: process.env.CONTEXTSTREAM_API_URL,
|
|
4069
4080
|
apiKey: process.env.CONTEXTSTREAM_API_KEY,
|
|
@@ -4071,7 +4082,8 @@ function loadConfig() {
|
|
|
4071
4082
|
defaultWorkspaceId: process.env.CONTEXTSTREAM_WORKSPACE_ID,
|
|
4072
4083
|
defaultProjectId: process.env.CONTEXTSTREAM_PROJECT_ID,
|
|
4073
4084
|
userAgent: process.env.CONTEXTSTREAM_USER_AGENT,
|
|
4074
|
-
allowHeaderAuth
|
|
4085
|
+
allowHeaderAuth,
|
|
4086
|
+
contextPackEnabled
|
|
4075
4087
|
});
|
|
4076
4088
|
if (!parsed.success) {
|
|
4077
4089
|
const missing = parsed.error.errors.map((e) => e.path.join(".")).join(", ");
|
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.
|
|
4
|
+
"version": "0.4.11",
|
|
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",
|