# Opencanvas

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

- **Type:** MCP server
- **Install:** `agentstack add mcp-ashark-ai-05-opencanvas`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ashark-ai-05](https://agentstack.voostack.com/s/ashark-ai-05)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ashark-ai-05](https://github.com/ashark-ai-05)
- **Source:** https://github.com/ashark-ai-05/opencanvas
- **Website:** https://github.com/ashark-ai-05/opencanvas#readme

## Install

```sh
agentstack add mcp-ashark-ai-05-opencanvas
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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
  &nbsp;·&nbsp;
  ⭐ Star on GitHub
  &nbsp;·&nbsp;
  📡 API reference
  &nbsp;·&nbsp;
  🏗 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

```bash
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](https://github.com/ashark-ai-05/opencanvas/releases). 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](https://ai-sdk.dev/), 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

```jsonc
// ~/.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:

```jsonc
{
  "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 `POST`s push directives into the per-conversation event bus.

```bash
# 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](https://ashark-ai-05.github.io/opencanvas/api.html) (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.

```bash
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

```bash
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.

- **Author:** [ashark-ai-05](https://github.com/ashark-ai-05)
- **Source:** [ashark-ai-05/opencanvas](https://github.com/ashark-ai-05/opencanvas)
- **License:** MIT
- **Homepage:** https://github.com/ashark-ai-05/opencanvas#readme

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

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-ashark-ai-05-opencanvas
- Seller: https://agentstack.voostack.com/s/ashark-ai-05
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
