[Bug Report]: filesystem move_file overwrites existing destination files despite its no-overwrite contract

Author: yang0228Created Sep 20, 2026Updated Sep 24, 2026

Version

Reproduced against repository main at c2ad42e3eb9b27830db41a3e6f51ca7179d9b168. Component: @agent-infra/mcp-server-filesystem (source package.json: 1.2.29). This is a source-checkout reproduction, not a claim about a tested npm release or CLI version.

Environment: macOS arm64, Node.js v25.9.0, MCP SDK 1.15.1, Zod 3.23.8.

Issue Type

  • Other: filesystem MCP server (@agent-infra/mcp-server-filesystem)

Model Provider

  • Other: not applicable; direct MCP calls, no LLM required.

Problem Description

move_file tells callers that it fails when the destination exists, but moving a regular file to an existing regular file silently overwrites the destination on the tested platform. The tool reports success and the original destination content is lost.

Reproduction

Use a new disposable directory as the server's allowed directory (createServer({ allowedDirectories: [dir] })). Replace <dir> below with its absolute path. Do not run this against valuable files. Send these MCP tool calls in order:

json
{"name":"write_file","arguments":{"path":"<dir>/source.txt","content":"SOURCE"}}
{"name":"write_file","arguments":{"path":"<dir>/destination.txt","content":"KEEP_DESTINATION"}}
{"name":"move_file","arguments":{"source":"<dir>/source.txt","destination":"<dir>/destination.txt"}}
{"name":"read_file","arguments":{"path":"<dir>/destination.txt"}}

Expected: the move fails, source.txt still contains SOURCE, and destination.txt still contains KEEP_DESTINATION.

Actual:

  • The tool returns Successfully moved ... without an error.
  • destination.txt contains SOURCE.
  • source.txt no longer exists.

Control: moving to a previously nonexistent destination succeeds as expected.

Source

The tool description, server.ts:385-390 explicitly promises rejection when the destination exists. The handler, lines 397-399 validates the paths and calls fs.rename directly, without enforcing that promise.

A fix should preserve existing destination data and cover conflicts as well as successful moves. Directory/symlink behavior and concurrent destination creation need explicit consideration; a pre-check alone should not be described as an atomic no-overwrite guarantee.

Verification scope

Reproduced using the unmodified checkout source with a real MCP Client, InMemoryTransport, server handlers, and temporary files. No filesystem functions were mocked. This report establishes the regular-file case on macOS; Windows, Linux, and the full Desktop application were not tested.

Error Logs

The operation incorrectly reports success:

Successfully moved <dir>/source.txt to <dir>/destination.txt

Source: bytedance/UI-TARS-desktop