@contextstream/mcp-server 0.3.25 → 0.3.27
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 +20 -10
- package/dist/index.js +31 -724
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
Persistent memory, semantic search, and code intelligence for any MCP-compatible AI tool.
|
|
4
4
|
|
|
5
|
-
ContextStream is a shared
|
|
5
|
+
ContextStream is a shared "brain" for your AI workflows. It stores decisions, preferences, and lessons, and lets your AI tools search and analyze your codebase with consistent context across sessions.
|
|
6
|
+
|
|
7
|
+
## Just Ask
|
|
8
|
+
|
|
9
|
+
**You don't need to memorize tool names.** Just describe what you want and your AI uses the right ContextStream tools automatically:
|
|
10
|
+
|
|
11
|
+
| You say... | ContextStream does... |
|
|
12
|
+
|------------|----------------------|
|
|
13
|
+
| "session summary" | Gets a summary of your workspace context |
|
|
14
|
+
| "what did we decide about auth?" | Recalls past decisions about authentication |
|
|
15
|
+
| "remember we're using PostgreSQL" | Saves this to memory for future sessions |
|
|
16
|
+
| "search for payment code" | Searches your codebase semantically |
|
|
17
|
+
| "what depends on UserService?" | Analyzes code dependencies |
|
|
18
|
+
|
|
19
|
+
No special syntax. No commands to learn. Just ask.
|
|
20
|
+
|
|
21
|
+
> **Tip:** For best results, add the [recommended editor rules](https://contextstream.io/docs/quickstart) so your AI consistently calls `session_init` / `context_smart` automatically.
|
|
22
|
+
|
|
23
|
+

|
|
6
24
|
|
|
7
25
|
## Features
|
|
8
26
|
|
|
@@ -111,13 +129,6 @@ If your account has no workspaces, ContextStream will prompt your AI assistant t
|
|
|
111
129
|
- The current folder is created as a project inside that workspace
|
|
112
130
|
- Recommended: call `workspace_bootstrap(workspace_name="...", folder_path="...")`
|
|
113
131
|
|
|
114
|
-
### Slash commands (prompts)
|
|
115
|
-
|
|
116
|
-
Most MCP clients expose ContextStream prompts as `/contextstream:...` slash commands.
|
|
117
|
-
|
|
118
|
-
- Prompts are parameter-free: selecting a command should immediately insert the template.
|
|
119
|
-
- Templates avoid asking for workspace/project IDs and instead rely on `session_init` + session defaults.
|
|
120
|
-
|
|
121
132
|
## Free vs PRO tools
|
|
122
133
|
|
|
123
134
|
Tools are labeled as `(Free)` or `(PRO)` in the MCP tool list.
|
|
@@ -128,8 +139,7 @@ Tools are labeled as `(Free)` or `(PRO)` in the MCP tool list.
|
|
|
128
139
|
|
|
129
140
|
## Troubleshooting
|
|
130
141
|
|
|
131
|
-
-
|
|
132
|
-
- Slash commands do nothing: update to the latest `@contextstream/mcp-server` and restart your MCP client (prompts are parameter-free and should insert immediately).
|
|
142
|
+
- Tools not appearing: restart the client after editing MCP config; confirm Node 18+ is available to the client runtime.
|
|
133
143
|
- Unauthorized errors: verify `CONTEXTSTREAM_API_URL` and `CONTEXTSTREAM_API_KEY` (or `CONTEXTSTREAM_JWT`).
|
|
134
144
|
- Wrong workspace/project: use `workspace_associate` to map the current repo folder to the correct workspace.
|
|
135
145
|
|
package/dist/index.js
CHANGED
|
@@ -6504,6 +6504,20 @@ ${options.workspaceId ? `# Workspace ID: ${options.workspaceId}` : ""}
|
|
|
6504
6504
|
};
|
|
6505
6505
|
}
|
|
6506
6506
|
|
|
6507
|
+
// src/version.ts
|
|
6508
|
+
import { createRequire } from "module";
|
|
6509
|
+
function getVersion() {
|
|
6510
|
+
try {
|
|
6511
|
+
const require2 = createRequire(import.meta.url);
|
|
6512
|
+
const pkg = require2("../package.json");
|
|
6513
|
+
const version = pkg?.version;
|
|
6514
|
+
if (typeof version === "string" && version.trim()) return version.trim();
|
|
6515
|
+
} catch {
|
|
6516
|
+
}
|
|
6517
|
+
return "unknown";
|
|
6518
|
+
}
|
|
6519
|
+
var VERSION = getVersion();
|
|
6520
|
+
|
|
6507
6521
|
// src/tools.ts
|
|
6508
6522
|
function formatContent(data) {
|
|
6509
6523
|
return JSON.stringify(data, null, 2);
|
|
@@ -6515,7 +6529,7 @@ function toStructured(data) {
|
|
|
6515
6529
|
return void 0;
|
|
6516
6530
|
}
|
|
6517
6531
|
function registerTools(server, client, sessionManager) {
|
|
6518
|
-
const
|
|
6532
|
+
const upgradeUrl = process.env.CONTEXTSTREAM_UPGRADE_URL || "https://contextstream.io/pricing";
|
|
6519
6533
|
const defaultProTools = /* @__PURE__ */ new Set([
|
|
6520
6534
|
// AI endpoints (typically paid/credit-metered)
|
|
6521
6535
|
"ai_context",
|
|
@@ -6544,7 +6558,7 @@ function registerTools(server, client, sessionManager) {
|
|
|
6544
6558
|
return errorResult(
|
|
6545
6559
|
[
|
|
6546
6560
|
`Access denied: \`${toolName}\` requires ContextStream PRO.`,
|
|
6547
|
-
`Upgrade: ${
|
|
6561
|
+
`Upgrade: ${upgradeUrl}`
|
|
6548
6562
|
].join("\n")
|
|
6549
6563
|
);
|
|
6550
6564
|
}
|
|
@@ -6582,7 +6596,7 @@ function registerTools(server, client, sessionManager) {
|
|
|
6582
6596
|
title: `${config.title} (${accessLabel})`,
|
|
6583
6597
|
description: `${config.description}
|
|
6584
6598
|
|
|
6585
|
-
Access: ${accessLabel}${accessLabel === "PRO" ? ` (upgrade: ${
|
|
6599
|
+
Access: ${accessLabel}${accessLabel === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`
|
|
6586
6600
|
};
|
|
6587
6601
|
const safeHandler = async (input) => {
|
|
6588
6602
|
try {
|
|
@@ -6595,7 +6609,7 @@ Access: ${accessLabel}${accessLabel === "PRO" ? ` (upgrade: ${upgradeUrl2})` : "
|
|
|
6595
6609
|
const errorCode = error?.code || error?.status || "UNKNOWN_ERROR";
|
|
6596
6610
|
const isPlanLimit = String(errorCode).toUpperCase() === "FORBIDDEN" && String(errorMessage).toLowerCase().includes("plan limit reached");
|
|
6597
6611
|
const upgradeHint = isPlanLimit ? `
|
|
6598
|
-
Upgrade: ${
|
|
6612
|
+
Upgrade: ${upgradeUrl}` : "";
|
|
6599
6613
|
const serializedError = new Error(
|
|
6600
6614
|
`[${errorCode}] ${errorMessage}${upgradeHint}${errorDetails ? `: ${JSON.stringify(errorDetails)}` : ""}`
|
|
6601
6615
|
);
|
|
@@ -6624,6 +6638,18 @@ Upgrade: ${upgradeUrl2}` : "";
|
|
|
6624
6638
|
const ctx = sessionManager?.getContext();
|
|
6625
6639
|
return typeof ctx?.project_id === "string" ? ctx.project_id : void 0;
|
|
6626
6640
|
}
|
|
6641
|
+
registerTool(
|
|
6642
|
+
"mcp_server_version",
|
|
6643
|
+
{
|
|
6644
|
+
title: "Get MCP server version",
|
|
6645
|
+
description: "Return the running ContextStream MCP server package version",
|
|
6646
|
+
inputSchema: external_exports.object({})
|
|
6647
|
+
},
|
|
6648
|
+
async () => {
|
|
6649
|
+
const result = { name: "contextstream-mcp", version: VERSION };
|
|
6650
|
+
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
6651
|
+
}
|
|
6652
|
+
);
|
|
6627
6653
|
registerTool(
|
|
6628
6654
|
"auth_me",
|
|
6629
6655
|
{
|
|
@@ -8528,723 +8554,6 @@ function registerResources(server, client, apiUrl) {
|
|
|
8528
8554
|
);
|
|
8529
8555
|
}
|
|
8530
8556
|
|
|
8531
|
-
// src/prompts.ts
|
|
8532
|
-
var ID_NOTES = [
|
|
8533
|
-
"Notes:",
|
|
8534
|
-
"- If ContextStream is not initialized in this conversation, call `session_init` first (omit ids).",
|
|
8535
|
-
"- Do not ask me for `workspace_id`/`project_id` \u2014 use session defaults or IDs returned by `session_init`.",
|
|
8536
|
-
"- Prefer omitting IDs in tool calls when the tool supports defaults."
|
|
8537
|
-
];
|
|
8538
|
-
var upgradeUrl = process.env.CONTEXTSTREAM_UPGRADE_URL || "https://contextstream.io/pricing";
|
|
8539
|
-
var proPrompts = /* @__PURE__ */ new Set([
|
|
8540
|
-
"build-context",
|
|
8541
|
-
"generate-plan",
|
|
8542
|
-
"generate-tasks",
|
|
8543
|
-
"token-budget-context"
|
|
8544
|
-
]);
|
|
8545
|
-
function promptAccessLabel(promptName) {
|
|
8546
|
-
return proPrompts.has(promptName) ? "PRO" : "Free";
|
|
8547
|
-
}
|
|
8548
|
-
function registerPrompts(server) {
|
|
8549
|
-
server.registerPrompt(
|
|
8550
|
-
"explore-codebase",
|
|
8551
|
-
{
|
|
8552
|
-
title: `Explore Codebase (${promptAccessLabel("explore-codebase")})`,
|
|
8553
|
-
description: "Get an overview of a project codebase structure and key components"
|
|
8554
|
-
},
|
|
8555
|
-
async () => ({
|
|
8556
|
-
messages: [
|
|
8557
|
-
{
|
|
8558
|
-
role: "user",
|
|
8559
|
-
content: {
|
|
8560
|
-
type: "text",
|
|
8561
|
-
text: [
|
|
8562
|
-
"I want to understand the current codebase.",
|
|
8563
|
-
"",
|
|
8564
|
-
...ID_NOTES,
|
|
8565
|
-
"",
|
|
8566
|
-
"Please help me by:",
|
|
8567
|
-
"1. Use `projects_overview` to get a project summary (use session defaults; only pass `project_id` if required).",
|
|
8568
|
-
"2. Use `projects_files` to identify key entry points.",
|
|
8569
|
-
"3. If a focus area is clear from our conversation, prioritize it; otherwise ask me what to focus on.",
|
|
8570
|
-
"4. Use `search_semantic` (and optionally `search_hybrid`) to find the most relevant files.",
|
|
8571
|
-
"5. Summarize the architecture, major modules, and where to start editing."
|
|
8572
|
-
].join("\n")
|
|
8573
|
-
}
|
|
8574
|
-
}
|
|
8575
|
-
]
|
|
8576
|
-
})
|
|
8577
|
-
);
|
|
8578
|
-
server.registerPrompt(
|
|
8579
|
-
"capture-decision",
|
|
8580
|
-
{
|
|
8581
|
-
title: `Capture Decision (${promptAccessLabel("capture-decision")})`,
|
|
8582
|
-
description: "Document an architectural or technical decision in workspace memory"
|
|
8583
|
-
},
|
|
8584
|
-
async () => ({
|
|
8585
|
-
messages: [
|
|
8586
|
-
{
|
|
8587
|
-
role: "user",
|
|
8588
|
-
content: {
|
|
8589
|
-
type: "text",
|
|
8590
|
-
text: [
|
|
8591
|
-
"Please capture an architectural/technical decision in ContextStream memory.",
|
|
8592
|
-
"",
|
|
8593
|
-
...ID_NOTES,
|
|
8594
|
-
"",
|
|
8595
|
-
"Instructions:",
|
|
8596
|
-
"- If the decision is already described in this conversation, extract: title, context, decision, consequences/tradeoffs.",
|
|
8597
|
-
"- If anything is missing, ask me 1\u20133 quick questions to fill the gaps.",
|
|
8598
|
-
"- Then call `session_capture` with:",
|
|
8599
|
-
' - event_type: "decision"',
|
|
8600
|
-
" - title: (short ADR title)",
|
|
8601
|
-
" - content: a well-formatted ADR (Context, Decision, Consequences)",
|
|
8602
|
-
' - tags: include relevant tags (e.g., "adr", "architecture")',
|
|
8603
|
-
' - importance: "high"',
|
|
8604
|
-
"",
|
|
8605
|
-
"After capturing, confirm what was saved."
|
|
8606
|
-
].join("\n")
|
|
8607
|
-
}
|
|
8608
|
-
}
|
|
8609
|
-
]
|
|
8610
|
-
})
|
|
8611
|
-
);
|
|
8612
|
-
server.registerPrompt(
|
|
8613
|
-
"review-context",
|
|
8614
|
-
{
|
|
8615
|
-
title: `Code Review Context (${promptAccessLabel("review-context")})`,
|
|
8616
|
-
description: "Build context for reviewing code changes"
|
|
8617
|
-
},
|
|
8618
|
-
async () => ({
|
|
8619
|
-
messages: [
|
|
8620
|
-
{
|
|
8621
|
-
role: "user",
|
|
8622
|
-
content: {
|
|
8623
|
-
type: "text",
|
|
8624
|
-
text: [
|
|
8625
|
-
"I need context to review a set of code changes.",
|
|
8626
|
-
"",
|
|
8627
|
-
...ID_NOTES,
|
|
8628
|
-
"",
|
|
8629
|
-
"First:",
|
|
8630
|
-
"- If file paths and a short change description are not already in this conversation, ask me for them.",
|
|
8631
|
-
"",
|
|
8632
|
-
"Then build review context by:",
|
|
8633
|
-
"1. Using `graph_dependencies` to find what depends on the changed areas.",
|
|
8634
|
-
"2. Using `graph_impact` to assess potential blast radius.",
|
|
8635
|
-
"3. Using `memory_search` to find related decisions/notes.",
|
|
8636
|
-
"4. Using `search_semantic` to find related code patterns.",
|
|
8637
|
-
"",
|
|
8638
|
-
"Provide:",
|
|
8639
|
-
"- What the files/components do",
|
|
8640
|
-
"- What might be affected",
|
|
8641
|
-
"- Relevant prior decisions/lessons",
|
|
8642
|
-
"- Review checklist + risks to focus on"
|
|
8643
|
-
].join("\n")
|
|
8644
|
-
}
|
|
8645
|
-
}
|
|
8646
|
-
]
|
|
8647
|
-
})
|
|
8648
|
-
);
|
|
8649
|
-
server.registerPrompt(
|
|
8650
|
-
"investigate-bug",
|
|
8651
|
-
{
|
|
8652
|
-
title: `Investigate Bug (${promptAccessLabel("investigate-bug")})`,
|
|
8653
|
-
description: "Build context for debugging an issue"
|
|
8654
|
-
},
|
|
8655
|
-
async () => ({
|
|
8656
|
-
messages: [
|
|
8657
|
-
{
|
|
8658
|
-
role: "user",
|
|
8659
|
-
content: {
|
|
8660
|
-
type: "text",
|
|
8661
|
-
text: [
|
|
8662
|
-
"I want help investigating a bug.",
|
|
8663
|
-
"",
|
|
8664
|
-
...ID_NOTES,
|
|
8665
|
-
"",
|
|
8666
|
-
"First:",
|
|
8667
|
-
"- If the error/symptom is not already stated, ask me for the exact error message and what I expected vs what happened.",
|
|
8668
|
-
"- If an affected area/component is not known, ask me where I noticed it.",
|
|
8669
|
-
"",
|
|
8670
|
-
"Then:",
|
|
8671
|
-
"1. Use `search_semantic` to find code related to the error/symptom.",
|
|
8672
|
-
"2. Use `search_pattern` to locate where similar errors are thrown or logged.",
|
|
8673
|
-
"3. If you identify key functions, use `graph_call_path` to trace call flows.",
|
|
8674
|
-
"4. Use `memory_search` to check if we have prior notes/bugs about this area.",
|
|
8675
|
-
"",
|
|
8676
|
-
"Return:",
|
|
8677
|
-
"- Likely origin locations",
|
|
8678
|
-
"- Call flow (if found)",
|
|
8679
|
-
"- Related past context",
|
|
8680
|
-
"- Suggested debugging steps"
|
|
8681
|
-
].join("\n")
|
|
8682
|
-
}
|
|
8683
|
-
}
|
|
8684
|
-
]
|
|
8685
|
-
})
|
|
8686
|
-
);
|
|
8687
|
-
server.registerPrompt(
|
|
8688
|
-
"explore-knowledge",
|
|
8689
|
-
{
|
|
8690
|
-
title: `Explore Knowledge Graph (${promptAccessLabel("explore-knowledge")})`,
|
|
8691
|
-
description: "Navigate and understand the knowledge graph for a workspace"
|
|
8692
|
-
},
|
|
8693
|
-
async () => ({
|
|
8694
|
-
messages: [
|
|
8695
|
-
{
|
|
8696
|
-
role: "user",
|
|
8697
|
-
content: {
|
|
8698
|
-
type: "text",
|
|
8699
|
-
text: [
|
|
8700
|
-
"Help me explore the knowledge captured in this workspace.",
|
|
8701
|
-
"",
|
|
8702
|
-
...ID_NOTES,
|
|
8703
|
-
"",
|
|
8704
|
-
"Approach:",
|
|
8705
|
-
"1. Use `memory_summary` for a high-level overview.",
|
|
8706
|
-
"2. Use `memory_decisions` to see decision history (titles + a few key details).",
|
|
8707
|
-
"3. Use `memory_list_nodes` to see available knowledge nodes.",
|
|
8708
|
-
"4. If a starting topic is clear from the conversation, use `memory_search` for it.",
|
|
8709
|
-
"5. Use `graph_related` on the most relevant nodes to expand connections.",
|
|
8710
|
-
"",
|
|
8711
|
-
"Provide:",
|
|
8712
|
-
"- Key themes and topics",
|
|
8713
|
-
"- Important decisions + rationale",
|
|
8714
|
-
"- Suggested \u201Cnext nodes\u201D to explore"
|
|
8715
|
-
].join("\n")
|
|
8716
|
-
}
|
|
8717
|
-
}
|
|
8718
|
-
]
|
|
8719
|
-
})
|
|
8720
|
-
);
|
|
8721
|
-
server.registerPrompt(
|
|
8722
|
-
"onboard-to-project",
|
|
8723
|
-
{
|
|
8724
|
-
title: `Project Onboarding (${promptAccessLabel("onboard-to-project")})`,
|
|
8725
|
-
description: "Generate onboarding context for a new team member"
|
|
8726
|
-
},
|
|
8727
|
-
async () => ({
|
|
8728
|
-
messages: [
|
|
8729
|
-
{
|
|
8730
|
-
role: "user",
|
|
8731
|
-
content: {
|
|
8732
|
-
type: "text",
|
|
8733
|
-
text: [
|
|
8734
|
-
"Create an onboarding guide for a new team member joining this project.",
|
|
8735
|
-
"",
|
|
8736
|
-
...ID_NOTES,
|
|
8737
|
-
"",
|
|
8738
|
-
"First:",
|
|
8739
|
-
"- If the role is not specified, ask me what role they are onboarding into (backend, frontend, fullstack, etc.).",
|
|
8740
|
-
"",
|
|
8741
|
-
"Gather context:",
|
|
8742
|
-
"1. Use `projects_overview` and `projects_statistics` for project summary.",
|
|
8743
|
-
"2. Use `projects_files` to identify key entry points.",
|
|
8744
|
-
"3. Use `memory_timeline` and `memory_decisions` to understand recent changes and architectural choices.",
|
|
8745
|
-
"4. Use `search_semantic` to find READMEs/docs/setup instructions.",
|
|
8746
|
-
"",
|
|
8747
|
-
"Output:",
|
|
8748
|
-
"- Project overview and purpose",
|
|
8749
|
-
"- Tech stack + architecture map",
|
|
8750
|
-
"- Key files/entry points relevant to the role",
|
|
8751
|
-
"- Important decisions + rationale",
|
|
8752
|
-
"- Recent changes/current focus",
|
|
8753
|
-
"- Step-by-step getting started"
|
|
8754
|
-
].join("\n")
|
|
8755
|
-
}
|
|
8756
|
-
}
|
|
8757
|
-
]
|
|
8758
|
-
})
|
|
8759
|
-
);
|
|
8760
|
-
server.registerPrompt(
|
|
8761
|
-
"analyze-refactoring",
|
|
8762
|
-
{
|
|
8763
|
-
title: `Refactoring Analysis (${promptAccessLabel("analyze-refactoring")})`,
|
|
8764
|
-
description: "Analyze a codebase for refactoring opportunities"
|
|
8765
|
-
},
|
|
8766
|
-
async () => ({
|
|
8767
|
-
messages: [
|
|
8768
|
-
{
|
|
8769
|
-
role: "user",
|
|
8770
|
-
content: {
|
|
8771
|
-
type: "text",
|
|
8772
|
-
text: [
|
|
8773
|
-
"Analyze the codebase for refactoring opportunities.",
|
|
8774
|
-
"",
|
|
8775
|
-
...ID_NOTES,
|
|
8776
|
-
"",
|
|
8777
|
-
"If a target area is obvious from our conversation, focus there; otherwise ask me what area to analyze.",
|
|
8778
|
-
"",
|
|
8779
|
-
"Please investigate:",
|
|
8780
|
-
"1. `graph_circular_dependencies` (circular deps to break)",
|
|
8781
|
-
"2. `graph_unused_code` (dead code to remove)",
|
|
8782
|
-
"3. `search_pattern` (duplication patterns)",
|
|
8783
|
-
"4. `projects_statistics` (high complexity hotspots)",
|
|
8784
|
-
"",
|
|
8785
|
-
"Provide a prioritized list with quick wins vs deeper refactors."
|
|
8786
|
-
].join("\n")
|
|
8787
|
-
}
|
|
8788
|
-
}
|
|
8789
|
-
]
|
|
8790
|
-
})
|
|
8791
|
-
);
|
|
8792
|
-
server.registerPrompt(
|
|
8793
|
-
"build-context",
|
|
8794
|
-
{
|
|
8795
|
-
title: `Build LLM Context (${promptAccessLabel("build-context")})`,
|
|
8796
|
-
description: "Build comprehensive context for an LLM task"
|
|
8797
|
-
},
|
|
8798
|
-
async () => ({
|
|
8799
|
-
messages: [
|
|
8800
|
-
{
|
|
8801
|
-
role: "user",
|
|
8802
|
-
content: {
|
|
8803
|
-
type: "text",
|
|
8804
|
-
text: [
|
|
8805
|
-
"Build comprehensive context for the task we are working on.",
|
|
8806
|
-
"",
|
|
8807
|
-
`Access: ${promptAccessLabel("build-context")}${promptAccessLabel("build-context") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
8808
|
-
"",
|
|
8809
|
-
...ID_NOTES,
|
|
8810
|
-
"",
|
|
8811
|
-
"First:",
|
|
8812
|
-
"- If the \u201Cquery\u201D is clear from the latest user request, use that.",
|
|
8813
|
-
"- Otherwise ask me: \u201CWhat do you need context for?\u201D",
|
|
8814
|
-
"",
|
|
8815
|
-
"Then:",
|
|
8816
|
-
"- Call `ai_enhanced_context` with include_code=true, include_docs=true, include_memory=true (omit IDs unless required).",
|
|
8817
|
-
"- Synthesize the returned context into a short briefing with links/file paths and key decisions/risks."
|
|
8818
|
-
].join("\n")
|
|
8819
|
-
}
|
|
8820
|
-
}
|
|
8821
|
-
]
|
|
8822
|
-
})
|
|
8823
|
-
);
|
|
8824
|
-
server.registerPrompt(
|
|
8825
|
-
"smart-search",
|
|
8826
|
-
{
|
|
8827
|
-
title: `Smart Search (${promptAccessLabel("smart-search")})`,
|
|
8828
|
-
description: "Search across memory, decisions, and code for a query"
|
|
8829
|
-
},
|
|
8830
|
-
async () => ({
|
|
8831
|
-
messages: [
|
|
8832
|
-
{
|
|
8833
|
-
role: "user",
|
|
8834
|
-
content: {
|
|
8835
|
-
type: "text",
|
|
8836
|
-
text: [
|
|
8837
|
-
"Find the most relevant context for what I am asking about.",
|
|
8838
|
-
"",
|
|
8839
|
-
...ID_NOTES,
|
|
8840
|
-
"",
|
|
8841
|
-
"First:",
|
|
8842
|
-
"- If a query is clear from the conversation, use it.",
|
|
8843
|
-
"- Otherwise ask me what I want to find.",
|
|
8844
|
-
"",
|
|
8845
|
-
"Then:",
|
|
8846
|
-
"1. Use `session_smart_search` for the query.",
|
|
8847
|
-
"2. If results are thin, follow up with `search_hybrid` and `memory_search`.",
|
|
8848
|
-
"3. Return the top results with file paths/links and a short synthesis."
|
|
8849
|
-
].join("\n")
|
|
8850
|
-
}
|
|
8851
|
-
}
|
|
8852
|
-
]
|
|
8853
|
-
})
|
|
8854
|
-
);
|
|
8855
|
-
server.registerPrompt(
|
|
8856
|
-
"recall-context",
|
|
8857
|
-
{
|
|
8858
|
-
title: `Recall Context (${promptAccessLabel("recall-context")})`,
|
|
8859
|
-
description: "Retrieve relevant past decisions and memory for a query"
|
|
8860
|
-
},
|
|
8861
|
-
async () => ({
|
|
8862
|
-
messages: [
|
|
8863
|
-
{
|
|
8864
|
-
role: "user",
|
|
8865
|
-
content: {
|
|
8866
|
-
type: "text",
|
|
8867
|
-
text: [
|
|
8868
|
-
"Recall relevant past context (decisions, notes, lessons) for what I am asking about.",
|
|
8869
|
-
"",
|
|
8870
|
-
...ID_NOTES,
|
|
8871
|
-
"",
|
|
8872
|
-
"First:",
|
|
8873
|
-
"- If a recall query is clear from the conversation, use it.",
|
|
8874
|
-
"- Otherwise ask me what topic I want to recall.",
|
|
8875
|
-
"",
|
|
8876
|
-
"Then:",
|
|
8877
|
-
"- Use `session_recall` with the query (omit IDs unless required).",
|
|
8878
|
-
"- Summarize the key points and any relevant decisions/lessons."
|
|
8879
|
-
].join("\n")
|
|
8880
|
-
}
|
|
8881
|
-
}
|
|
8882
|
-
]
|
|
8883
|
-
})
|
|
8884
|
-
);
|
|
8885
|
-
server.registerPrompt(
|
|
8886
|
-
"session-summary",
|
|
8887
|
-
{
|
|
8888
|
-
title: `Session Summary (${promptAccessLabel("session-summary")})`,
|
|
8889
|
-
description: "Get a compact summary of workspace/project context"
|
|
8890
|
-
},
|
|
8891
|
-
async () => ({
|
|
8892
|
-
messages: [
|
|
8893
|
-
{
|
|
8894
|
-
role: "user",
|
|
8895
|
-
content: {
|
|
8896
|
-
type: "text",
|
|
8897
|
-
text: [
|
|
8898
|
-
"Generate a compact, token-efficient summary of the current workspace/project context.",
|
|
8899
|
-
"",
|
|
8900
|
-
...ID_NOTES,
|
|
8901
|
-
"",
|
|
8902
|
-
"Use `session_summary` (default max_tokens=500 unless I specify otherwise).",
|
|
8903
|
-
"Then list:",
|
|
8904
|
-
"- Top decisions (titles only)",
|
|
8905
|
-
"- Any high-priority lessons to watch for"
|
|
8906
|
-
].join("\n")
|
|
8907
|
-
}
|
|
8908
|
-
}
|
|
8909
|
-
]
|
|
8910
|
-
})
|
|
8911
|
-
);
|
|
8912
|
-
server.registerPrompt(
|
|
8913
|
-
"capture-lesson",
|
|
8914
|
-
{
|
|
8915
|
-
title: `Capture Lesson (${promptAccessLabel("capture-lesson")})`,
|
|
8916
|
-
description: "Record a lesson learned from an error or correction"
|
|
8917
|
-
},
|
|
8918
|
-
async () => ({
|
|
8919
|
-
messages: [
|
|
8920
|
-
{
|
|
8921
|
-
role: "user",
|
|
8922
|
-
content: {
|
|
8923
|
-
type: "text",
|
|
8924
|
-
text: [
|
|
8925
|
-
"Capture a lesson learned so it is surfaced in future sessions.",
|
|
8926
|
-
"",
|
|
8927
|
-
...ID_NOTES,
|
|
8928
|
-
"",
|
|
8929
|
-
"If the lesson details are not fully present in the conversation, ask me for:",
|
|
8930
|
-
"- title (what to remember)",
|
|
8931
|
-
"- severity (low|medium|high|critical, default medium)",
|
|
8932
|
-
"- category (workflow|code_quality|verification|communication|project_specific)",
|
|
8933
|
-
"- trigger (what caused it)",
|
|
8934
|
-
"- impact (what went wrong)",
|
|
8935
|
-
"- prevention (how to prevent it)",
|
|
8936
|
-
"- keywords (optional)",
|
|
8937
|
-
"",
|
|
8938
|
-
"Then call `session_capture_lesson` with those fields and confirm it was saved."
|
|
8939
|
-
].join("\n")
|
|
8940
|
-
}
|
|
8941
|
-
}
|
|
8942
|
-
]
|
|
8943
|
-
})
|
|
8944
|
-
);
|
|
8945
|
-
server.registerPrompt(
|
|
8946
|
-
"capture-preference",
|
|
8947
|
-
{
|
|
8948
|
-
title: `Capture Preference (${promptAccessLabel("capture-preference")})`,
|
|
8949
|
-
description: "Save a user preference to memory"
|
|
8950
|
-
},
|
|
8951
|
-
async () => ({
|
|
8952
|
-
messages: [
|
|
8953
|
-
{
|
|
8954
|
-
role: "user",
|
|
8955
|
-
content: {
|
|
8956
|
-
type: "text",
|
|
8957
|
-
text: [
|
|
8958
|
-
"Save a user preference to ContextStream memory.",
|
|
8959
|
-
"",
|
|
8960
|
-
...ID_NOTES,
|
|
8961
|
-
"",
|
|
8962
|
-
"If the preference is not explicit in the conversation, ask me what to remember.",
|
|
8963
|
-
"",
|
|
8964
|
-
"Then call `session_capture` with:",
|
|
8965
|
-
'- event_type: "preference"',
|
|
8966
|
-
"- title: (short title)",
|
|
8967
|
-
"- content: (preference text)",
|
|
8968
|
-
'- importance: "medium"'
|
|
8969
|
-
].join("\n")
|
|
8970
|
-
}
|
|
8971
|
-
}
|
|
8972
|
-
]
|
|
8973
|
-
})
|
|
8974
|
-
);
|
|
8975
|
-
server.registerPrompt(
|
|
8976
|
-
"capture-task",
|
|
8977
|
-
{
|
|
8978
|
-
title: `Capture Task (${promptAccessLabel("capture-task")})`,
|
|
8979
|
-
description: "Capture an action item into memory"
|
|
8980
|
-
},
|
|
8981
|
-
async () => ({
|
|
8982
|
-
messages: [
|
|
8983
|
-
{
|
|
8984
|
-
role: "user",
|
|
8985
|
-
content: {
|
|
8986
|
-
type: "text",
|
|
8987
|
-
text: [
|
|
8988
|
-
"Capture an action item into ContextStream memory.",
|
|
8989
|
-
"",
|
|
8990
|
-
...ID_NOTES,
|
|
8991
|
-
"",
|
|
8992
|
-
"If the task is not explicit in the conversation, ask me what to capture.",
|
|
8993
|
-
"",
|
|
8994
|
-
"Then call `session_capture` with:",
|
|
8995
|
-
'- event_type: "task"',
|
|
8996
|
-
"- title: (short title)",
|
|
8997
|
-
"- content: (task details)",
|
|
8998
|
-
'- importance: "medium"'
|
|
8999
|
-
].join("\n")
|
|
9000
|
-
}
|
|
9001
|
-
}
|
|
9002
|
-
]
|
|
9003
|
-
})
|
|
9004
|
-
);
|
|
9005
|
-
server.registerPrompt(
|
|
9006
|
-
"capture-bug",
|
|
9007
|
-
{
|
|
9008
|
-
title: `Capture Bug (${promptAccessLabel("capture-bug")})`,
|
|
9009
|
-
description: "Capture a bug report into workspace memory"
|
|
9010
|
-
},
|
|
9011
|
-
async () => ({
|
|
9012
|
-
messages: [
|
|
9013
|
-
{
|
|
9014
|
-
role: "user",
|
|
9015
|
-
content: {
|
|
9016
|
-
type: "text",
|
|
9017
|
-
text: [
|
|
9018
|
-
"Capture a bug report in ContextStream memory.",
|
|
9019
|
-
"",
|
|
9020
|
-
...ID_NOTES,
|
|
9021
|
-
"",
|
|
9022
|
-
"If details are missing, ask me for:",
|
|
9023
|
-
"- title",
|
|
9024
|
-
"- description",
|
|
9025
|
-
"- steps to reproduce (optional)",
|
|
9026
|
-
"- expected behavior (optional)",
|
|
9027
|
-
"- actual behavior (optional)",
|
|
9028
|
-
"",
|
|
9029
|
-
"Then call `session_capture` with:",
|
|
9030
|
-
'- event_type: "bug"',
|
|
9031
|
-
"- title: (bug title)",
|
|
9032
|
-
"- content: a well-formatted bug report (include all provided details)",
|
|
9033
|
-
"- tags: component/area tags",
|
|
9034
|
-
'- importance: "high"'
|
|
9035
|
-
].join("\n")
|
|
9036
|
-
}
|
|
9037
|
-
}
|
|
9038
|
-
]
|
|
9039
|
-
})
|
|
9040
|
-
);
|
|
9041
|
-
server.registerPrompt(
|
|
9042
|
-
"capture-feature",
|
|
9043
|
-
{
|
|
9044
|
-
title: `Capture Feature (${promptAccessLabel("capture-feature")})`,
|
|
9045
|
-
description: "Capture a feature request into workspace memory"
|
|
9046
|
-
},
|
|
9047
|
-
async () => ({
|
|
9048
|
-
messages: [
|
|
9049
|
-
{
|
|
9050
|
-
role: "user",
|
|
9051
|
-
content: {
|
|
9052
|
-
type: "text",
|
|
9053
|
-
text: [
|
|
9054
|
-
"Capture a feature request in ContextStream memory.",
|
|
9055
|
-
"",
|
|
9056
|
-
...ID_NOTES,
|
|
9057
|
-
"",
|
|
9058
|
-
"If details are missing, ask me for:",
|
|
9059
|
-
"- title",
|
|
9060
|
-
"- description",
|
|
9061
|
-
"- rationale (optional)",
|
|
9062
|
-
"- acceptance criteria (optional)",
|
|
9063
|
-
"",
|
|
9064
|
-
"Then call `session_capture` with:",
|
|
9065
|
-
'- event_type: "feature"',
|
|
9066
|
-
"- title: (feature title)",
|
|
9067
|
-
"- content: a well-formatted feature request",
|
|
9068
|
-
"- tags: component/area tags",
|
|
9069
|
-
'- importance: "medium"'
|
|
9070
|
-
].join("\n")
|
|
9071
|
-
}
|
|
9072
|
-
}
|
|
9073
|
-
]
|
|
9074
|
-
})
|
|
9075
|
-
);
|
|
9076
|
-
server.registerPrompt(
|
|
9077
|
-
"generate-plan",
|
|
9078
|
-
{
|
|
9079
|
-
title: `Generate Plan (${promptAccessLabel("generate-plan")})`,
|
|
9080
|
-
description: "Generate a development plan from a description"
|
|
9081
|
-
},
|
|
9082
|
-
async () => ({
|
|
9083
|
-
messages: [
|
|
9084
|
-
{
|
|
9085
|
-
role: "user",
|
|
9086
|
-
content: {
|
|
9087
|
-
type: "text",
|
|
9088
|
-
text: [
|
|
9089
|
-
"Generate a development plan for what I am trying to build/fix.",
|
|
9090
|
-
"",
|
|
9091
|
-
`Access: ${promptAccessLabel("generate-plan")}${promptAccessLabel("generate-plan") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
9092
|
-
"",
|
|
9093
|
-
...ID_NOTES,
|
|
9094
|
-
"",
|
|
9095
|
-
"Use the most recent user request as the plan description. If unclear, ask me for a one-paragraph description.",
|
|
9096
|
-
"",
|
|
9097
|
-
"Then call `ai_plan` and present the plan as an ordered list with milestones and risks."
|
|
9098
|
-
].join("\n")
|
|
9099
|
-
}
|
|
9100
|
-
}
|
|
9101
|
-
]
|
|
9102
|
-
})
|
|
9103
|
-
);
|
|
9104
|
-
server.registerPrompt(
|
|
9105
|
-
"generate-tasks",
|
|
9106
|
-
{
|
|
9107
|
-
title: `Generate Tasks (${promptAccessLabel("generate-tasks")})`,
|
|
9108
|
-
description: "Generate actionable tasks from a plan or description"
|
|
9109
|
-
},
|
|
9110
|
-
async () => ({
|
|
9111
|
-
messages: [
|
|
9112
|
-
{
|
|
9113
|
-
role: "user",
|
|
9114
|
-
content: {
|
|
9115
|
-
type: "text",
|
|
9116
|
-
text: [
|
|
9117
|
-
"Generate actionable tasks for the work we are discussing.",
|
|
9118
|
-
"",
|
|
9119
|
-
`Access: ${promptAccessLabel("generate-tasks")}${promptAccessLabel("generate-tasks") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
9120
|
-
"",
|
|
9121
|
-
...ID_NOTES,
|
|
9122
|
-
"",
|
|
9123
|
-
"If a plan_id exists in the conversation, use it. Otherwise use the latest user request as the description.",
|
|
9124
|
-
"If granularity is not specified, default to medium.",
|
|
9125
|
-
"",
|
|
9126
|
-
"Call `ai_tasks` and return a checklist of tasks with acceptance criteria for each."
|
|
9127
|
-
].join("\n")
|
|
9128
|
-
}
|
|
9129
|
-
}
|
|
9130
|
-
]
|
|
9131
|
-
})
|
|
9132
|
-
);
|
|
9133
|
-
server.registerPrompt(
|
|
9134
|
-
"token-budget-context",
|
|
9135
|
-
{
|
|
9136
|
-
title: `Token-Budget Context (${promptAccessLabel("token-budget-context")})`,
|
|
9137
|
-
description: "Get the most relevant context that fits within a token budget"
|
|
9138
|
-
},
|
|
9139
|
-
async () => ({
|
|
9140
|
-
messages: [
|
|
9141
|
-
{
|
|
9142
|
-
role: "user",
|
|
9143
|
-
content: {
|
|
9144
|
-
type: "text",
|
|
9145
|
-
text: [
|
|
9146
|
-
"Build the most relevant context that fits within a token budget.",
|
|
9147
|
-
"",
|
|
9148
|
-
`Access: ${promptAccessLabel("token-budget-context")}${promptAccessLabel("token-budget-context") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
9149
|
-
"",
|
|
9150
|
-
...ID_NOTES,
|
|
9151
|
-
"",
|
|
9152
|
-
"First:",
|
|
9153
|
-
"- If a query is clear from the conversation, use it; otherwise ask me for a query.",
|
|
9154
|
-
"- If max_tokens is not specified, ask me for a token budget (e.g., 500/1000/2000).",
|
|
9155
|
-
"",
|
|
9156
|
-
"Then call `ai_context_budget` and return the packed context plus a short note about what was included/excluded."
|
|
9157
|
-
].join("\n")
|
|
9158
|
-
}
|
|
9159
|
-
}
|
|
9160
|
-
]
|
|
9161
|
-
})
|
|
9162
|
-
);
|
|
9163
|
-
server.registerPrompt(
|
|
9164
|
-
"find-todos",
|
|
9165
|
-
{
|
|
9166
|
-
title: `Find TODOs (${promptAccessLabel("find-todos")})`,
|
|
9167
|
-
description: "Scan the codebase for TODO/FIXME/HACK notes and summarize"
|
|
9168
|
-
},
|
|
9169
|
-
async () => ({
|
|
9170
|
-
messages: [
|
|
9171
|
-
{
|
|
9172
|
-
role: "user",
|
|
9173
|
-
content: {
|
|
9174
|
-
type: "text",
|
|
9175
|
-
text: [
|
|
9176
|
-
"Scan the codebase for TODO/FIXME/HACK notes and summarize them.",
|
|
9177
|
-
"",
|
|
9178
|
-
...ID_NOTES,
|
|
9179
|
-
"",
|
|
9180
|
-
"Use `search_pattern` with query `TODO|FIXME|HACK` (or a pattern inferred from the conversation).",
|
|
9181
|
-
"Group results by file path, summarize themes, and propose a small prioritized cleanup list."
|
|
9182
|
-
].join("\n")
|
|
9183
|
-
}
|
|
9184
|
-
}
|
|
9185
|
-
]
|
|
9186
|
-
})
|
|
9187
|
-
);
|
|
9188
|
-
server.registerPrompt(
|
|
9189
|
-
"generate-editor-rules",
|
|
9190
|
-
{
|
|
9191
|
-
title: `Generate Editor Rules (${promptAccessLabel("generate-editor-rules")})`,
|
|
9192
|
-
description: "Generate ContextStream AI rule files for your editor"
|
|
9193
|
-
},
|
|
9194
|
-
async () => ({
|
|
9195
|
-
messages: [
|
|
9196
|
-
{
|
|
9197
|
-
role: "user",
|
|
9198
|
-
content: {
|
|
9199
|
-
type: "text",
|
|
9200
|
-
text: [
|
|
9201
|
-
"Generate ContextStream AI rule files for my editor.",
|
|
9202
|
-
"",
|
|
9203
|
-
...ID_NOTES,
|
|
9204
|
-
"",
|
|
9205
|
-
"First:",
|
|
9206
|
-
"- If you can infer the project folder path from the environment/IDE roots, use it.",
|
|
9207
|
-
"- Otherwise ask me for an absolute folder path.",
|
|
9208
|
-
"- Ask which editor(s) (windsurf,cursor,cline,kilo,roo,claude,aider) or default to all.",
|
|
9209
|
-
"",
|
|
9210
|
-
"Then call `generate_editor_rules` and confirm which files were created/updated."
|
|
9211
|
-
].join("\n")
|
|
9212
|
-
}
|
|
9213
|
-
}
|
|
9214
|
-
]
|
|
9215
|
-
})
|
|
9216
|
-
);
|
|
9217
|
-
server.registerPrompt(
|
|
9218
|
-
"index-local-repo",
|
|
9219
|
-
{
|
|
9220
|
-
title: `Index Local Repo (${promptAccessLabel("index-local-repo")})`,
|
|
9221
|
-
description: "Ingest local files into ContextStream for indexing/search"
|
|
9222
|
-
},
|
|
9223
|
-
async () => ({
|
|
9224
|
-
messages: [
|
|
9225
|
-
{
|
|
9226
|
-
role: "user",
|
|
9227
|
-
content: {
|
|
9228
|
-
type: "text",
|
|
9229
|
-
text: [
|
|
9230
|
-
"Ingest local files into ContextStream for indexing/search.",
|
|
9231
|
-
"",
|
|
9232
|
-
...ID_NOTES,
|
|
9233
|
-
"",
|
|
9234
|
-
"First:",
|
|
9235
|
-
"- Ask me for the local directory path to ingest if it is not already specified.",
|
|
9236
|
-
"",
|
|
9237
|
-
"Then:",
|
|
9238
|
-
"- Call `projects_ingest_local` with the path (use session defaults for project, or the `project_id` returned by `session_init`).",
|
|
9239
|
-
"- Explain how to monitor progress via `projects_index_status`."
|
|
9240
|
-
].join("\n")
|
|
9241
|
-
}
|
|
9242
|
-
}
|
|
9243
|
-
]
|
|
9244
|
-
})
|
|
9245
|
-
);
|
|
9246
|
-
}
|
|
9247
|
-
|
|
9248
8557
|
// src/session-manager.ts
|
|
9249
8558
|
var SessionManager = class {
|
|
9250
8559
|
constructor(server, client) {
|
|
@@ -9537,7 +8846,6 @@ var SessionManager = class {
|
|
|
9537
8846
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
9538
8847
|
import { homedir } from "os";
|
|
9539
8848
|
import { join as join3 } from "path";
|
|
9540
|
-
var VERSION = "0.3.4";
|
|
9541
8849
|
function showFirstRunMessage() {
|
|
9542
8850
|
const configDir = join3(homedir(), ".contextstream");
|
|
9543
8851
|
const starShownFile = join3(configDir, ".star-shown");
|
|
@@ -9608,8 +8916,7 @@ async function main() {
|
|
|
9608
8916
|
const sessionManager = new SessionManager(server, client);
|
|
9609
8917
|
registerTools(server, client, sessionManager);
|
|
9610
8918
|
registerResources(server, client, config.apiUrl);
|
|
9611
|
-
|
|
9612
|
-
console.error(`ContextStream MCP server starting...`);
|
|
8919
|
+
console.error(`ContextStream MCP server v${VERSION} starting...`);
|
|
9613
8920
|
console.error(`API URL: ${config.apiUrl}`);
|
|
9614
8921
|
console.error(`Auth: ${config.apiKey ? "API Key" : config.jwt ? "JWT" : "None"}`);
|
|
9615
8922
|
console.error(`Auto-Context: ENABLED (context loads on first tool call)`);
|
package/package.json
CHANGED