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.
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:
(
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 onRuntimeContextfor the process lifetime, so they were outside #634'ssession-scoped remit and are never closed at all. Grepping
mcp/server.pyfor
audit_store,kill_switch_storeorsession_state_storereturnsnothing.
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)KillSwitchBlockStorehas noclose(). Its methods are__init__,block,unblock,is_blocked,blocked_at.So closing all three consistently means adding
close()toKillSwitchBlockStorefirst, then passing the stores intoMCPServerandclosing them in the existing
finallyafterproxy.shutdown().This predates #661 and is not introduced by it.