Repository navigation
Expose API to inspect and remove inactive server sessions #1063
Description
Activity
I agree there should be some mechanism. In the meantime, here's a workaround to delete a session which might be helpful to someone. You can define stub-ish request class and pass it to
doDeletemanually. You can make plausible implementations for the other methods to guard against future changes todoDelete, but right now it only callsgetRequestURIandgetHeader.class FakeDeleteRequest implements HttpServletRequest { private final String sessionId; public FakeDeleteRequest(String sessionId) { this.sessionId = sessionId; } @Override public String getRequestURI() { return "/mcp"; // or whatever } @Override public String getHeader(String name) { if (name.equalsIgnoreCase("Mcp-Session-Id")) { return sessionId; } return null; } // stub the rest }
- addedenhancementNew feature or requestNew feature or requestP2Moderate issues affecting some users, edge cases, potentially valuable featureModerate issues affecting some users, edge cases, potentially valuable feature
on Aug 17, 2026 - addedready for workThe goal is clear and work towards it can be commencedThe goal is clear and work towards it can be commencedand removedready for workThe goal is clear and work towards it can be commencedThe goal is clear and work towards it can be commenced
on Aug 17, 2026 A minimal server-side API could preserve the current transport behavior while making lifecycle management explicit:
Collection<String> sessionIds(); Optional<McpStreamableServerSession> session(String sessionId); boolean removeSession(String sessionId);
A read-only snapshot (or
Set<String>) would be enough for an application-level idle-timeout job;removeSessionshould perform the same cleanup as the existing DELETE path and be idempotent for an unknown id. If exposing the session object is undesirable,sessionIds()plusremoveSession()avoids leaking transport internals. Would this narrower API fit the intended lifecycle contract, or is a pluggableSessionStorealready preferred for 2.0?The main problem here, abandoned sessions piling up after a client crashes without sending DELETE, looks covered on main now. HttpServletStreamableServerTransportProvider runs a periodic sweeper (added in 1178539, caafc85 and e3e0f51) that evicts any session that has no open stream and received no request during the last interval. You configure it through the builder:
HttpServletStreamableServerTransportProvider.builder() .sessionSweepInterval(Duration.ofMinutes(10)) // default is 30 minutes; null disables it .build();An idle session gets reclaimed somewhere between one and two intervals after its last activity, and a session holding an open GET stream is never touched. The behaviour is documented in docs/server.md and covered by sessionEviction / sessionHoldingAnOpenStreamIsNotEvicted in HttpServletStreamableIntegrationTests.
That leaves the other two asks: a public getSessions() / removeSession() and a pluggable SessionStore. Is there still a concrete use case the sweeper doesn't handle? One example would be an app that has to drop a session right away when a user logs out or a tenant gets revoked, instead of waiting for the next sweep. If there is, I'd be glad to put together a small PR adding only removeSession(String sessionId) on the provider, which closes the session gracefully the way a DELETE does. I'd keep a SessionStore abstraction out of scope for now: it's a much bigger surface to commit to, and session state also lives in the WebFlux/WebMVC transports.
@tzolov does that scope sound reasonable before I start?
While integrating the Java MCP SDK 2.0, we noticed that HttpServletStreamableServerTransportProvider stores McpStreamableServerSession instances in an internal private HashMap, but currently does not expose a public API to inspect or remove server sessions.
Currently, the SDK does not expose any API to inspect, invalidate, or remove these sessions programmatically. The only supported way to remove a session appears to be an explicit HTTP DELETE request from the client.
This becomes problematic if a client terminates unexpectedly (application crash, network failure, process termination ...) and never sends the DELETE request. In this case, the server application has no possibility to clean up abandoned sessions, even if it can determine (e.g.: via an idle timeout) that a session has not been used for hours or days.
From our understanding, this means that the internal session map may continue to grow over time, as applications cannot implement their own session cleanup strategy.
We searched the existing issues and found discussions around session lifecycle management and pluggable session stores (e.g.: issue #274). However, we could not find an issue addressing the missing API to inspect and remove abandoned sessions managed by HttpServletStreamableServerTransportProvider.
Would it be possible to expose a public server-side session management API (e.g.: removeSession(), getSessions(), or a pluggable SessionStore/SessionManager) to allow applications to implement idle timeout and cleanup strategies for stateful Streamable HTTP servers?