@philau2512/fast-context-mcp 1.5.5 → 1.5.6

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.5",
3
+ "version": "1.5.6",
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",
@@ -53,4 +53,4 @@
53
53
  "access": "public"
54
54
  },
55
55
  "license": "MIT"
56
- }
56
+ }
@@ -1,43 +1,61 @@
1
1
  import { statSync } from "node:fs";
2
- import { isAbsolute } from "node:path";
2
+ import { isAbsolute, resolve } from "node:path";
3
3
  import { z } from "zod";
4
4
 
5
5
  export const PROJECT_PATH_REQUIRED_MESSAGE =
6
- "project_path is required. Pass the absolute path to the project root directory.";
6
+ "project_path is optional. Pass the absolute or relative path to the project root directory, or omit to use current working directory.";
7
7
 
8
8
  export const projectPathSchema = z
9
9
  .string()
10
10
  .trim()
11
- .min(1, PROJECT_PATH_REQUIRED_MESSAGE);
11
+ .nullish()
12
+ .transform((val) => val ?? "")
13
+ .default("");
14
+
15
+ /**
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}
23
+ */
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;
28
+ }
29
+ if (isAbsolute(trimmed)) {
30
+ return trimmed;
31
+ }
32
+ return resolve(cwd, trimmed);
33
+ }
12
34
 
13
35
  /**
14
36
  * Validate the project root path provided to fast_context_search.
37
+ * Automatically resolves relative paths or empty/omitted paths against cwd.
15
38
  * Returns null when valid, otherwise an MCP-friendly error string.
16
39
  *
17
40
  * @param {string} projectPath
18
41
  * @param {(path: string) => import("node:fs").Stats} [statFn]
42
+ * @param {string} [cwd]
19
43
  * @returns {string|null}
20
44
  */
21
- export function validateProjectPath(projectPath, statFn = statSync) {
22
- if (!projectPath) {
23
- return `Error: ${PROJECT_PATH_REQUIRED_MESSAGE}`;
24
- }
25
-
26
- if (!isAbsolute(projectPath)) {
27
- return `Error: project_path must be an absolute path, got: ${projectPath}`;
28
- }
45
+ export function validateProjectPath(projectPath, statFn = statSync, cwd = process.cwd()) {
46
+ const resolved = resolveProjectPath(projectPath, cwd);
29
47
 
30
48
  try {
31
- const st = statFn(projectPath);
49
+ const st = statFn(resolved);
32
50
  if (!st.isDirectory()) {
33
- return `Error: project_path is not a directory: ${projectPath}`;
51
+ return `Error: project_path is not a directory: ${resolved}`;
34
52
  }
35
53
  } catch (error) {
36
54
  if (error?.code === "ENOENT") {
37
- return `Error: project_path does not exist: ${projectPath}`;
55
+ return `Error: project_path does not exist: ${resolved}`;
38
56
  }
39
57
  if (error?.code === "EACCES" || error?.code === "EPERM") {
40
- return `Error: cannot access project_path (${error.code}): ${projectPath}`;
58
+ return `Error: cannot access project_path (${error.code}): ${resolved}`;
41
59
  }
42
60
  const reason = error?.message ? `${error.code || "UNKNOWN"}: ${error.message}` : String(error);
43
61
  return `Error: failed to validate project_path: ${reason}`;
package/src/server.mjs CHANGED
@@ -22,7 +22,11 @@ import { fileURLToPath } from "node:url";
22
22
  import { z } from "zod";
23
23
 
24
24
  import { searchWithContent, extractKeyInfo } from "./core.mjs";
25
- import { projectPathSchema, validateProjectPath } from "./project-path.mjs";
25
+ import {
26
+ projectPathSchema,
27
+ resolveProjectPath,
28
+ validateProjectPath,
29
+ } from "./project-path.mjs";
26
30
 
27
31
  const PACKAGE_JSON = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
28
32
  export const SERVER_VERSION = PACKAGE_JSON.version;
@@ -122,9 +126,9 @@ export function buildFastContextSearchTool({
122
126
  'Add local-language business terms only when needed.'
123
127
  ),
124
128
  project_path: projectPathSchema.describe(
125
- "MANDATORY: Absolute path to project root directory (required). " +
126
- "You MUST supply this parameter explicitly on every call (e.g. /Users/username/projects/myproject or C:/Users/username/projects/myproject). " +
127
- "Never leave empty or omit."
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 ."
128
132
  ),
129
133
  tree_depth: z
130
134
  .number()
@@ -192,7 +196,7 @@ export function buildFastContextSearchTool({
192
196
  exclude_paths,
193
197
  include_code_snippets,
194
198
  }) => {
195
- const projectPath = project_path;
199
+ const projectPath = resolveProjectPath(project_path);
196
200
  const validationError = validatePath(projectPath);
197
201
  if (validationError) {
198
202
  return { content: [{ type: "text", text: validationError }] };