Skip to content

preview_* tools silently disappear from running agents after a server restart #7870

Description

@thedouglenz

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

  1. Start a thread with a provider that gets the t3-code MCP server attached.
  2. Restart the server.
  3. 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.

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