Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { mkdir, writeFile } from "fs/promises";
import { mkdir, readFile, writeFile } from "fs/promises";
import { dirname, resolve } from "path";
import { fileURLToPath } from "url";
import { z } from "zod";
import { startEmbeddingTracker } from "./core/embedding-tracker.js";
import { isBrokenPipeError, runCleanup } from "./core/process-lifecycle.js";
Expand Down Expand Up @@ -36,6 +37,8 @@ const passthroughArgs = process.argv.slice(2);
const ROOT_DIR = passthroughArgs[0] && !SUB_COMMANDS.includes(passthroughArgs[0])
? resolve(passthroughArgs[0])
: process.cwd();
const INSTRUCTIONS_PATH = resolve(dirname(fileURLToPath(import.meta.url)), "../INSTRUCTIONS.md");
const INSTRUCTIONS_RESOURCE_URI = "contextplus://instructions";

function parseAgentTarget(input?: string): AgentTarget {
const normalized = (input ?? "claude").toLowerCase();
Expand Down Expand Up @@ -133,6 +136,18 @@ const server = new McpServer({
capabilities: { logging: {} },
});

server.resource(
"contextplus_instructions",
INSTRUCTIONS_RESOURCE_URI,
async (uri) => ({
contents: [{
uri: uri.href,
mimeType: "text/markdown",
text: await readFile(INSTRUCTIONS_PATH, "utf8"),
}],
Comment on lines +139 to +147
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads INSTRUCTIONS.md from disk on every resource request. Since the content is static, consider reading it once at startup (or memoizing it) to avoid repeated filesystem I/O and simplify failure handling (single place to report missing file).

Copilot uses AI. Check for mistakes.
}),
Comment on lines +142 to +148
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resource handler directly awaits readFile(INSTRUCTIONS_PATH). If INSTRUCTIONS.md is missing from the installed package (or the path resolution changes), this will throw and may fail the resource request (and possibly bubble up as a server error). Consider catching readFile errors here and returning a clear, deterministic message (or fallback content) rather than letting the exception propagate.

Suggested change
async (uri) => ({
contents: [{
uri: uri.href,
mimeType: "text/markdown",
text: await readFile(INSTRUCTIONS_PATH, "utf8"),
}],
}),
async (uri) => {
let text: string;
try {
text = await readFile(INSTRUCTIONS_PATH, "utf8");
} catch (error) {
text =
"# Context+ Instructions\n\n" +
"The instructions file could not be loaded from the expected location.\n\n" +
`Expected path: \`${INSTRUCTIONS_PATH}\`.\n\n` +
"This may indicate a packaging or installation issue. Please ensure that the `INSTRUCTIONS.md` file " +
"is included in the installed package and that the path resolution is correct.";
}
return {
contents: [
{
uri: uri.href,
mimeType: "text/markdown",
text,
},
],
};
},

Copilot uses AI. Check for mistakes.
);

server.tool(
"get_context_tree",
"Get the structural tree of the project with file headers, function names, classes, enums, and line ranges. " +
Expand Down