Skip to content

read-only stdio mode still exposes mutating tools in tools/list #281

@EmersonZh

Description

@EmersonZh

Hi Supabase team,

While testing MCP server safety and CI-linting checks, I noticed a possible mismatch between the documented read-only behavior and the stdio tools/list output.

The README says read_only=true disables mutating tools such as apply_migration, deploy_edge_function, delete_branch, and update_storage_config:

When running the npm stdio package with --read-only, tools/list still exposes mutating tools. For example, apply_migration appears in the tool list and is annotated with readOnlyHint: false / destructiveHint: true.

Reproduction

Run the stdio server in read-only mode:

SUPABASE_ACCESS_TOKEN=sbp_mock_for_schema_only \
  npx -y @supabase/mcp-server-supabase@0.8.1 --read-only

Then connect with an MCP client or the MCP Inspector and call tools/list.

Observed tool names include:

apply_migration
deploy_edge_function
create_branch
delete_branch
merge_branch
reset_branch
rebase_branch

apply_migration appears with annotations like:

{
  "name": "apply_migration",
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": true
  }
}

Expected

If stdio --read-only is intended to mirror remote read_only=true, mutating tools should probably be removed from tools/list, not only rejected at call time.

If the current behavior is intentional, it would be helpful to document the distinction:

  • remote read_only=true filters mutating tools from the visible inventory;
  • stdio --read-only exposes mutating tools but rejects them when called.

Why this matters

For MCP clients and CI linting, tools/list is the main machine-readable source of truth. If destructive tools are visible in a read-only profile, agents may still plan around them even if the server rejects the call later.

mcp-lint context

V0 of mcp-lint is ready at https://github.com/agentsnative/mcp-lint. It is a CI linter for MCP servers that checks installability, tool schemas, annotations, read-only profiles, secret handling, and high-risk tool configuration. This finding is the kind of signal mcp-lint is designed to catch automatically before releases.

Would you be interested in trying the V0 mcp-lint report for this repo? I would be happy to run it against the server and share the output in an issue or PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions