Skip to content

Bug: ValueError on MCP server shutdown from promo.py isatty() call #607

@bm-clawd

Description

@bm-clawd

Description

When the BM MCP server shuts down (e.g., after a benchmark run or when an MCP client disconnects), a ValueError: I/O operation on closed file traceback is thrown from the cloud promo system.

Stack trace

basic_memory/cli/app.py:58 in <lambda>
  ctx.call_on_close(lambda: maybe_show_cloud_promo(ctx.invoked_subcommand))

basic_memory/cli/promo.py:85 in maybe_show_cloud_promo
  interactive = _is_interactive_session() if is_interactive is None

basic_memory/cli/promo.py:27 in _is_interactive_session
  return sys.stdin.isatty() and sys.stdout.isatty()

ValueError: I/O operation on closed file

Cause

maybe_show_cloud_promo is registered as a call_on_close callback. When the MCP server runs over stdio, stdin/stdout are closed by the time the callback fires. sys.stdin.isatty() then raises ValueError.

Suggested fix

Guard the isatty check:

def _is_interactive_session() -> bool:
    try:
        return sys.stdin.isatty() and sys.stdout.isatty()
    except ValueError:
        return False

Or skip the promo callback entirely when the invoked subcommand is mcp.

Reproduction

# Any MCP client that connects and disconnects will trigger this
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"test","version":"1.0"},"protocolVersion":"2024-11-05"}}' | bm mcp --transport stdio
# Ctrl-C or close stdin → traceback appears

Environment

  • basic-memory: installed from main via uv
  • Python 3.13.12
  • FastMCP 3.0.2
  • macOS (x86_64)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions