diff --git a/src/features/claude-code-mcp-loader/scope-filter.ts b/src/features/claude-code-mcp-loader/scope-filter.ts index 690421e0c..6da03829c 100644 --- a/src/features/claude-code-mcp-loader/scope-filter.ts +++ b/src/features/claude-code-mcp-loader/scope-filter.ts @@ -1,17 +1,6 @@ -import { existsSync, realpathSync } from "fs" -import { resolve } from "path" +import { containsPath } from "../../shared/contains-path" import type { ClaudeCodeMcpServer } from "./types" -function normalizePath(path: string): string { - const resolvedPath = resolve(path) - - if (!existsSync(resolvedPath)) { - return resolvedPath - } - - return realpathSync(resolvedPath) -} - export function shouldLoadMcpServer( server: Pick, cwd = process.cwd() @@ -24,5 +13,5 @@ export function shouldLoadMcpServer( return false } - return normalizePath(server.projectPath) === normalizePath(cwd) + return containsPath(server.projectPath, cwd) } diff --git a/src/shared/contains-path.ts b/src/shared/contains-path.ts index bd37a5bb9..f51d1f70d 100644 --- a/src/shared/contains-path.ts +++ b/src/shared/contains-path.ts @@ -1,6 +1,22 @@ import { existsSync, realpathSync } from "fs" import { basename, dirname, isAbsolute, join, normalize, relative, resolve } from "path" +function findNearestExistingAncestor(resolvedPath: string): string { + let candidatePath = resolvedPath + + while (!existsSync(candidatePath)) { + const parentPath = dirname(candidatePath) + + if (parentPath === candidatePath) { + return candidatePath + } + + candidatePath = parentPath + } + + return candidatePath +} + function toCanonicalPath(pathToNormalize: string): string { const resolvedPath = resolve(pathToNormalize) @@ -12,12 +28,13 @@ function toCanonicalPath(pathToNormalize: string): string { } } - const parentDirectory = dirname(resolvedPath) - const canonicalParentDirectory = existsSync(parentDirectory) - ? realpathSync.native(parentDirectory) - : parentDirectory + const nearestExistingAncestor = findNearestExistingAncestor(resolvedPath) + const canonicalAncestor = existsSync(nearestExistingAncestor) + ? realpathSync.native(nearestExistingAncestor) + : nearestExistingAncestor + const relativePathFromAncestor = relative(nearestExistingAncestor, resolvedPath) - return normalize(join(canonicalParentDirectory, basename(resolvedPath))) + return normalize(join(canonicalAncestor, relativePathFromAncestor || basename(resolvedPath))) } export function containsPath(rootPath: string, candidatePath: string): boolean {