Ask anything. The agent renders typed widgets on a tldraw canvas — markdown, charts, kanbans, code, tables, web embeds, sandboxed plugins. Every conversation indexes back into a local SQLite KB, so the canvas gets smarter with every turn.
User types a question · agent renders six typed widgets · drag, pin, link, export.
Every output is a typed contract between the agent and the renderer. Add new widget kinds without fine-tuning. Plug in any MCP server. Drive the canvas from any process.
15 built-in widget kinds — markdown, code, tables, charts, kanban, calendars, web embeds, sandboxed plugins. Each is a Zod schema + a React component. Add more without retraining.
Six provider adapters: Claude (Agent SDK or direct), OpenAI, OpenRouter, Ollama (fully local), Sourcegraph Amp. Switch via one config field. Run it 100% offline if you want.
Drop in any Model Context Protocol server — Confluence, Jira, filesystem, GitHub. Every LLM provider gets them via tool-use, whether it's Claude, GPT, or a local Llama.
Every conversation auto-indexes into a local SQLite + sqlite-vec store. Old turns become searchable across all your chats. Hybrid BM25 + vector retrieval. Bigger context with use.
Any local process — cron jobs, watchers, scripts — can render
widgets via POST /v1/canvas/widgets.
Authenticated. Browser tab sees them live via SSE.
Token-authenticated local backend. Strict CORS. Sandboxed plugin iframes (null origin, no parent DOM access). No telemetry, no remote services unless you point it at one.
# Clone, install, configure, run. git clone https://github.com/ashark-ai-05/opencanvas.git cd opencanvas pnpm install cp .env.example .env # set at least one provider key pnpm electron:dev # full stack: backend + Vite + Electron
Packaged installers (.dmg /
.exe /
.AppImage) ship via the
Releases tab.
The canvas isn't just for the agent. Any local process can place
widgets, stream long answers, register custom widget kinds, and
inspect canvas state via a REST API. Full
/openapi.yaml
spec ships in the repo; Swagger UI lives at
/docs
when the backend's running.
# Place a chart from your shell. curl -X POST http://127.0.0.1:3457/v1/canvas/widgets \ -H 'content-type: application/json' \ -H "x-opencanvas-token: $(cat ~/.opencanvas/auth-token)" \ -d '{ "kind": "chart", "role": "primary", "payload": { "title": "Sales", "spec": { ... } } }'