Documentation Index
Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
Use this file to discover all available pages before exploring further.
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
~/Library/Application Support/Monolex/monosurf/sites/
├── x.com.json
├── threads.net.json
├── news.ycombinator.com.json
├── github.com.json
├── reddit.com.json
└── producthunt.com.json
Plugin Structure
{
"description": "Human-readable site description",
"base_url": "https://example.com",
"tags": ["category", "tags", "for", "search"],
"commands": {
"command_name": {
"url": "/path?q={query}",
"wait": "css-selector",
"wait_timeout": 10,
"extract_js": "(() => { /* JS that returns JSON array */ })()",
"intent": "read"
}
},
"display": {
"command_name": {
"format": "list",
"template": "{field1} — {field2}\n {field3}"
}
}
}
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)
"actions": [
{"click": "css-selector"},
{"type": "{text}"},
{"sleep": 500},
{"js": "(() => { document.querySelector('[role=button]').click(); return 'clicked'; })()"}
]
| 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:
{"js": "(() => { const btns = document.querySelectorAll('[role=button]'); for (const b of btns) { if (b.textContent.trim() === 'Reply') { b.click(); return 'clicked'; } } return 'not found'; })()"}
This replaces the v0.2 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:
"display": {
"top": {
"format": "list",
"template": "{rank}. {title} ({site})\n {score} | {author} | {comments}"
}
}
Domain Security
The filename IS the identity. MonoSurf enforces:
- Filename = domain:
x.com.json can only define base_url for x.com
- URL validation: Relative URLs are prepended with
base_url
- Mismatch = rejection: If
base_url domain doesn’t match filename, plugin is refused
This prevents a malicious plugin from masquerading as another domain.
Variable Substitution
URLs and type actions support {variable} syntax:
monosurf x.com search "rust programming"
↓
url: "/search?q={query}" → "/search?q=rust%20programming"
Variables come from CLI positional arguments:
- First arg after command →
{query}, {id}, {text}
- Unresolved variables are silently removed
Commands can reuse extraction logic from other commands:
"new": {
"url": "/newest",
"wait": ".athing",
"extract_js": "$ref:top"
}
$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
monosurf sites sign # Sign all plugins
monosurf sites sign x.com # Sign one plugin
Signing computes a checksum of all extract_js and actions in the plugin and writes it to the JSON:
"integrity": {
"verified": "2026-04-07",
"checksum": "c707dc804a7b0065"
}
Verification
[OK] x.com: OK (verified: 2026-04-07)
[OK] github.com: OK (verified: 2026-04-07)
[TAMPERED] reddit.com: Checksum mismatch. Plugin may have been modified.
[UNSIGNED] custom.com: No checksum. Run 'monosurf sites sign' to seal.
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 sign to re-seal
Plugin Registry
Official plugins are distributed through api.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 |
Source is determined server-side from the developer’s JWT org membership. It cannot be self-asserted by the client.
Publishing
openclis-dev login # authenticate as developer
monosurf sites push x.com # upload to registry
Installing
monosurf sites pull x.com # download from registry (Ed25519 signed)
Reset to Official
monosurf sites reset x.com # restore from official backup
If AI modifies a plugin locally (source changes to 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
monosurf sites index # Scan all JSON files → SQLite index
monosurf sites search "tech" # Search by tags, description, domain
monosurf sites # List all installed plugins
The index enables AI to discover which sites are available:
AI: "What tech news sites can I read?"
→ monosurf sites search "tech news"
→ news.ycombinator.com, reddit.com, producthunt.com
→ monosurf news.ycombinator.com top --limit 5
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 | — | Reddit |
producthunt.com | today | — | Product Hunt |