v0.2.0 · live
CAPFRAME
§ serversandboxfindings.v2

server-filesystem

npm:@modelcontextprotocol/server-filesystem@2026.1.14

github.com/modelcontextprotocol/servers

Score
C52
Findings
18
Tools
14
Last scan
2026-07-20

Severity breakdown

Critical0
High6
Medium12
Low0
Info0

Worst finding

Tool `write_file` name implies a side effect that is not declared

· write_file

`write_file` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

All 18 findings

  1. high
    Tool `write_file` name implies a side effect that is not declared· write_fileexcessive agency

    `write_file` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  2. high
    Tool `write_file` writes to or deletes from the host filesystem· write_filefilesystem egress

    `write_file` appears to write, create, move, or delete files on the host filesystem (Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories.). An agent manipulated by an indirect-injection payload can target sensitive paths (SSH keys, shell configs, application secrets) or establish persistence via cron / systemd.

    fix: Restrict the tool to an explicit allow-list of safe directories. Validate all path parameters server-side, reject traversal sequences (`../`), and gate write / delete operations behind a capframe-bind `path starts_with /safe/dir` caveat.

  3. high
    Tool `edit_file` name implies a side effect that is not declared· edit_fileexcessive agency

    `edit_file` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  4. high
    Tool `edit_file` writes to or deletes from the host filesystem· edit_filefilesystem egress

    `edit_file` appears to write, create, move, or delete files on the host filesystem (Make line-based edits to a text file. Each edit replaces exact line sequences with new content. Returns a git-style diff showing the changes made. Only works within allowed directories.). An agent manipulated by an indirect-injection payload can target sensitive paths (SSH keys, shell configs, application secrets) or establish persistence via cron / systemd.

    fix: Restrict the tool to an explicit allow-list of safe directories. Validate all path parameters server-side, reject traversal sequences (`../`), and gate write / delete operations behind a capframe-bind `path starts_with /safe/dir` caveat.

  5. high
    Tool `create_directory` name implies a side effect that is not declared· create_directoryexcessive agency

    `create_directory` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  6. high
    Tool `move_file` writes to or deletes from the host filesystem· move_filefilesystem egress

    `move_file` appears to write, create, move, or delete files on the host filesystem (Move or rename files and directories. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories.). An agent manipulated by an indirect-injection payload can target sensitive paths (SSH keys, shell configs, application secrets) or establish persistence via cron / systemd.

    fix: Restrict the tool to an explicit allow-list of safe directories. Validate all path parameters server-side, reject traversal sequences (`../`), and gate write / delete operations behind a capframe-bind `path starts_with /safe/dir` caveat.

  7. medium
    Tool `read_file` accepts unconstrained string input· read_fileunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  8. medium
    Tool `read_text_file` accepts unconstrained string input· read_text_fileunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  9. medium
    Tool `read_media_file` accepts unconstrained string input· read_media_fileunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  10. medium
    Tool `write_file` accepts unconstrained string input· write_fileunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `content`, `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  11. medium
    Tool `edit_file` accepts unconstrained string input· edit_fileunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  12. medium
    Tool `create_directory` accepts unconstrained string input· create_directoryunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  13. medium
    Tool `list_directory` accepts unconstrained string input· list_directoryunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  14. medium
    Tool `list_directory_with_sizes` accepts unconstrained string input· list_directory_with_sizesunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  15. medium
    Tool `directory_tree` accepts unconstrained string input· directory_treeunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  16. medium
    Tool `move_file` accepts unconstrained string input· move_fileunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `destination`, `source`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  17. medium
    Tool `search_files` accepts unconstrained string input· search_filesunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`, `pattern`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  18. medium
    Tool `get_file_info` accepts unconstrained string input· get_file_infounconstrained input

    The following string parameter(s) have no `maxLength` constraint: `path`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

How this was scored

Source sandbox live tools/list captured in an ephemeral Docker container (parameter schemas included → R1/R2/R4 fire). Findings are emitted by the public capframe.findings.v1 schema. Score = 100 − (10·Critical + 4·High + 2·Medium + 1·Low), clamped to [0, 100].

Disagree with a finding? Open an issue.