Connect an LLM (Claude, or anything that speaks MCP or plain HTTP) to the chart you have open in Openview. It can read the candles, indicators, alerts and drawings, and draw on the chart — support/resistance lines, Fibonacci retracements, trend lines, notes. Ask “where is the resistance on this chart?” and it pulls the bars, works it out, and marks the levels.
Can: read the active chart (symbol, timeframe, bars, indicators, alerts, drawings), fetch candles for any symbol and timeframe, add drawings, and remove drawings it created.
Can never: touch the app’s code or settings, create or change alerts or indicators, delete your drawings, or reach anything outside the chart surface. There is no code-execution path. Everything an LLM draws is tagged, shows up in the object tree, and is one Ctrl+Z away from gone.
node mcp/server.mjsIt binds http://127.0.0.1:8787 and also serves the app itself.http://127.0.0.1:8787/ — any localhost-served copy or a file:// open works too; the page auto-connects to the bridge. On a non-localhost origin, add ?agent=1 to the URL.claude mcp add openview -- node /absolute/path/to/openvieweb/mcp/server.mjs --mcpClaude Desktop: add the same command under mcpServers in its config. --mcp starts its own HTTP server, or attaches to one already running on the port — start order doesn’t matter.| Tool | Does |
|---|---|
get_chart | Active symbol, timeframe, chart type, bar count, last bar, visible range |
get_bars | OHLCV candles (symbol?, timeframe?, limit? ≤ 1500) — defaults to the open chart |
get_indicators | Moving averages with current values, RSI, added indicators (read-only) |
get_alerts | The symbol’s alerts (read-only) |
list_drawings | Every drawing on the chart (llm:true = added by the LLM) |
add_drawings | Batch-add drawings: hline, trend, ray, ext, vline, rect, ellipse, fib, fibext, fibfan, fibtime, channel, pitchfork, triangle, text, callout, pricelabel, flag… |
remove_drawings | Remove LLM-added drawings by id, or all of them (llm_only:true) |
Same capabilities, served from http://127.0.0.1:8787.
GET /api/health → { ok, appConnected }
GET /api/chart
GET /api/bars?symbol=&timeframe=&limit=
GET /api/indicators
GET /api/alerts
GET /api/drawings
POST /api/drawings body: { drawings:[{type, points:[{time,price}], color?, width?, dash?, text?, name?}] }
DELETE /api/drawings/<id> (LLM-added drawings only)
DELETE /api/drawings?llm=1 (clear all LLM-added drawings)Times are UNIX seconds. Timeframes: 1m 5m 15m 30m 1h 2h 4h 6h 12h 1d 1w 2w 1M 1Y (1M = month, 1m = minute). dash: 0 solid, 1 dashed, 2 dotted.
| Env / setting | Default | Meaning |
|---|---|---|
OPENVIEW_PORT | 8787 | Server port (page side: localStorage.fv_agent_port) |
OPENVIEW_TOKEN | off | Optional shared secret; clients must send X-OpenView-Token |
The bridge is local-only by design: it binds 127.0.0.1 only, enforces a Host-header allowlist (blocking DNS rebinding), and requires browser callers to have a localhost or file:// origin — hostile origins are rejected.
Both the server and the page enforce a fixed command allowlist: no eval, no filesystem access, no settings surface. Drawing input is validated and capped (≤ 40 per call, ≤ 400 total, text sanitized), request bodies are capped at 512 KB, and the static file server refuses dotfiles and .env*. The bridge in the page never runs inside embeds (grid panels or the mobile WebView) and only ever talks to 127.0.0.1.