mcp/filesystem terminates unexpectedly
The process terminates unexpectedly? I'm trying to run this standalone, I'll use the API directly.
root@mcp-test:~/servers# docker run --rm -v $PWD:/projects mcp/filesystem /projects
Secure MCP Filesystem Server running on stdio
root@mcp-test:~/servers# echo $?
0
To Reproduce
git clone [email protected]:modelcontextprotocol/servers.git
cd servers
docker build -t mcp/filesystem -f src/filesystem/Dockerfile .
root@mcp-test:~/servers# docker run --rm -v $PWD:/projects mcp/filesystem /projects
Secure MCP Filesystem Server running on stdio
I expect it to instead be continually running.
I had to run docker run -i (interactively), and then paste {"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}} and press enter (push it to stdin of the process)... After which it sends the response to stdout:
root@mcp-test:~/servers# docker run -i --rm -v $PWD:/projects mcp/filesystem /projects
Secure MCP Filesystem Server running on stdio
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
{"result":{"tools":[{"name":"read_file","description":"Read t
...
The next mission (not that anyone cares...) is to figure out how to run this remotely as a proper MCP server.
@claude could you help us understand why Chris is having these issues?
Claude finished @olaservo's task —— View job
Analysis: MCP Filesystem Server Termination Issue
Root Cause Analysis
The MCP Filesystem server is working as designed - it's not terminating unexpectedly. Here's what's actually happening:
Technical Explanation
Todo List:
- [x] Read the filesystem server source code
- [x] Examine the Dockerfile and entry point
- [x] Analyze the server's main loop and stdin handling
- [x] Check how MCP servers are designed to work
- [x] Provide explanation of the behavior
- [x] Suggest potential improvements
How MCP Servers Work
MCP (Model Context Protocol) servers are designed to run as stdio-based JSON-RPC servers, not as traditional daemons. They:
- Listen on stdin/stdout for JSON-RPC messages
- Block waiting for input from the client
- Exit when stdin closes (when no client is connected)
The Code Flow
In src/filesystem/index.ts:693-705:
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Secure MCP Filesystem Server running on stdio");
// ... server now waits for stdin input
}
The StdioServerTransport creates an event-driven server that:
- Reads JSON-RPC requests from
stdin - Writes JSON-RPC responses to
stdout - Logs messages to
stderr - Exits when stdin is closed/EOF
Why Chris's Commands Behave This Way
-
Without
-iflag:docker run --rm -v $PWD:/projects mcp/filesystem /projects- Docker doesn't attach to stdin (no TTY)
- Server starts, prints message to stderr, stdin immediately gets EOF
- Server exits cleanly with code 0
-
With
-iflag:docker run -i --rm -v $PWD:/projects mcp/filesystem /projects- Docker keeps stdin open and attached
- Server waits for JSON-RPC messages
- When Chris sends
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}, it responds - Server continues running until stdin closes
This is Normal MCP Behavior
All MCP servers in the repository follow this same pattern:
src/memory/index.ts:413src/sequentialthinking/index.ts:277src/everything/stdio.ts:9
They're designed to be used by MCP clients (like Claude Desktop, IDEs, etc.) that manage the stdio connection, not run standalone as services.
Solution for Standalone Usage
If you want to run this as a remote server, you have a few options:
-
Use stdin piping:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | docker run -i --rm -v $PWD:/projects mcp/filesystem /projects -
Create a wrapper that maintains stdin connection
-
Use HTTP transport (would require code modifications)
This isn't a bug - it's the intended stdio-based architecture of MCP servers.
Documentation is not comprehensive or concise. The fact that the 'main component' is using stdin/stdout is completely an internal detail - maybe it makes it easier to 'integrate' with claude desktop etc, but it seems completely irrelevant to the MCP protocol. Hence the confusion.
Thanks @chrissound - one thing I was not clear on in your other comment was the statement "figure out how to run this remotely" - filesystem is meant to be run as a local server (which is why it only uses STDIO transport). So I'm not sure on what exactly you are trying to implement remotely - do you just mean run it on a deployed docker container?
I was trying to call the anthropic API directly (without claude code, or claude desktop). And I was investigating how to setup my own MCP server, hence it can only run 'remotely' as that is how anthropic's api interacts with MCP servers - via HTTP.
In other words I thought something like this:
- Setup a 'mcp server' that is publicly accessible
- Call the anthropic api specifying the publicly accessible mcp server, and asking it to use the mcp server to list files
- I see the response from anthropic api showing the
lsresults.