Let AI agents (Claude, etc.) manage your Violentmonkey userscripts through the Model Context Protocol.
Violentmonkey runs inside the browser and cannot listen on a port, so a small local server bridges the two sides:
┌────────┐ MCP (stdio or HTTP) ┌──────────────────┐ WebSocket ┌───────────────┐
│ Agent │ ────────────────────► │ @violentmonkey/ │ ◄──────────── │ Violentmonkey │
│(Claude)│ ◄──────────────────── │ mcp (server) │ ──────────► │ (extension) │
└────────┘ └──────────────────┘ tool calls └───────────────┘
- The agent speaks MCP to the server.
- The extension connects to the server over a WebSocket, authenticated with a one-time token.
- The server owns the list of tools and their schemas. Agent tool calls are forwarded to the extension and the results are returned.
Claude Code:
claude mcp add violentmonkey -- npx -y @violentmonkey/mcp -p 5678Claude Desktop / any stdio-based client (mcpServers config):
{
"mcpServers": {
"violentmonkey": {
"command": "npx",
"args": ["-y", "@violentmonkey/mcp", "-p", "5678"]
}
}
}Ask the agent to call vm_status. It returns a connect URL such as:
https://violentmonkey.github.io/mcp_connect.html?port=5678&token=<generated_token>
Open it in the browser. Violentmonkey intercepts the URL and shows an authorization page; after you approve, the extension connects to the server and the tools become usable.
The same URL is also printed to stderr when the server starts.
"List my userscripts", "Create a script that hides the sidebar on example.com", "Fix the bug in my GitHub script".
npx @violentmonkey/mcp [options]
-p, --port <number> Port for the extension (and HTTP transport). Default: 5678
--host <host> Bind address. Default: 127.0.0.1
--token <string> Use a fixed token instead of generating one. Env: VM_MCP_TOKEN
--readonly Only expose read-only tools (no write, enable or delete)
--transport <type> MCP transport: "stdio" (default) or "http"
stdio (default) - the agent spawns the server as a child process. Nothing is written to stdout except MCP messages; logs go to stderr. The server lives as long as the agent session.
http - the server runs standalone and serves Streamable HTTP MCP at POST /mcp on the same port as the extension WebSocket. Use this when the agent is not on the same machine's process tree (remote agents, other devices). Requests must carry Authorization: Bearer <token>. Because a restarted server would invalidate the token, pass a fixed --token (or VM_MCP_TOKEN) in this mode.
VM_MCP_TOKEN=secret npx @violentmonkey/mcp -p 5678 --transport http
claude mcp add --transport http violentmonkey http://127.0.0.1:5678/mcp --header "Authorization: Bearer secret"Exposing the server beyond localhost (--host 0.0.0.0) is your responsibility; put it behind TLS and treat the token as a password. See docs/security.md.
| Tool | Description | Annotations |
|---|---|---|
vm_status |
Whether the extension is connected, its version, and the connect URL. Works even when disconnected. | read-only |
scripts_list |
List scripts (id, name, namespace, version, enabled, matches). | read-only |
scripts_get |
Get a script's metadata and source code by id. | read-only |
scripts_write |
Create or update a script from source code. With id it updates that script; without id it matches by @name and @namespace, or creates a new one. Returns whether it was created. |
idempotent |
scripts_set_enabled |
Enable or disable a script. | idempotent |
scripts_delete |
Remove a script. | destructive |
Exact input/output schemas live in packages/protocol and are the single source of truth.
In --readonly mode only the read-only tools (vm_status, scripts_list, scripts_get) are exposed.
When the extension is not connected, every tool except vm_status returns an MCP error result (isError: true) with code 503 and the message Violentmonkey is not connected. Over the HTTP transport this is a tool result, not an HTTP status, since the HTTP request itself succeeded.
The server binds to localhost, requires a token, and only accepts connections from the browser extension. Use --readonly if the agent should only be able to read your scripts. See docs/security.md for the threat model.
- docs/design.md: how it works.
- docs/protocol.md: the extension WebSocket protocol.
- DEVELOPMENT.md: packages, building, testing, releasing, and integrating the client library into the extension.
MIT