Skip to content

MCP Tool execution hangs indefinitely in stdio mode when calling external Python scripts #671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ycycycl opened this issue May 9, 2025 · 2 comments

Comments

@ycycycl
Copy link

ycycycl commented May 9, 2025

Describe the bug
When using FastMCP in stdio transport mode, any tool that attempts to execute an external Python script will hang indefinitely until timeout, without returning any result or error. The same code works perfectly when using SSE transport mode.

To Reproduce
Steps to reproduce the behavior:

  1. Create a minimal external script (minimal_script.py) that simply prints output and exits
import sys

def main():
    print("Successfully Call!")
    return 0

if __name__ == "__main__":
    sys.exit(main())
  1. Create an MCP server with a tool that calls this external script
import os
import sys
import asyncio
import subprocess
from typing import Dict, Any

from mcp.server.fastmcp import FastMCP

# Initialize MCP
mcp = FastMCP("bug_demo")

@mcp.tool()
async def call_external_script() -> Dict[str, Any]:
    """Call external script and return result"""
    # Get script path
    current_dir = os.path.dirname(os.path.abspath(__file__))
    script_path = os.path.join(current_dir, "minimal_script.py")
    
    # Build command
    cmd = [sys.executable, script_path]
    
    try:
        # Execute external command
        process = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        
        # Wait for process to complete and get output
        stdout, stderr = await process.communicate()
        
        return {
            "success": process.returncode == 0,
            "stdout": stdout.decode().strip(),
            "stderr": stderr.decode().strip(),
            "return_code": process.returncode
        }
    except Exception as e:
        return {
            "success": False,
            "error": str(e)
        }

if __name__ == "__main__":
    mcp.run(transport="stdio")
    # mcp.run(transport="sse")
  1. Run the server in stdio mode
  2. Call the tool (Using MCP Inspector) that executes the external script
  3. Observe that the tool call hangs indefinitely with no response

Expected behavior
The tool should execute the external Python script, capture its output, and return the results promptly, regardless of the transport mode used (stdio or SSE).

Screenshots
When using stdio, the tool will hang indefinitely until timeout.
Image

However, correct results can be obtained by using SSE mode.
Image

Desktop (please complete the following information):

  • OS: Windows 11 24H2 26100.3775
  • Python 3.10.0
  • mcp 1.7.1
  • asyncio 3.4.3

Additional context
· The issue persists regardless of whether using asyncio.create_subprocess_exec() or subprocess.run().
· I tried printing something in an external py script and found that when calling the tool in STDIO mode, it would be unresponsive, but after timeout, the external py script would be executed and something would be printed out. This is like the running of a py script being blocked until the tool call times out before it can run

@DanielAvdar
Copy link
Contributor

@ycycycl
take a look here: dev-kit-mcp-server
it works smoothly.

@Hellwz
Copy link

Hellwz commented May 17, 2025

Met the exact same issue here. The function mentioned by @DanielAvdar solved it perfectly. Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants