modelcontextprotocol / modelcontextprotocol/servers

filesystem: tools/list succeeds without initialize handshake (MCP lifecycle bypass)

Open
#4,195 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
90.5k
Forks
11.7k
Avg merge
2d 2h
Merged PRs (30d)
5

Description

Describe the bug
The @modelcontextprotocol/server-filesystem MCP server accepts and successfully handles tools/list before the client completes the required MCP lifecycle handshake (initializenotifications/initialized). The server returns a normal JSON-RPC result instead of rejecting the request as out-of-order.

This breaks the expected MCP session state machine: compliant clients assume that only initialize is valid until the handshake completes. Allowing other methods early can mask misconfigured clients, weaken assumptions used by security tooling, and make session-scoped state (capabilities, auth context, subscriptions) harder to reason about.

Environment
OS: Linux (Proxmox VE host)
MCP server build: ships with current Cursor Desktop (Node-based, secure-filesystem-server v0.2.0, per server log line "serverInfo":{"name":"secure-filesystem-server","version":"0.2.0"})

To Reproduce
Start the filesystem MCP server with a valid allowed directory, e.g.:

npx -y @modelcontextprotocol/server-filesystem /tmp

Do not send initialize or notifications/initialized.

Send a JSON-RPC request for tools/list over stdio, e.g.:

{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}

Observe the response.

Expected behavior
Before the MCP handshake completes, the server should:

  • Reject all methods except initialize (and any explicitly documented pre-init exceptions, if the spec allows them).
  • Return a structured JSON-RPC error (e.g. invalid request / server not initialized), not a successful result.
  • Optionally log a clear diagnostic on stderr indicating that the client violated lifecycle ordering.

After a valid initialize + notifications/initialized sequence, tools/list should succeed as usual.

Actual behaviour
Without any prior initialize call, tools/list is executed successfully and the server returns a JSON-RPC response containing result (tool enumeration), as if the session were already initialized.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the @modelcontextprotocol/server-filesystem entry point launched by npx -y @modelcontextprotocol/server-filesystem /tmp, reproduce the pre-initialize tools/list request, and trace its request handling. Confirm that only the documented pre-initialization methods are accepted, that an out-of-order request returns a structured error, and that initialize followed by notifications/initialized still permits tools/list.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
api, backend-api-design
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.