It is the web platform
Not a proprietary DSL. fetch, getUserMedia, IndexedDB, WebAuthn and Web Push all work. Chrome
DevTools, Playwright and Vitest work. If you can build a web app, you can build a mini app.
This documentation describes a platform that is being built. Nothing here ships today. It is published early because the specification is meant to be read, argued with and corrected before the runtime is frozen — and because it is the interface a company’s AI agent will read to produce a mini app. Where research did not settle a question, the page says so instead of guessing.
Sollar’s core is deliberately narrow: messaging, calls, translation, groups, AI agents. Nothing else. There are no connectors, no MCP, no plugins, no skills in the core.
Everything that turns Sollar into a superapp — a CRM, an ERP, an approvals queue, a mail client, a catalogue — arrives as a mini app: HTML, CSS and JavaScript in a signed package, verified and run in an isolated WebView, with access to a declared set of Sollar capabilities.
It is the web platform
Not a proprietary DSL. fetch, getUserMedia, IndexedDB, WebAuthn and Web Push all work. Chrome
DevTools, Playwright and Vitest work. If you can build a web app, you can build a mini app.
One manifest, two audiences
The actions[] you declare render as buttons for a human and as callable tools for a Sollar
AI agent. One declaration, never two lists to keep in sync.
Your company can ship without us
A tenant-private mini app — your own ERP, for your own staff — is signed by your organisation and needs no Sollar review. Your release cycle is not our queue.
Written to be read by a machine
Every page is served as raw Markdown at <path>.md, plus llms.txt and llms-full.txt. The
bridge contract is a TypeScript .d.ts; the manifest is JSON Schema.
{ "manifest_version": 1, "name": "Acme ERP", "version": "2.4.1", "permissions": [ { "scope": "sollar.room.context", "purpose": "Attach the current conversation to a purchase order." } ], "network": { "connect": ["erp.acme.example"] }, "actions": [ { "name": "list_pending_approvals", "title": "List pending approvals", "description": "Returns purchase orders awaiting the current user's approval, most urgent first.", "annotations": { "read_only": true, "destructive": false, "idempotent": true, "open_world": false }, "confirm": "never" } ]}sollar.actions.handle('list_pending_approvals', async ({ limit = 10 }) => { const { token } = await sollar.auth.getToken() const res = await fetch(`https://erp.acme.example/approvals?limit=${limit}`, { headers: { Authorization: `Bearer ${token}` }, }) return { approvals: await res.json() }})That is the whole idea. A human taps List pending approvals; an agent calls
list_pending_approvals. Same code, same permission check, same audit trail.
| If you want to… | Read |
|---|---|
| Build something in ten minutes | Get started |
Understand what sollar.* can do | Bridge API reference |
| Wire a mini app to your own backend | Authentication |
| Make your app usable by AI agents | Agent actions |
| Know why the runtime is a WebView | Runtime architecture |
| Check what Apple and Google allow | Store compliance |
| Point Claude Code at this site | Build with AI |