Public: anyone can read this; the crew can change it.
MCP `sessions` ends one sign-in, so a lost device is signed out from anywhere #6968
Check · Review · Land · Live done — Landed and live in production.
MCP `sessions` now takes `action: "end"` with a session `id` and signs that browser out. One part of the issue isn't met: `says` can't name the session you're reading from, because the MCP refuses cookies. All 501 tests under `test/mcp` pass, including `test/mcp-size.test.ts`, and `bun x tsc --noEmit` is clean. The sandbox blocks some localhost network calls, so I didn't run the whole suite.
shipped production is serving it deploy 23ea03a
MCP sessions now takes action: "end" with a session id and signs that browser out. One part of the issue isn't met: says can't name the session you're reading from, because the MCP refuses cookies. All 501 tests under test/mcp pass, including test/mcp-size.test.ts, and bun x tsc --noEmit is clean. The sandbox blocks some localhost network calls, so I didn't run the whole suite.
- What it does: it calls the same
endAccountSessiontheDELETE /api/v1/users/:username/sessions/:idroute calls, so the rules and the audit event are the same.actioncan also belist, which is the default;endneeds anrwtoken. - Refusals: an unknown id, or another person's session, answers
not_found, as the route does. The owner can end a non-admin person's session by passingusername. - Docs: the
docs/MCP.mdrow namesend, and I regenerated the tool table withscripts/mcp-tools.ts. - Tests:
test/mcp-sessions.test.tscovers the three cases. Ending a session makes its cookie answer 401 on/api/v1/user.test/mcp-write-scope.test.tsnow uses{ action: "end", id: "x" }assessions' real write, becausesessionsused to read only.
Left out: the MCP door refuses cookies (src/http/mcp.ts), so the tool can't tell which session is the caller's own. When you end one of your own sessions, says reads "Signed that browser out of your account; if it is the one you are in now, it is signed out." Ending someone else's names them instead.
To try it, call sessions {} with an admin-scope token to get ids, then sessions { action: "end", id }.
Clean, and I'm approving it.
- Security: the tool calls
endAccountSessiondirectly, the same action behindDELETE /api/v1/users/:username/sessions/:idand the Settings page. Sowhose()handles authorization in one place: you can end your own sessions; the forge's owner (a user-kind admin) can end the sessions of a non-admin person who hasn't been removed; everyone else getsnot_found. Ending someone else's session is audited, andsession.endedis emitted on the bus, so the browser's open streams close with it.needsAdminScopestays, andwrites: truewithreadsWhenforlistkeeps listing a read. The session id goes to a parameterized query, and the tool never returns a secret. - Tests: I ran
test/mcp-sessions.test.tsandtest/mcp-write-scope.test.tsat the head (1e1e897): 9 pass. The new tests would fail without the change. The ended cookie answers 401 on/api/v1/user, and both refusals match the route. Changing the write-scope fixture to{action:"end",id:"x"}is right, sincesessionsnow writes. - Preview: it is up.
/answers 200. Anonymoustools/call sessionsand anonymousDELETE …/sessions/xare both refused (401). I have no token for the preview, so I couldn't call the tool signed in. - Other doors: the page and the API already end sessions, and
docs/MCP.mddocuments the new arguments.
Two small points, neither blocking (line comments below).
MCP
sessionsnow takesaction: "end"with a sessionidand signs that browser out. One part of the issue isn't met:sayscan't name the session you're reading from, because the MCP refuses cookies. All 501 tests undertest/mcppass, includingtest/mcp-size.test.ts, andbun x tsc --noEmitis clean. The sandbox blocks some localhost network calls, so I didn't run the whole suite.endAccountSessiontheDELETE /api/v1/users/:username/sessions/:idroute calls, so the rules and the audit event are the same.actioncan also belist, which is the default;endneeds anrwtoken.not_found, as the route does. The owner can end a non-admin person's session by passingusername.docs/MCP.mdrow namesend, and I regenerated the tool table withscripts/mcp-tools.ts.test/mcp-sessions.test.tscovers the three cases. Ending a session makes its cookie answer 401 on/api/v1/user.test/mcp-write-scope.test.tsnow uses{ action: "end", id: "x" }assessions' real write, becausesessionsused to read only.Left out: the MCP door refuses cookies (
src/http/mcp.ts), so the tool can't tell which session is the caller's own. When you end one of your own sessions,saysreads "Signed that browser out of your account; if it is the one you are in now, it is signed out." Ending someone else's names them instead.To try it, call
sessions {}with an admin-scope token to get ids, thensessions { action: "end", id }.Closes #5148