Skip to content

Improve Permission Handling in Filesystem MCP Server #239

Closed as not planned

Description

@rovo79

Improve Permission Handling in Filesystem MCP Server

Issue

When using the Filesystem MCP server with Claude desktop app on macOS, there's a suboptimal user experience around system-level file permissions. Currently, permission prompts are triggered only after a failed file access attempt, leading to a jarring experience where:

  1. User requests to read a file using read_file tool
  2. Operation fails due to lack of permissions
  3. Claude app prompts for system permissions
  4. User has to retry the operation

Impact

This creates a poor user experience where:

  • Operations fail before permissions are established
  • Users see error messages before permission prompts
  • Multiple permission prompts might appear for different files
  • Operations need to be manually retried after granting permissions

Proposed Solution

Add a new check_permissions tool to the Filesystem MCP server that would:

  • Allow proactive permission checking before file operations
  • Trigger any needed system permission prompts upfront
  • Return clear status about which paths are accessible
  • Enable better error handling and user guidance

Implementation Details

  • New tool: check_permissions
  • Input: Array of paths to validate
  • Output: Mapping of paths to their permission status
  • Validates both MCP server allowed directories and system-level permissions
  • Triggers OS permission prompts in a controlled manner

Benefits

  • More predictable permission flow
  • Better user experience
  • Clearer feedback about access status
  • Reduced need for error recovery
  • Maintains separation of concerns within MCP architecture

Notes

While the ideal fix might involve changes to the Claude desktop app itself, this server-side solution provides a workable improvement within the current architecture.

Activity

  1. rovo79 commented on Dec 5, 2024

    @rovo79
    Author

    Proposed Code Changes

    Here's a suggested implementation for the check_permissions tool:

    // Add new schema for permission check
    const CheckPermissionsArgsSchema = z.object({
      paths: z.array(z.string()),
    });
    
    // Add new function to check permissions
    async function checkPathPermissions(paths: string[]): Promise<Record<string, boolean>> {
      const results: Record<string, boolean> = {};
      
      for (const requestedPath of paths) {
        try {
          // First validate if path is allowed
          const validPath = await validatePath(requestedPath);
          
          // Then check if we have read access
          try {
            await fs.access(validPath, fs.constants.R_OK);
            results[requestedPath] = true;
          } catch {
            results[requestedPath] = false;
          }
        } catch (error) {
          results[requestedPath] = false;
        }
      }
      
      return results;
    }
    
    // Add to tools list in setRequestHandler(ListToolsRequestSchema...)
    {
      name: "check_permissions",
      description:
        "Check if the server has necessary permissions to access specified paths. " +
        "Use this tool before attempting other operations to ensure proper access. " +
        "Returns a mapping of paths to their permission status. This allows establishing " +
        "system-level permissions upfront.",
      inputSchema: zodToJsonSchema(CheckPermissionsArgsSchema) as ToolInput,
    }
    
    // Add to tool handler switch statement in CallToolRequestSchema
    case "check_permissions": {
      const parsed = CheckPermissionsArgsSchema.safeParse(args);
      if (!parsed.success) {
        throw new Error(`Invalid arguments for check_permissions: ${parsed.error}`);
      }
      
      const results = await checkPathPermissions(parsed.data.paths);
      const formattedResults = Object.entries(results)
        .map(([path, hasAccess]) => `${path}: ${hasAccess ? 'Access granted' : 'Access denied'}`)
        .join('\n');
        
      return {
        content: [{ type: "text", text: formattedResults }],
      };
    }
  2. jspahrsummers commented on Dec 5, 2024

    @jspahrsummers
    Member

    @rovo79 If you'd like to put those changes into a PR, we'd be happy to review! 🙏

  3. added
    enhancementNew feature or request
    and removed
    bugSomething isn't working
    on Dec 5, 2024
  4. added
    server-filesystemReference implementation for the Filesystem MCP server - src/filesystem
    on Apr 26, 2025
  5. olaservo commented on Aug 17, 2025

    @olaservo
    Member

    @claude is this feature request still relevant based on your understanding of the current filesystem implementation?

  6. claude commented on Aug 17, 2025

    @claude
    Contributor

    Claude finished @olaservo's task —— View job


    Feature Relevance Assessment

    Based on my analysis of the current filesystem MCP server implementation, this feature request remains highly relevant and valuable.

    Current Permission Handling Analysis

    Current Implementation

    The filesystem server currently handles permissions through:

    1. Path validation only: The validatePath function (src/filesystem/index.ts:78-117) validates that requested paths are within allowed directories
    2. Fail-fast on file operations: All file operations directly call filesystem functions and rely on Node.js to throw errors for permission issues
    3. No proactive permission checking: There's no mechanism to check filesystem permissions before attempting operations

    Problem Still Exists

    The original issue persists in the current implementation:

    1. Reactive error handling: Permission errors only surface when file operations fail
    2. Poor user experience: Users see cryptic Node.js filesystem errors before system permission prompts
    3. No batch permission validation: Each file operation fails independently, potentially triggering multiple permission prompts
    4. Limited error context: Generic "EACCES" or "EPERM" errors don't provide clear guidance about what permissions are needed
    Proposed Solution Value

    Benefits of check_permissions Tool

    The proposed check_permissions tool would provide:

    1. Proactive validation: Check permissions before operations fail
    2. Better user experience: Trigger permission prompts upfront in a controlled manner
    3. Batch checking: Validate multiple paths efficiently
    4. Clear feedback: Return structured permission status for each path
    5. Enhanced error handling: Enable better UX flows in MCP clients

    Implementation Considerations

    The proposed solution could be enhanced beyond the original comment:

    // Enhanced implementation could include:
    async function checkPathPermissions(paths: string[]): Promise<Record<string, PermissionResult>> {
      const results: Record<string, PermissionResult> = {};
      
      for (const requestedPath of paths) {
        try {
          const validPath = await validatePath(requestedPath);
          // Check multiple permission types
          const readAccess = await fs.access(validPath, fs.constants.R_OK).then(() => true).catch(() => false);
          const writeAccess = await fs.access(validPath, fs.constants.W_OK).then(() => true).catch(() => false);
          
          results[requestedPath] = {
            accessible: true,
            readable: readAccess,
            writable: writeAccess,
            path: validPath
          };
        } catch (error) {
          results[requestedPath] = {
            accessible: false,
            error: error.message
          };
        }
      }
      
      return results;
    }

    Recommendation

    ✅ This feature should be implemented.

    The permission handling UX issue described in the original issue has not been addressed in the current implementation. Adding a check_permissions tool would:

    • Improve user experience significantly
    • Enable better error handling in MCP clients
    • Provide a clean separation between path validation and permission checking
    • Follow established patterns in the existing codebase

    The implementation would fit naturally with the existing tool architecture and security model.

  7. cliffhall commented on Oct 19, 2026

    @cliffhall
    Member

    Closing: out of scope for the reference servers.

    Thank you for the suggestion, and apologies for the long wait for a response.

    These servers are reference implementations: they exist to show how each part of MCP is used, not to be general-purpose products, so new features are taken selectively (CONTRIBUTING.md). OS-level permission prompts are raised by the host application, not by an MCP server, so a check_permissions tool cannot trigger them and does not fit the reference server's purpose. This is not a judgment on the idea or on you; a server in the MCP Registry may well offer it, and anyone is welcome to build on these servers to do so. This is happening as part of the backlog triage in #4875.

  8. added
    closed-out-of-scopeClosed: out of scope here; listings and new servers go to the MCP Registry (#4875)
    on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    closed-out-of-scopeClosed: out of scope here; listings and new servers go to the MCP Registry (#4875)enhancementNew feature or requestserver-filesystemReference implementation for the Filesystem MCP server - src/filesystem

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions