preview_* tools silently disappear from running agents after a server restart
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
What happens
After the server restarts, agents in already-running threads lose their preview_* tools. The agent reports that the tools do not exist; nothing is logged and no error surfaces in the UI.
Why
McpSessionRegistry keeps issued credentials only in memory:
// apps/server/src/mcp/McpSessionRegistry.ts:98
const state = yield* SynchronizedRef.make<RegistryState>({ records: new Map() });
The acquireRelease finalizer only clears the module-level activeMcpSessionRegistry pointer, so the map simply dies with the process. A resumed provider session keeps presenting the bearer token it was issued before the restart, the auth middleware no longer has a record for that token hash, and every tool call is rejected.
This is reachable through ordinary use — anything that restarts the backend (an update, the desktop app restarting its server) while a thread has an active provider session.
Reproduce
- Start a thread with a provider that gets the
t3-codeMCP server attached. - Restart the server.
- Ask the agent to use a
preview_*tool.
The agent reports the tool does not exist rather than reporting an auth failure.
One thing worth knowing before fixing it
issueActiveMcpCredential revokes the thread's existing credentials before issuing new ones:
activeMcpSessionRegistry
.revokeThread(request.threadId)
.pipe(Effect.andThen(activeMcpSessionRegistry.issue(request)))
That matters if the fix is "re-issue on resume": a resumed session that is still using its old credential can have it revoked out from under it while the new config is in flight. Persisting credentials and reloading them on boot sidesteps that, but it needs the liveness writes to coalesce or every turn writes a row.
Context
Found downstream in a fork (thedouglenz/trellis), where the same registry serves an additional toolkit and the symptom was more obvious. Happy to leave this as a report — I know large PRs are not what you are looking for.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/server/src/mcp/McpSessionRegistry.ts, especially the in-memory RegistryState, acquireRelease finalizer, and issueActiveMcpCredential flow. Reproduce by restarting the server while a thread has the t3-code MCP server attached, then request a preview_* tool. Done means resumed agents retain usable preview_* tools after restart without silent authentication failures or unsafe credential revocation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100