Site Plugins
Every website MonoSurf can access is defined by a single JSON file. Adding a new site means creating one file — no Rust code, no rebuilding, no deploying. Standalonemonosurf and kernel-cli websurf enter through the same lib-monosurf facade and load the same plugins through lib-monosurf-core.
Verified against monosurf 0.11.3, OpenCLIs build
2026-07-19-222928.
Plugin Location
Plugin Structure
Fields
Top Level
Command Fields
Actions (Write Operations)
Accessing Accessibility Tree in JS Actions
For sites that strip CSS selectors (like Meta’s Threads), use ARIA roles in JS:js, click, type, and wait for current CDP workflows. Legacy plugin
JSON can still contain a pw action and monosurf sites help currently lists
that compatibility shape, but execution fails closed with conversion guidance.
Display Templates
Templates use{field} to reference fields from extracted JSON objects:
Domain Security
The filename IS the identity. MonoSurf enforces:- Filename = domain:
x.com.jsoncan only definebase_urlforx.com - URL validation: Relative URLs are prepended with
base_url - Mismatch = rejection: If
base_urldomain doesn’t match filename, plugin is refused
Variable Substitution
URLs and type actions support{variable} syntax:
- First arg after command →
{query},{id},{text} - Unresolved variables are silently removed
Shared Extraction via $ref
Commands can reuse extraction logic from other commands:$ref:top copies the extract_js from the top command. Avoids duplicating long JavaScript strings.
Plugin Integrity
Site plugins contain JavaScript that runs in the browser. MonoSurf protects against tampering with a checksum system.Signing
extract_js and actions in the plugin and writes it to the JSON:
Verification
Runtime Enforcement
Every plugin execution checks integrity before running:- OK — executes normally
- UNSIGNED — blocked. Must be signed before first use.
- TAMPERED — blocked. Execution refused until reviewed and re-signed.
--user-data-dir. A known
foreign listener blocks immediately, and temporarily unknown ownership gets
only a bounded settle interval before failure. The command stops before the plugin can navigate, read cookies, or run actions. This protects unattended
site commands and batch work as well as direct profile browsing.
If the live domain jar is empty and a gated bridge/login snapshot exists,
hydration happens before plugin navigation. Every cookie scope is validated,
an explicit HTTP(S) origin is supplied, attributes are preserved, and any CDP
error fails the command. A non-empty live jar always wins.
Workflow
- Create or modify a plugin JSON
monosurf sites sign— seal it- Plugin runs normally
- If JSON is modified externally → checksum breaks → execution blocked
- Review the change →
monosurf sites signto re-seal
Plugin Registry
Official plugins are distributed throughapi.openclis.com. Users can pull plugins from the server, and authorized developers can push updates.
Source Levels
Source is determined server-side from the developer’s JWT org membership. It cannot be self-asserted by the client.
Publishing
Installing
Reset to Official
local), reset restores the official version from backup.