v0.2.0 · live
CAPFRAME
§ serversandboxfindings.v2

server-filesystem

npm:@modelcontextprotocol/server-filesystem@2026.1.14

github.com/modelcontextprotocol/servers

Score
C64
Findings
15
Tools
14
Last scan
2026-06-05

Severity breakdown

Critical0
High3
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 15 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 `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`).

  3. 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`).

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. 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.

  11. 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`, `sortBy`. 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 `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.

  13. 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.

  14. 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.

  15. 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.