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.Plugin Location
Plugin Structure
Fields
Top Level
| Field | Required | Description |
|---|---|---|
description | Yes | What this site is |
base_url | Yes | Must match filename domain |
tags | No | For monosurf sites search |
commands | Yes | Available commands |
display | No | Output formatting |
Command Fields
| Field | Required | Description |
|---|---|---|
url | Yes | URL to navigate. {query} for variable substitution |
wait | No | CSS selector to wait for before extraction. Empty = timeout only |
wait_timeout | No | Seconds to wait (default: 10) |
extract_js | No | JavaScript that returns JSON.stringify([...]) |
intent | No | "read" (default) or "write" |
actions | No | Sequential actions for write operations |
Actions (Write Operations)
| Action | Description |
|---|---|
click | Click an element by CSS selector (JS element.click()) |
type | Type text into focused element. Supports multiline (line breaks preserved) |
sleep | Wait milliseconds |
js | Execute JavaScript in browser context via CDP Runtime.evaluate |
Accessing Accessibility Tree in JS Actions
For sites that strip CSS selectors (like Meta’s Threads), use ARIA roles in JS:pw (Playwright script) action type, which is no longer supported since MonoSurf v0.4 communicates with Chrome directly via CDP without Playwright.
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.
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 | Who | Trust |
|---|---|---|
openclis | Monolex team | Official — highest trust |
partner | Registered partner org | Trusted — org verified |
dev | Registered developer | Review recommended |
local | User’s machine | User’s responsibility |
Publishing
Installing
Reset to Official
local), reset restores the official version from backup.
Server Endpoints
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/plugins | GET | Public | List all plugins |
/plugins/<domain> | GET | Public | Get plugin + Ed25519 signature |
/admin/plugins | POST | JWT or Admin key | Upload/update plugin |
Indexing and Search
Existing Plugins
| Domain | Read | Write | Description |
|---|---|---|---|
x.com | search, timeline, read, trending | post, reply | X (Twitter) |
threads.net | feed, search, profile, read | post, reply, delete | Threads (Meta) |
news.ycombinator.com | top, new, ask, show, search, read | — | Hacker News |
github.com | trending, trending-weekly, search | — | GitHub |
reddit.com | hot, new, search, read, front | — | |
producthunt.com | today | — | Product Hunt |