Repository navigation
feat: add opt-in userscript invocation and structured result tools - #2
Merged
Merged
Conversation
Add capability-negotiated handler discovery, JSON invocation and result polling. Cover structured responses, input validation, authorization errors and read-only filtering with transport tests.
Follow the API agreed in violentmonkey/violentmonkey#2726: - script_handlers lists named handlers per script and frame, with an optional description and an inputSchema hint that is not validated. - script_call requires a handler name. - script_results returns calls and reports as a discriminated union on `kind`; reports carry the callId of their call, if any. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
gera2ld
requested changes
Nov 3, 2026
gera2ld
left a comment
Member
There was a problem hiding this comment.
Thanks for the PR. The design looks good. I have a few doc changes to request:
- Delete
docs/script-execution.md. Move the proposal and validation content into this PR description, and keep theGM.mcpAPI reference with the extension docs. If the server needs anything beyond the README, add a short tools section todocs/contract.mdand link to the extension docs. - In the README, remove the "proposed" paragraph. Add the three tools to the Tools table with annotations (
script_callis destructive and open-world) and leave the required Violentmonkey version empty for now. - Update the Non-goals entry in
docs/contract.mdabout not driving userscripts from outside.
As requested in review: - Remove docs/script-execution.md; its proposal and validation notes move to the PR description, and the GM.mcp API reference stays with the extension docs. - List script_handlers, script_call and script_results in the README Tools table, with an empty Violentmonkey version for now. - Add the three tools to docs/contract.md and update the Non-goals entry about driving userscripts from outside. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
@gera2ld Thanks! All three are done in a735d6f:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
An agent developing a userscript can install it, reload a granted tab and inspect
GM_log, but testing the same parser, validator or calculation with several inputs currently requires editing the script or adding a custom trigger. Asynchronous log output also needs an ad hoc convention to associate each result with its request.This change lets an agent discover a userscript's explicitly registered, named handlers, invoke one with JSON input and receive a structured value or error, without repeating the script's top-level initialization. Scripts can also deliberately report results, on their own or attached to a call.
Interfaces
The tool shapes follow the userscript API agreed in violentmonkey/violentmonkey#2726. The tools are documented in the README Tools table and in
docs/contract.md, and theGM.mcpAPI reference lives with the extension docs.script_handlers({ tabId })returnsscripts: [{ scriptId, frameId, handlers: [{ name, description?, inputSchema? }] }].inputSchemais a hint provided by the script and is not validated.script_call({ tabId, scriptId, handler, frameId?, params?, callId?, wait?, timeoutMs? })returns a call record (kind: "call") with a correlated call ID and status.script_results({ tabId, scriptId?, callId?, afterSeq?, limit? })reads retained calls and reports (kind: "report", with thecallIdof their call, if any) with a sequence cursor.GM.mcp/GM_mcp={ register, report }. Handlers receive{ params, report }, wherereportis bound to the call, so userscripts never handle call IDs.This PR adds the protocol schemas, inferred types, server transport/capability tests, README and contract documentation, and a changeset. Tools are exposed only when the connected extension advertises support; existing extensions keep their current tool list. Read-only mode exposes discovery and results, while excluding
script_call.Scope and authorization
This extends the development contract, which excluded driving userscripts from outside; the Non-goals entry is updated accordingly. There is still no generic evaluation, DOM query, navigation, console capture or network capture tool. The agent can only call handlers a userscript explicitly registers, and results contain only what the script returns or reports.
Invocation requires a connected MCP session, an explicitly granted tab, an enabled installed script and the named handler registered in that document. Scripts opt in with
@grant GM.mcp(orGM_mcp) and an explicit registration. Registration is an application-level opt-in, not a new security sandbox: an agent already allowed to edit scripts can add a handler, and a handler can do anything its userscript can.File saving, download directories, local filesystem access and application-specific integrations are deferred to a separate change. Existing
GM_downloadbehavior is unchanged.Lifecycle and limits
400), unknown handlers (404) and denied access (403).timed_outcall.Compatibility and release
The MCP repository owns the tool schemas, typed client interfaces, capability negotiation and transport tests. The extension PR owns the GM API, authorization, per-document dispatch, result retention and page lifecycle. The README leaves the required Violentmonkey version empty until the extension release is known. The MCP package release and extension rollout should be coordinated.
Validation
handlerargument, handler-name validation and malformedscript_handlers/script_resultsoutput.GM_mcpran with@inject-into pageandGM.mcpwith@inject-into content, each in the top document, a same-origin iframe and a cross-origin iframe, with 12 named handlers per frame.unregister()removes only its own handlerswait: false, execution timeout and late completionpageshow.persisted === true, renewed document channels, handlers and metadata restored without repeated initializationLate replies could not overwrite cancelled calls, and no unexpected page JavaScript errors were observed. Firefox has not yet been verified in a real browser; build success is not a cross-browser compatibility claim.
Browser-tested revisions: MCP
162a229and extension1cdae382; later commits address review nits (a redundant assignment, formatting, message wording) and documentation.