An open canvas workspace for AI coding agents
Jetro
Give your AI coding agent an infinite visual workspace.
Jetro is an open-source VS Code extension that adds a living canvas to your editor. Your AI agent can render charts, tables, dashboards, interactive frames, and rich data visualizations โ all on a spatial, persistent surface.
Your coding agent is powerful, but it's trapped in a text window. Jetro unlocks its full potential by giving it a visual layer to build on.
jetro.ai โ Try the hosted version with built-in data, skills, and sharing. No setup required.
Features
- Infinite Canvas โ draggable, resizable elements: frames, charts, notes, embeds
- MCP Integration โ works with any MCP-compatible agent (Claude Code, Cursor, Copilot, Cline, Windsurf, Qwen, etc.)
- Live Frames โ HTML iframes with Python refresh bindings for real-time dashboards
- Charts โ Plotly.js bundled for instant chart rendering (bar, scatter, pie, candlestick, and more)
- C2 Mode โ wire frames together with named data channels for interconnected dashboards
- Data Layer โ import CSV, Excel, Parquet, JSON; query with SQL via DuckDB
- Document Parsing โ PDF, DOCX, PPTX, XLSX, HTML, images (OCR)
- Code Execution โ run Python/R scripts in sandboxed subprocesses
- Data Connectors โ reusable Python modules for external APIs, databases, spreadsheets
- Deploy โ containerize projects as web apps with Docker
- Share โ publish canvas elements as interactive web pages (requires backend)
- Projects โ organize work into scoped workspaces with their own canvases
Platform Support
| Platform | Status | |----------|--------| | macOS (Apple Silicon) | Fully supported | | macOS (Intel) | Fully supported | | Windows (x64) | Fully supported | | Linux (x64) | Supported |
Getting Started
Prerequisites
- Node.js 18+ โ required for building and running the MCP server
- VS Code 1.85+ (or compatible: Cursor, Windsurf, Antigravity, or any VS Code fork)
- Python 3 (optional) โ for document parsing, live refresh scripts, and code execution
- Docker (optional) โ for deploying projects as web apps
Clone and Install
git clone https://github.com/JetroExtension/Jetro.git
cd Jetro
Install extension dependencies
cd extension
npm install
Install MCP server dependencies
cd ../mcp-server
npm install
cd ..
Build Everything
The extension has four build targets that must all be built:
cd extension
1. Extension backend (TypeScript โ single JS bundle)
npm run build:ext
2. Canvas webview (React app โ bundled HTML/JS/CSS)
npm run build:webview
3. Daemon (headless background worker for refresh bindings)
npm run build:daemon
4. MCP server (TypeScript โ bundled JS, copied into extension)
npm run build:mcp
Or build all four at once:
npm run package
Run in Development (F5)
- Open the
extension/folder in VS Code - Press F5 โ this launches a new Extension Development Host window
- The Jetro sidebar appears in the activity bar
- Open a folder in the dev host โ Jetro initializes
- You're automatically logged in as
jetro@jetro.ai(dev mode) - Ask your AI agent to build something โ it renders to the canvas
Package as .vsix
To build an installable .vsix package:
cd extension
bash scripts/build-vsix.sh
This runs all build steps, creates a minimal node_modules (native deps only), and packages everything into jetro-0.0.5.vsix.
Install it:
code --install-extension jetro-0.0.5.vsix
What Each Build Target Does
| Command | What it builds | Output | |---------|---------------|--------| | npm run build:ext | Extension backend (activation, tools, services) | out/extension.js | | npm run build:webview | Canvas React app + connector UI | webview/canvas.js, webview/connector.js | | npm run build:daemon | Headless daemon for background refresh bindings | dist/daemon.js | | npm run build:mcp | MCP server (tool handlers for agents) | mcp-server/out/index.js | | npm run package | All of the above | All outputs |
Dev Mode
Out of the box, Jetro runs in dev mode โ no Firebase, no backend, no sign-up required.
You're automatically logged in as jetro@jetro.ai. All core features work immediately:
- Canvas rendering and layout
- MCP tools (jetrender, jetcanvas, jetexec, jetquery, jet_parse, etc.)
- Code execution (Python/R)
- DuckDB SQL queries and dataset import
- Document parsing
- Live refresh bindings (script-based)
- Data connectors
- Deploy (Docker, local)
jet_dataโ financial data API proxy (configure your own data provider)jet_shareโ publishing canvas elements to shareable URLs- Deploy publishing โ public URLs for deployed apps
Adding Your Own Content
Skills
Skills are analysis prompts your agent fetches via jet_skill({ name: "Skill Name" }).
Create JSON files in extension/agent/skills/:
{
"name": "Company Analysis",
"description": "Deep-dive analysis of a public company",
"prompt": "You are analyzing a company. Follow these steps:\n1. Fetch the company profile using jetdata\n2. Review the financial statements\n3. Render your findings to the canvas using jetrender\n..."
}
Skills are loaded on extension activation and listed in CLAUDE.md automatically. The agent sees the name and description; the full prompt is fetched on demand when the agent calls jet_skill.
Templates
Templates are output formats your agent fetches via jet_template({ name: "Template Name" }).
Create JSON files in extension/agent/templates/:
{
"name": "Investment Report",
"description": "Structured equity research report format",
"content": "# {Company Name} โ Investment Report\n\n## Executive Summary\n...\n\n## Financial Analysis\n...\n\n## Valuation\n..."
}
System Prompt
The system prompt is your agent's operating doctrine โ methodology, priorities, behavioral guidelines.
Create extension/agent/system-prompts/prompt.md:
# My Agent Doctrine
You are a research assistant specializing in...
Methodology
- Always verify data from multiple sources
- Present findings with supporting evidence
- ...
Priorities
- Accuracy over speed
- ...
The system prompt is delivered to the agent on the first MCP tool call of each session. It's held in memory only โ never written to the user's workspace.
Configuration
Data API (optional)
The jet_data tool proxies data requests through a backend API. By default, it points to http://localhost:8787.
To use your own backend:
- Open VS Code settings (Cmd/Ctrl + ,)
- Search for
jetro.apiUrl - Set it to your backend URL
jet_data won't work. But you can still use: jet.marketโ free market data (yfinance wrapper) available in Python scriptsjet_execโ run any Python/R code that fetches data directly- All other tools work fully locally
Authentication (optional)
Dev mode works without any auth. To add real user authentication:
- Create a Firebase project at https://console.firebase.google.com
- Enable Email/Password authentication
- Get your Web API Key from Project Settings โ General
- Edit
extension/src/services/firebaseConfig.ts:
export const FIREBASEAPIKEY = "your-api-key-here";
export const FIREBASEPROJECTID = "your-project-id";
- Rebuild:
npm run build:ext
Deploy Relay (optional)
To publish deployed apps with public URLs:
- Set up your own backend with relay support
- In VS Code settings, set
jetro.relayDomainto your domain
Project Structure
Jetro/
โโโ extension/ # VS Code extension
โ โโโ src/ # TypeScript source
โ โ โโโ extension.ts # Activation, command registration
โ โ โโโ canvas/ # Canvas webview (React + xyflow)
โ โ โ โโโ app/ # React app: nodes, toolbar, edges
โ โ โโโ sidebar/ # Sidebar webview (auth, library, projects)
โ โ โโโ services/ # Core services
โ โ โ โโโ authService.ts # Auth (Firebase or dev mode)
โ โ โ โโโ bootstrapService.ts # Loads skills/templates, generates CLAUDE.md
โ โ โ โโโ fileManager.ts # Workspace file operations
โ โ โ โโโ nativeManager.ts # Node.js detection, MCP server deployment
โ โ โ โโโ refreshBindingManager.ts # Live refresh timer management
โ โ โ โโโ shareManager.ts # Share lifecycle (requires backend)
โ โ โ โโโ deployManager.ts # Docker deploy lifecycle
โ โ โ โโโ duckdb.ts # DuckDB cache (NAPI)
โ โ โโโ tools/ # MCP tool handlers (extension side)
โ โ โโโ daemon/ # Headless background worker
โ โ โโโ types/ # TypeScript type definitions
โ โโโ agent/ # Bundled agent content
โ โ โโโ skills/ # Your skill JSON files
โ โ โโโ templates/ # Your template JSON files
โ โ โโโ system-prompts/ # Your system prompt (prompt.md)
โ โ โโโ docs/ # Reference guide for agent help
โ โโโ scripts/ # Build scripts
โ โ โโโ build-vsix.sh # Full VSIX build pipeline
โ โ โโโ prepare-modules.sh # Strip node_modules for packaging
โ โ โโโ restore-modules.sh # Restore full node_modules after packaging
โ โโโ assets/ # Icons, images
โ โโโ esbuild.extension.mjs # Extension bundler config
โ โโโ esbuild.webview.mjs # Webview bundler config
โ โโโ package.json # Extension manifest
โ โโโ tsconfig.json # TypeScript config
โโโ mcp-server/ # MCP server (stdio)
โ โโโ src/index.ts # All MCP tool definitions and handlers
โ โโโ esbuild.mcp.mjs # MCP server bundler config
โโโ agent/ # Agent content (source of truth)
โ โโโ skills/ # Skill definitions (add yours here)
โ โโโ templates/ # Template definitions (add yours here)
โ โโโ system-prompts/ # System prompt (add yours here)
โ โโโ docs/ # Reference documentation
โโโ LICENSE # MIT
โโโ README.md # This file
How It Works
- Activation โ extension starts, detects system Node.js, deploys MCP server to
~/.jetro/mcp-server/ - Bootstrap โ reads skills/templates from
extension/agent/, generatesCLAUDE.md(thin prompt) listing available tools and skills - MCP Config โ writes
.mcp.jsonto workspace so agents discover Jetro's tools automatically - Agent interaction โ agent calls MCP tools (
jetrender,jetdata,jet_canvas, etc.) โ results render on canvas - System prompt โ delivered on first tool call via
wrapResponse()(held in memory, never on disk) - Refresh bindings โ Python scripts run on timers, output JSON โ pushed into frame iframes via
jet:refreshCustomEvent
MCP Tools
| Tool | Purpose | |------|---------| | jet_render | Render elements to canvas (frame, chart, note, embed) | | jet_canvas | Canvas operations (read, move, resize, arrange, bind, delete) | | jet_data | Fetch data from configured API (requires backend) | | jet_query | Query local DuckDB cache with SQL | | jet_exec | Execute Python/R code | | jet_parse | Parse documents (PDF, DOCX, images, etc.) to markdown | | jet_save | Save structured data (lists, projects, portfolios) | | jet_skill | Fetch a skill prompt by name | | jet_template | Fetch a template by name | | jet_search | Search for stock/security symbols | | jet_deploy | Deploy project as Docker web app | | jet_share | Share canvas elements as web pages (requires backend) | | jet_connector | Create/manage data connectors |
MCP Configuration by Editor
Jetro auto-writes MCP config for most editors. If your agent can't see tools:
| Editor | Config Location | Auto-configured? | |--------|----------------|-----------------| | Claude Code / VS Code | {workspace}/.mcp.json | Yes | | Cursor | {workspace}/.cursor/mcp.json | Yes | | Antigravity | ~/.gemini/antigravity/mcp_config.json | Yes | | Windsurf | Global settings | Manual | | Codex (OpenAI) | ~/.codex/config.toml (TOML format) | Manual | | Qwen Code | {workspace}/.qwen/settings.json | Manual | | Cline | VS Code globalStorage | Manual | | Continue | ~/.continue/config.yaml | Manual |
For manual setup, copy the server entry from .jetro/mcp-config.json in your workspace.
Troubleshooting
MCP Tools Not Loading
- Run "Jetro: Reinitialize MCP Server" from the command palette
- Check Output panel โ filter "Jetro" for errors
- Verify
.mcp.jsonexists in workspace root - Ensure Node.js 18+ is installed:
node --version - Restart your editor
Frame Preview is Blank
- Click the refresh button (circular arrow) in the canvas toolbar
- Switch to another canvas tab and back
- Ensure HTML is a complete document (
<!DOCTYPE html><html>...</html>)
Refresh Script Not Running
- Check Output panel โ filter "Jetro" for
[bindings]errors - Test manually:
python3 .jetro/scripts/your_script.py - Script must output valid JSON to stdout
- Ensure Python 3 is installed
DuckDB Not Working
- DuckDB uses NAPI bindings โ works across all Node/Electron versions
- If it fails on first run, sign out and back in (re-initializes after workspace creation)
- Check Output panel for
DuckDB initmessages
Deploy Fails
- Ensure Docker Desktop is installed and running
- Check
projects/{slug}/deploy/hasserver.py,requirements.txt,Dockerfile - Check Output panel โ filter "Jetro" for
[deploy]errors
Customization
Thin Prompt (CLAUDE.md)
The thin prompt is the auto-generated CLAUDE.md that agents read on every turn. It tells the agent what tools exist and how to use them.
To customize it (add behavioral doctrine, domain-specific instructions, language preferences), edit the content array in extension/src/services/bootstrapService.ts โ injectAgentContext().
See agent/docs/thin-prompt-reference.md for a full guide on customization, including how to add working style, language support, and domain guidelines.
Custom MCP Tools
Tools are defined in mcp-server/src/index.ts in the TOOLS array. Each tool has a name, description, and JSON Schema for its input parameters. To add a custom tool:
- Add the tool definition to the
TOOLSarray:
{
name: "my_tool",
description: "What this tool does",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "The input" }
},
required: ["query"]
}
}
- Add a handler function:
async function handleMyTool(args: { query: string }): Promise<string> {
// Your logic here
return JSON.stringify({ result: "..." });
}
- Wire it in the tool dispatcher's
switchstatement
- Rebuild:
npm run build:mcp
Contributing
Contributions welcome! Please open an issue first to discuss what you'd like to change.
- Fork the repo
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes
- Test locally (F5 in VS Code)
- Submit a pull request
Development Workflow
# Terminal 1: Watch extension
cd extension && npm run build:ext -- --watch
Terminal 2: Watch webview
cd extension && npm run build:webview -- --watch
Terminal 3: Watch MCP server
cd mcp-server && npm run build -- --watch
VS Code: Press F5 to launch Extension Development Host
Setting Up a Test Workspace
When you press F5, VS Code opens an Extension Development Host. To pre-configure a test folder, create extension/.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}", "/path/to/your/test/folder"]
}
]
}
Replace /path/to/your/test/folder with any folder on your machine. The Extension Development Host will open that folder with Jetro active.
Links
- jetro.ai โ Hosted version with built-in data, skills, and sharing
- Open VSX โ Install from Open VSX marketplace
- VS Code Marketplace โ Install from Microsoft marketplace
License
MIT License. See LICENSE for details.