Summary
When MCP dispatches insert_text, the wire verb is cdpInsertText. Under extension service-worker load races, registry resolve can return null for that verb even though other CDP tools (e.g. click_at → cdpClickAt) succeed. Callers then see Unknown tool: cdpInsertText.
Repro
- Context: MCP client connected to FSB extension bridge; active tab on x.com compose with Draft.js
[data-testid=tweetTextarea_0].
- Steps:
- Ensure extension service worker has recently restarted (or reload unpacked extension without full Chrome restart).
- Call
click_at on the compose field — observe success.
- Call
insert_text with a short string into the focused compose field.
- Observed:
insert_text fails with Unknown tool: cdpInsertText while click_at works.
- Example: compose URL such as
https://x.com/compose/post or an in-thread reply composer.
Code pointers (verified against /workspace/FSB)
extension/ai/tool-definitions.js — insert_text entry with _cdpVerb: 'cdpInsertText' (~L872–886); getToolByNameOrVerb (~L1473) matches _contentVerb / _cdpVerb.
extension/ws/mcp-bridge-client.js — resolveMcpToolDefinition (~L104); hard /^cdp[A-Z]/ fallback calling executeCDPToolDirect (~L1908–1924).
extension/content/messaging.js — Unknown-tool path forwards /^cdp[A-Z]/ to background (~L1062–1088).
extension/background.js — executeCDPToolDirect / cdpInsertText case (~L19786+, ~L20055+).
mcp/src/tools/manual.ts — fsbVerb = tool._contentVerb || tool._cdpVerb || tool.name (~L252).
Branch fix/navigate-url-truth-and-draft-append already includes the hard CDP fallback and content last-resort; race still needs a durable resolve path + tests.
Proposed fix
Make wire-verb resolve deterministic at dispatch time: always resolve via globalThis.getToolByNameOrVerb (or TOOL_REGISTRY scan) before content routing, and keep the /^cdp[A-Z]/ → executeCDPToolDirect fallback as a non-optional safety net when resolve is null. Root cause is incomplete SW-side verb binding for cdpInsertText under load race, not missing CDP capability.
Acceptance / regression
- After SW restart,
insert_text and click_at both succeed on the same compose session without extension reload.
- Unit/integration: resolve
cdpInsertText and insert_text to the same tool def; null registry still routes /^cdp/ to executeCDPToolDirect.
- No regression for content-routed tools (
type_text, click).
Owner
extension (primary); mcp-server only if wire verb mapping in manual.ts drifts.
Priority: P1 · Owner: extension
Summary
When MCP dispatches
insert_text, the wire verb iscdpInsertText. Under extension service-worker load races, registry resolve can return null for that verb even though other CDP tools (e.g.click_at→cdpClickAt) succeed. Callers then seeUnknown tool: cdpInsertText.Repro
[data-testid=tweetTextarea_0].click_aton the compose field — observe success.insert_textwith a short string into the focused compose field.insert_textfails withUnknown tool: cdpInsertTextwhileclick_atworks.https://x.com/compose/postor an in-thread reply composer.Code pointers (verified against /workspace/FSB)
extension/ai/tool-definitions.js—insert_textentry with_cdpVerb: 'cdpInsertText'(~L872–886);getToolByNameOrVerb(~L1473) matches_contentVerb/_cdpVerb.extension/ws/mcp-bridge-client.js—resolveMcpToolDefinition(~L104); hard/^cdp[A-Z]/fallback callingexecuteCDPToolDirect(~L1908–1924).extension/content/messaging.js— Unknown-tool path forwards/^cdp[A-Z]/to background (~L1062–1088).extension/background.js—executeCDPToolDirect/cdpInsertTextcase (~L19786+, ~L20055+).mcp/src/tools/manual.ts—fsbVerb = tool._contentVerb || tool._cdpVerb || tool.name(~L252).Branch
fix/navigate-url-truth-and-draft-appendalready includes the hard CDP fallback and content last-resort; race still needs a durable resolve path + tests.Proposed fix
Make wire-verb resolve deterministic at dispatch time: always resolve via
globalThis.getToolByNameOrVerb(or TOOL_REGISTRY scan) before content routing, and keep the/^cdp[A-Z]/→executeCDPToolDirectfallback as a non-optional safety net when resolve is null. Root cause is incomplete SW-side verb binding forcdpInsertTextunder load race, not missing CDP capability.Acceptance / regression
insert_textandclick_atboth succeed on the same compose session without extension reload.cdpInsertTextandinsert_textto the same tool def; null registry still routes/^cdp/toexecuteCDPToolDirect.type_text,click).Owner
extension (primary); mcp-server only if wire verb mapping in
manual.tsdrifts.Priority: P1 · Owner: extension