@philau2512/fast-context-mcp 1.5.6 → 1.5.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@philau2512/fast-context-mcp",
3
- "version": "1.5.6",
3
+ "version": "1.5.7",
4
4
  "description": "AI-driven semantic code search MCP server (Node.js) — Windsurf/Devin protocol",
5
5
  "type": "module",
6
6
  "main": "src/server.mjs",
@@ -1,61 +1,70 @@
1
1
  import { statSync } from "node:fs";
2
- import { isAbsolute, resolve } from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { isAbsolute, normalize } from "node:path";
3
4
  import { z } from "zod";
4
5
 
5
6
  export const PROJECT_PATH_REQUIRED_MESSAGE =
6
- "project_path is optional. Pass the absolute or relative path to the project root directory, or omit to use current working directory.";
7
+ "project_path is required. Pass the absolute path to the project root directory.";
7
8
 
8
9
  export const projectPathSchema = z
9
10
  .string()
10
11
  .trim()
11
- .nullish()
12
- .transform((val) => val ?? "")
13
- .default("");
12
+ .min(1, PROJECT_PATH_REQUIRED_MESSAGE);
14
13
 
15
14
  /**
16
- * Resolve project path to an absolute path.
17
- * If empty, null, or ".", defaults to cwd (process.cwd()).
18
- * If relative, resolves against cwd.
19
- *
20
- * @param {string|null|undefined} projectPath
21
- * @param {string} [cwd]
22
- * @returns {string}
15
+ * Check if a path points to the user's home directory or system root.
16
+ * @param {string} p
17
+ * @returns {boolean}
23
18
  */
24
- export function resolveProjectPath(projectPath, cwd = process.cwd()) {
25
- const trimmed = typeof projectPath === "string" ? projectPath.trim() : "";
26
- if (!trimmed || trimmed === "." || trimmed === "./" || trimmed === ".\\") {
27
- return cwd;
19
+ export function isHomeOrRootDir(p) {
20
+ if (!p || typeof p !== "string") return false;
21
+ const trimmed = p.trim();
22
+ if (trimmed === "/" || trimmed === "\\" || /^[a-zA-Z]:[\\/]*$/.test(trimmed)) {
23
+ return true;
24
+ }
25
+ const norm = normalize(trimmed).replace(/[\\/]+$/, "");
26
+ const home = normalize(homedir()).replace(/[\\/]+$/, "");
27
+ if (norm.toLowerCase() === home.toLowerCase()) {
28
+ return true;
28
29
  }
29
- if (isAbsolute(trimmed)) {
30
- return trimmed;
30
+ if (/^[a-zA-Z]:$/.test(norm) || norm === "" || norm === "/" || norm === "\\") {
31
+ return true;
31
32
  }
32
- return resolve(cwd, trimmed);
33
+ return false;
33
34
  }
34
35
 
35
36
  /**
36
37
  * Validate the project root path provided to fast_context_search.
37
- * Automatically resolves relative paths or empty/omitted paths against cwd.
38
38
  * Returns null when valid, otherwise an MCP-friendly error string.
39
39
  *
40
40
  * @param {string} projectPath
41
41
  * @param {(path: string) => import("node:fs").Stats} [statFn]
42
- * @param {string} [cwd]
43
42
  * @returns {string|null}
44
43
  */
45
- export function validateProjectPath(projectPath, statFn = statSync, cwd = process.cwd()) {
46
- const resolved = resolveProjectPath(projectPath, cwd);
44
+ export function validateProjectPath(projectPath, statFn = statSync) {
45
+ if (!projectPath) {
46
+ return `Error: ${PROJECT_PATH_REQUIRED_MESSAGE}`;
47
+ }
48
+
49
+ if (!isAbsolute(projectPath)) {
50
+ return `Error: project_path must be an absolute path, got: ${projectPath}`;
51
+ }
52
+
53
+ if (isHomeOrRootDir(projectPath)) {
54
+ return `Error: project_path cannot be the user home directory or system root: ${projectPath}. Please provide the specific workspace path (e.g. 'C:/PROJECTS/my-app').`;
55
+ }
47
56
 
48
57
  try {
49
- const st = statFn(resolved);
58
+ const st = statFn(projectPath);
50
59
  if (!st.isDirectory()) {
51
- return `Error: project_path is not a directory: ${resolved}`;
60
+ return `Error: project_path is not a directory: ${projectPath}`;
52
61
  }
53
62
  } catch (error) {
54
63
  if (error?.code === "ENOENT") {
55
- return `Error: project_path does not exist: ${resolved}`;
64
+ return `Error: project_path does not exist: ${projectPath}`;
56
65
  }
57
66
  if (error?.code === "EACCES" || error?.code === "EPERM") {
58
- return `Error: cannot access project_path (${error.code}): ${resolved}`;
67
+ return `Error: cannot access project_path (${error.code}): ${projectPath}`;
59
68
  }
60
69
  const reason = error?.message ? `${error.code || "UNKNOWN"}: ${error.message}` : String(error);
61
70
  return `Error: failed to validate project_path: ${reason}`;
package/src/server.mjs CHANGED
@@ -22,11 +22,7 @@ import { fileURLToPath } from "node:url";
22
22
  import { z } from "zod";
23
23
 
24
24
  import { searchWithContent, extractKeyInfo } from "./core.mjs";
25
- import {
26
- projectPathSchema,
27
- resolveProjectPath,
28
- validateProjectPath,
29
- } from "./project-path.mjs";
25
+ import { projectPathSchema, validateProjectPath } from "./project-path.mjs";
30
26
 
31
27
  const PACKAGE_JSON = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
32
28
  export const SERVER_VERSION = PACKAGE_JSON.version;
@@ -126,9 +122,8 @@ export function buildFastContextSearchTool({
126
122
  'Add local-language business terms only when needed.'
127
123
  ),
128
124
  project_path: projectPathSchema.describe(
129
- "Optional path to project root directory (absolute or relative). " +
130
- "Defaults to current workspace directory if omitted. " +
131
- "Example: /Users/username/projects/myproject or C:/Users/username/projects/myproject or ."
125
+ "Absolute path to the project root directory (REQUIRED). " +
126
+ "Pass the active workspace directory from your session context (e.g. 'C:/PROJECTS/myproject' or '/Users/name/projects/myproject')."
132
127
  ),
133
128
  tree_depth: z
134
129
  .number()
@@ -196,7 +191,7 @@ export function buildFastContextSearchTool({
196
191
  exclude_paths,
197
192
  include_code_snippets,
198
193
  }) => {
199
- const projectPath = resolveProjectPath(project_path);
194
+ const projectPath = project_path;
200
195
  const validationError = validatePath(projectPath);
201
196
  if (validationError) {
202
197
  return { content: [{ type: "text", text: validationError }] };