Skip to content

Commit 63918dd

Browse files
Fix filesystem server crashes on invalid paths with graceful validation
1 parent 60eb7c2 commit 63918dd

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

src/filesystem/index.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ if (args.length === 0) {
3838
console.error(" 1. Command-line arguments (shown above)");
3939
console.error(" 2. MCP roots protocol (if client supports it)");
4040
console.error("At least one directory must be provided by EITHER method for the server to operate.");
41+
console.error("Note: Directories will be validated at startup but operations will be retried at runtime.");
4142
}
4243

4344
// Store allowed directories in normalized and resolved form
@@ -58,22 +59,33 @@ let allowedDirectories = await Promise.all(
5859
})
5960
);
6061

61-
// Validate that all directories exist and are accessible
62-
await Promise.all(allowedDirectories.map(async (dir) => {
63-
try {
64-
const stats = await fs.stat(dir);
65-
if (!stats.isDirectory()) {
66-
console.error(`Error: ${dir} is not a directory`);
67-
process.exit(1);
62+
// Validate directories at startup - log warnings if path is not accessible at startup.
63+
// Directory accessibility may change between startup and runtime.
64+
const validatedDirectories = await Promise.all(
65+
allowedDirectories.map(async (dir) => {
66+
try {
67+
const stats = await fs.stat(dir);
68+
if (stats.isDirectory()) {
69+
console.error(`Directory accessible: ${dir}`);
70+
return dir;
71+
} else if (stats.isFile()) {
72+
console.error(`${dir} is a file, not a directory - skipping`);
73+
return null;
74+
} else {
75+
// Include symlinks/special files - they might become directories when NAS/VPN reconnects
76+
console.error(`${dir} is not a directory (${stats.isSymbolicLink() ? 'symlink' : 'special file'})`);
77+
return dir;
78+
}
79+
} catch (error) {
80+
// Include inaccessible paths - they might become accessible when storage/network reconnects
81+
console.error(`Directory not accessible: ${dir} - ${error instanceof Error ? error.message : String(error)}`);
82+
return dir;
6883
}
69-
} catch (error) {
70-
console.error(`Error accessing directory ${dir}:`, error);
71-
process.exit(1);
72-
}
73-
}));
84+
})
85+
).then(results => results.filter((dir): dir is string => dir !== null));
7486

7587
// Initialize the global allowedDirectories in lib.ts
76-
setAllowedDirectories(allowedDirectories);
88+
setAllowedDirectories(validatedDirectories);
7789

7890
// Schema definitions
7991
const ReadTextFileArgsSchema = z.object({

0 commit comments

Comments
 (0)