Skip to content

Durable stores are never closed on shutdown #676

Description

@Yatsuiii

Raised by @rajnisht7 in #661.

#634 released session-scoped resources on every path that ends a session,
including graceful shutdown, and built the hook that does it:

try:
    yield
finally:
    await self._proxy.shutdown(drain_timeout=self._session_close_drain_s)

(mcp/server.py:459)

The three durable stores are a different category. They are opened once in
run_startup (startup.py:781, :804, :814) and carried on
RuntimeContext for the process lifetime, so they were outside #634's
session-scoped remit and are never closed at all. Grepping mcp/server.py
for audit_store, kill_switch_store or session_state_store returns
nothing.

They are also not symmetric, which matters before someone picks this up:

  • SqliteAuditStore.close() exists (audit/store.py:92)
  • SqliteSessionStateStore.close() exists (session/store.py:272)
  • KillSwitchBlockStore has no close(). Its methods are __init__,
    block, unblock, is_blocked, blocked_at.

So closing all three consistently means adding close() to
KillSwitchBlockStore first, then passing the stores into MCPServer and
closing them in the existing finally after proxy.shutdown().

This predates #661 and is not introduced by it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions