AgentStack
MCP verified MIT Self-run

Opencanvas

mcp-ashark-ai-05-opencanvas · by ashark-ai-05

An infinite canvas your local LLM draws on. Typed widgets, BYO model (Claude/OpenAI/Ollama), MCP-native, local-first, MIT.

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add mcp-ashark-ai-05-opencanvas

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Opencanvas? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

OpenCanvas

Stop reading AI replies. Watch them assemble on an infinite canvas.

Your LLM doesn't print markdown — it places typed widgets on a tldraw canvas: charts, diagrams, code, kanbans, tables, custom HTML, anything. The agent learns your patterns and registers reusable widget templates over time. Works with any model that supports function calling — BYO key.

BYO model · MCP-native · Self-improving · Local-first · MIT

[](https://github.com/ashark-ai-05/opencanvas/actions/workflows/ci.yml) []() []() [](./LICENSE) [](./SECURITY.md)

▶︎ Try the demo  ·  ⭐ Star on GitHub  ·  📡 API reference  ·  🏗 Architecture

[Install](#install) · [Why](#why-its-different) · [Pick a model](#pick-any-llm) · [REST API](#drive-it-from-any-process) · [Security](./SECURITY.md)


What makes it different

| | OpenCanvas | Claude Artifacts | Cursor Composer | v0 (Vercel) | ChatGPT Canvas | |---|---|---|---|---|---| | Canvas-spatial UI | ✅ tldraw infinite canvas | ❌ single artifact pane | ❌ single editor pane | ❌ single preview pane | ⚠️ document only | | Multiple typed widgets per turn | ✅ markdown · chart · kanban · code · mermaid · custom HTML · … | ⚠️ one at a time | ❌ | ⚠️ one UI at a time | ❌ | | BYO model | ✅ any provider (Anthropic / OpenAI / Google / Groq / Ollama / OpenRouter) | ❌ Claude only | ⚠️ OpenAI + Anthropic + a few | ❌ Vercel-hosted | ❌ OpenAI only | | MCP-native | ✅ first-class | ✅ via Claude.ai | ⚠️ recent | ❌ | ❌ | | Self-improving widgets | ✅ agent extracts templates from its own renders | ❌ | ❌ | ❌ | ❌ | | Self-hosted / open source | ✅ MIT | ❌ | ❌ | ❌ | ❌ | | Local-first option | ✅ runs entirely on your machine | ❌ | ⚠️ partial | ❌ | ❌ |


Install

git clone https://github.com/ashark-ai-05/opencanvas.git
cd opencanvas
pnpm install
cp .env.example .env       # at least one provider key
pnpm electron:dev          # backend + Vite + Electron, one command

Headless without Electron: pnpm dev → http://127.0.0.1:3458

> Packaged installers (.dmg / .exe / .AppImage) ship via the Releases tab. Want to host a public demo? See [docs/deploy-railway.md](./docs/deploy-railway.md) — Railway + Groq Llama 3.1 70B, ~10 minutes.


Why it's different

| | Most chat apps | OpenCanvas | |---|---|---| | Output | A long stream of text | Typed widgets on a canvas — click, drag, pin, link, export | | Memory | Per-message context window | Self-improving SQLite KB; every chat is searchable across conversations | | Tools | A handful, baked in | 15 widget kinds + 12 agent tools + your MCP servers + runtime plugins | | Sources | Chat-only | MCP-native — any server (Confluence, Jira, filesystem, GitHub, …) | | Drive | Chat input only | REST API — any local process can render widgets via POST /v1/canvas/* | | Privacy | Cloud round-trips | Single-user, BYO credentials, runs entirely on your machine |


Pick any LLM

Every provider gets the same agent — same tools, same widget surface, same UX. The model is a config switch:

| Provider | Auth | Notes | |---|---|---| | Anthropic | ANTHROPIC_API_KEY | Claude Sonnet/Opus 4+; extended thinking auto-on | | OpenAI | OPENAI_API_KEY | GPT-4o, GPT-4.1, o-series | | Google Gemini | GOOGLE_API_KEY | Gemini 2.5/3.x Flash & Pro; thinking surfaces in the chat | | Groq | GROQ_API_KEY | Llama / Mixtral / Kimi at Groq speeds | | OpenRouter | OPENROUTER_API_KEY | One key, hundreds of models | | Ollama | none — local | Any model you've pulled (llama3.2, qwen2.5-coder, …) | | Sourcegraph Amp | AMP_API_KEY | Hosted agent loop (legacy path) |

Tool calling is driven by the Vercel AI SDK, so any provider with function-calling support works the same way. See [docs/plans/unified-agent.md](./docs/plans/unified-agent.md) for the architecture.

Embedders are pluggable too: bundled ONNX (runs offline), OpenAI, Voyage, or Ollama.

Fully-local config example

// ~/.opencanvas/config.json
{
  "activeProfile": "local",
  "profiles": [{
    "name": "local",
    "llm":   { "provider": "ollama", "model": "llama3.1:8b" },
    "embed": { "provider": "ollama", "model": "nomic-embed-text" },
    "sources": []
  }]
}

The widget catalog

15 kinds. Markdown · code blocks · tables · timelines · file trees · kanban · tasks · sticky notes · composite cards · charts (Vega-Lite) · calendars · clock/timer/stopwatch/pomodoro · web embeds (sandboxed iframes) · plugin-rendered iframes · generic fallback.

Every widget is a typed contract — Zod schema for props + a React component. Add a new kind without retraining anything.

Runtime plugins. The agent can call register_widget_kind mid-conversation to declare a new widget on the fly. Ships with a Python REPL (Pyodide) and a JS REPL example. Plugin iframes run with sandbox="allow-scripts", no allow-same-origin — null origin, no parent DOM access.


MCP-native

Add any MCP server under profiles[].sources — works with any LLM provider:

{
  "sources": [{
    "id": "dev-fs",
    "transport": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/Development"]
  }]
}

pnpm cli --probe-sources to verify. The agent invokes them as mcp__dev-fs__.


Drive it from any process

Any local process — cron jobs, watchers, scripts — can render widgets. The browser keeps an SSE connection open to /v1/canvas/events; external POSTs push directives into the per-conversation event bus.

# Place a Vega-Lite chart from your terminal
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":{...}}}'

Full REST reference: browse the live API docs (Scalar / Swagger UI), or read the raw [OpenAPI 3.1 spec](./docs/openapi.yaml). When the backend is running, the same UI is served at http://127.0.0.1:3457/docs.

Auth. A 256-bit token is generated on first run and persisted to ~/.opencanvas/auth-token (mode 0600). Required on state-mutating routes. See [SECURITY.md](./SECURITY.md).


Self-improving KB

Every conversation auto-indexes into the same SQLite + sqlite-vec store as your docs and code. Old turns become searchable via search_kb. Hybrid BM25 + vector retrieval. Idempotent re-indexing — re-running on unchanged content costs zero LLM calls.

pnpm cli --index ./docs            # markdown / text → chunks + embeddings
pnpm cli --index-code ./src        # tree-sitter chunks + symbols
pnpm cli --search ""        # hybrid search

The agent also learns you — kinds you keep + pin score higher; kinds you dismiss bias the next placement away. Per-conversation, persisted locally, no remote tracking.


Architecture

┌────────────────────┐                ┌─────────────────────────┐
│  Vite + React +    │   /v1/chat     │  Hono backend           │
│  tldraw            │ ─────────────→ │                         │
│  • floating chat   │                │  6 LLM adapters         │
│  • canvas          │                │  12 in-process tools    │
│  • palette ⌘K      │ ←── SSE ────── │  + external MCP servers │
│  • history         │  /v1/canvas/   │  + plugin registry      │
└────────────────────┘    events      │       │                 │
                                      │       ▼                 │
                                      │  SQLite + sqlite-vec    │
                                      └─────────────────────────┘

tldraw v3 with one shape util per widget kind. Zustand for app state. AI SDK 6 for chat streaming. Hono + better-sqlite3 + sqlite-vec on the backend. Electron wrapper for the desktop install.


Development

pnpm test                                          # backend (vitest, Node)
pnpm vitest run --config app/vite.config.ts        # frontend (vitest + jsdom)
pnpm typecheck                                     # tsc --noEmit
pnpm app:build                                     # production bundle
pnpm dist                                          # electron-builder installer

596 tests passing · 383 backend, 213 frontend.


Status

Experimental. Solo project, MIT. No telemetry, no remote services unless you point it at one.

Issues + PRs welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md). For security issues, [SECURITY.md](./SECURITY.md).

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.