DEV Community

Ilia Alshanetsky
Ilia Alshanetsky

Posted on • Originally published at ilia.ws

Driving TradingView Desktop From an AI Agent

Anyone who's tried AI-assisted trading research has hit the same wall.

The agent has no native access to your charts. You end up copy-pasting symbols, indicator values, screenshots, and Pine Script back and forth between TradingView and Claude or Cursor. The tools that try to fix this fall into two camps: route market data through a third-party API (added latency, added cost, their interpretation of your bars), or pollute your TradingView chart with helper indicators just so an agent can read them back.

There's a third path that's more obvious in retrospect: drive your local TradingView Desktop through the Chrome DevTools Protocol that the app already exposes on port 9222 when you launch it with --remote-debugging-port=9222. The agent talks to the same TradingView you already use, reads what your chart actually shows, executes Pine Script through TradingView's own runtime. Same data, same indicators, same features, just with an agent in the loop.

A project called tradesdontlie/tradingview-mcp started down this path. Then it stalled with TV Desktop 3.1.0 incompatibilities and a handful of bugs, and the maintainer went quiet on PRs. I forked it, and now 71 commits later just tagged 1.0.0 of the fork. This post covers what I added and what the tool doesn't do.

What's in 1.0.0

The release is at https://github.com/iliaal/tradingview-mcp/releases/tag/1.0.0 with the per-tool changelog. The high-level numbers:

  • 78 → 96 tools (18 new MCP tools)
  • A tv CLI (30 commands, 66 subcommands) mirroring the MCP surface
  • TV Desktop 3.1.0 compatibility across the whole surface
  • 338 offline tests (pattern detection, multi-timeframe, replay, CLI routing)
  • Removed ui_evaluate from the upstream surface (it accepted arbitrary JavaScript in the user's authenticated TV session)

Pine Script Lifecycle

The original project let an agent inspect Pine Script, but only barely. Editing, saving, switching, and version history all required the user to click through TradingView's UI. The 1.0.0 fork closes that gap with eight new tools:

  • pine_save_as and pine_rename for naming and copying scripts
  • pine_version_history, pine_delete, pine_switch_script for managing the Pine library
  • pine_smart_compile (auto-detects whether to add or update an indicator on the chart; returns elapsed_ms)
  • pine_analyze (offline static analysis; catches typos, unused vars, deprecated patterns before compile)
  • pine_check (server-side compile without putting the script on a chart; useful for CI-style validation)

The pine_check + pine_analyze pair is the unlock for AI-assisted Pine debugging. The agent writes a draft, runs pine_analyze for cheap structural checks, then pine_check for the real compile, reads errors, fixes, repeats. The user never has to add an unfinished script to the chart just to see whether it compiles.

Pine Drawing Readers

This is the part I keep using most. Five new tools let the agent read what a Pine indicator actually drew, after it's running on the chart:

  • data_get_pine_lines: horizontal price levels (support, resistance, trend lines)
  • data_get_pine_labels: text annotations (signal labels, divergence callouts)
  • data_get_pine_tables: table cells (stats panels, multi-symbol scanners)
  • data_get_pine_boxes: price zones (supply, demand, order blocks)
  • data_get_pine_shapes: plotshape and plotchar markers

Default behavior deduplicates and caps output (50 labels by default). Override with verbose=true or max_labels=N for cases where the agent needs the raw set.

Why this matters: agents writing Pine Script could previously check whether the script compiled, but couldn't verify whether the logic was correct. Now the agent can write an indicator, compile it, and read the labels back to confirm the right bars were tagged. Without this, AI-assisted Pine work stops at "syntax is fine, hope you wrote what you meant."

This also replaces the workflow that an agent would otherwise fall back to: screenshot the chart, run OCR over the image, hope the agent pieces together what the indicator drew. That path is slow (a screenshot round-trip plus OCR latency on every read), unreliable (overlapping labels and thin lines confuse the OCR), and expensive (chart images in the agent's context burn thousands of tokens before any reasoning happens). The structured readers skip all three problems.

Multi-Pane and Tab Navigation

Pine indicators rarely live alone. A real chart layout might have three panes (price + RSI + volume) and four tabs, one per ticker. The original project assumed a single chart context. The fork adds eleven tools that make the layout addressable:

  • pane_list, pane_focus, pane_set_layout, pane_set_symbol, pane_set_timeframe
  • pane_read_batch (single call that reads across all visible panes)
  • tab_list, tab_new, tab_close, tab_switch, tab_switch_by_name

pane_read_batch was the practical motivator: agents that need to compare indicator values across panes used to need 5+ round-trips. The batch reader collapses that to one CDP call, which matters when the agent is iterating quickly.

A non-obvious detail: pane focus needs a 300ms wait after pane.focus() for _activeChartWidgetWV to update, required since TV 3.1.0. The fork bakes this in so users don't have to discover it.

Multi-Timeframe and Pattern Detection

data_get_multi_timeframe reads indicator values across a list of timeframes (W → D → 4H → 1H → 15m alignment) in one call. It saves and restores the original timeframe, so the agent gets multi-timeframe context without disrupting the user's view.

data_detect_candlestick_patterns runs 17 classic patterns over raw OHLC bars: doji, hammer, hanging_man, inverted_hammer, shooting_star, marubozu, spinning_top, bullish_engulfing, bearish_engulfing, bullish_harami, bearish_harami, piercing_line, dark_cloud_cover, morning_star, evening_star, three_white_soldiers, three_black_crows. Each match returns the pattern name, a direction (bullish/bearish/neutral), and a strength score.

The point of doing pattern detection natively, instead of via a Pine indicator overlay, is chart hygiene. Pattern detection informs the agent; the user never wants to see it plotted on the chart. Running it over OHLC bars directly means no Pine indicator gets added to the chart, no scripts get pushed to TV's Save dialog, and the user's chart stays clean.

The tv CLI

The MCP surface is meant for AI agents. But the same operations are useful from a shell, and shipping both interfaces from the same code path (instead of building a separate CLI program) keeps them in sync.

tv ships 30 commands with 66 subcommands. A few examples:

tv quote get AAPL                          # current quote
tv data ohlcv AAPL --tf 1H --bars 200      # OHLCV bars
tv pine check ./my_indicator.pine          # offline compile
tv pine smart_compile ./my_indicator.pine  # add or update on chart
tv hotlist volume_gainers --country US     # scanner
tv stream all                              # poll-and-diff JSONL output
Enter fullscreen mode Exit fullscreen mode

tv stream polls the chart and emits JSONL whenever something changes: a new bar, an indicator value update, a new label drawn. Useful for piping into tail-and-watch workflows or for sanity-checking a strategy as it runs.

Cross-Platform Launch

tv_launch auto-detects native macOS, Linux, Windows, and Windows MSIX (Microsoft Store) installs of TradingView Desktop, resolves Windows paths correctly when invoked from WSL2, and handles the case where a binary refuses --remote-debugging-port from a direct spawn. macOS Electron 38 is the worst offender there; the fix is to fall back to open -a with the port flag in --args.

The motivation for sinking this much code into launch behavior is operational: in a CI-like setup or a containerized agent loop, you want tv_ensure to be a no-op when TV is already running and a clean launch when it isn't, on whichever OS the agent happens to be on. The original project assumed the user had TradingView running and never had to think about how it got there.

A Quiet Architectural Change

One refactor: per-call _deps dependency injection across ten core modules (chart, data, drawing, pane, pine, replay, ui, watchlist, alerts, capture).

Before: each module imported connection.js directly. State lived in module globals. Tests had to monkey-patch connection.js to swap CDP behavior.

After: each function accepts a _deps parameter, so the test harness passes in a mock CDP wrapper without touching globals. The installCdpMocks and mockEvaluateFromTable helpers in tests/helpers/mock-cdp.js give every test an isolated environment.

Practical result: 338 offline tests run in seconds without needing TradingView Desktop open. The previous test surface was much smaller because anything beyond a unit test required the real app running. The DI refactor unlocked the test count, which is what makes the 3.1.0 compat fixes safe to ship.

What Was Removed: ui_evaluate

The upstream had a tool called ui_evaluate that accepted arbitrary JavaScript and ran it in the authenticated TradingView session. Anyone with MCP access to the agent had effective full read/write access to the user's TradingView account state: watchlists, alerts, saved scripts, anything the session could see.

Dropped it. There's no use case for arbitrary JavaScript that isn't better served by a specific tool with a narrow boundary. If you need to read or modify something the existing tools don't cover, that's a missing tool, not a reason to expose the JS runtime.

What It Doesn't Do

The agent talks to your running TradingView Desktop via CDP. There's no API spoofing, no auth bypass, no headless TV. If you don't have TV Desktop installed, the tool can't help you.

TradingView's free tier covers most of the lifecycle tools. Some features need paid tiers (multi-pane, replay mode, second-resolution data, more indicators per chart). The tools wrap whatever the local TV exposes; they don't unlock features you don't have.

It doesn't bypass anything. It doesn't get you data TradingView doesn't already give you. The improvement is the agent surface, not the data access.

Install

git clone https://github.com/iliaal/tradingview-mcp
cd tradingview-mcp
npm install
Enter fullscreen mode Exit fullscreen mode

Add the server to ~/.claude/.mcp.json (or your MCP config). Launch TradingView with --remote-debugging-port=9222. The README has the paste-into-Claude-Code one-liner that covers the agent-side wiring.

Top comments (0)