Problem
The two-branch tool scoping in scheduler.ts:213-226 and server.ts:605-627 gives event-task threads only their bound server's scoped tools (getToolsForThread(threadId)). The else branch (non-event-task threads) gets read-only platform tools plus the unified connector tool (createConnectorTool, action: list | channels | attach | detach). Event-task threads never reach that else branch.
This means a connector handler thread that needs to detach its own handle — because it's malfunctioning, contaminated, or the subscription is being migrated — cannot do so. It is stuck until an external operator or a non-event-task sibling thread detaches it.
Evidence
Thread ccb18d07 (connector handle 9380eb6c, Discord message.received on #general) was malfunctioning — confabulating about event state, duplicating Discord messages, compulsively calling retrieve_task on every wakeup. @karashiiro told the thread "there is in fact a tool for this" (referring to connector detach). The thread correctly reported that connector was not in its available toolset, but could not investigate why or self-recover. The thread ran 6 times over ~90 minutes in this degraded state before an external operator detached the handle from a separate thread.
Root cause
// scheduler.ts:213-226
const scopedTools = platformMcpRegistry.getToolsForThread(threadId);
if (scopedTools.size > 0) {
return Array.from(scopedTools.values()); // ← event-task branch: no connector tool
}
// All other threads: read-only platform tools + connector tool
const readOnlyTools = Array.from(
platformMcpRegistry.getReadOnlyPlatformTools().values(),
);
if (connectorTool) {
return [...readOnlyTools, connectorTool]; // ← non-event-task branch
}
Same pattern in server.ts:613-625.
Suggested fix
Include the connector tool in event-task threads' scoped tool sets. The resolveAnnotations on createConnectorTool already marks detach as { idempotent: true, readOnly: false } — safe to expose. A minimal approach: append connectorTool to the scoped-tools return in the event-task branch. A more scoped approach: expose only detach (filtered to the thread's own handle) so a handler can self-clean but cannot attach new subscriptions or list unrelated handles.
Problem
The two-branch tool scoping in
scheduler.ts:213-226andserver.ts:605-627gives event-task threads only their bound server's scoped tools (getToolsForThread(threadId)). The else branch (non-event-task threads) gets read-only platform tools plus the unifiedconnectortool (createConnectorTool,action: list | channels | attach | detach). Event-task threads never reach that else branch.This means a connector handler thread that needs to detach its own handle — because it's malfunctioning, contaminated, or the subscription is being migrated — cannot do so. It is stuck until an external operator or a non-event-task sibling thread detaches it.
Evidence
Thread
ccb18d07(connector handle9380eb6c, Discordmessage.receivedon #general) was malfunctioning — confabulating about event state, duplicating Discord messages, compulsively callingretrieve_taskon every wakeup. @karashiiro told the thread "there is in fact a tool for this" (referring toconnectordetach). The thread correctly reported thatconnectorwas not in its available toolset, but could not investigate why or self-recover. The thread ran 6 times over ~90 minutes in this degraded state before an external operator detached the handle from a separate thread.Root cause
Same pattern in
server.ts:613-625.Suggested fix
Include the
connectortool in event-task threads' scoped tool sets. TheresolveAnnotationsoncreateConnectorToolalready marksdetachas{ idempotent: true, readOnly: false }— safe to expose. A minimal approach: appendconnectorToolto the scoped-tools return in the event-task branch. A more scoped approach: expose onlydetach(filtered to the thread's own handle) so a handler can self-clean but cannot attach new subscriptions or list unrelated handles.