-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Contributing
This project grows by surface area. Every TradingView capability someone wires up becomes a new verb an AI agent can use — a new thing it can see or do on a live chart. If you've ever wished the agent could reach one more corner of TradingView, that wish is a contribution waiting to happen.
This page is the friendly, expanded version of the repo's CONTRIBUTING.md — start here to understand what to build and how, then that file is the canonical rulebook.
You don't have to write code to help. In rough order of "easiest to land":
- File a good bug report. A tool that silently misbehaves on your setup is genuinely useful signal. See Filing a bug report.
- Improve reliability. TradingView ships UI changes constantly; selectors rot, timeouts get flaky. Hardening an existing tool (better selectors, error handling, retry/wait logic) is high-value and low-risk.
-
Improve the docs. This wiki, the
CLAUDE.mddecision trees, the README. If something confused you, fix it while it's fresh. -
Mirror a tool into the CLI. Anything the MCP layer can do, the
tvcommand should be able to do too. - Wire up a new TradingView endpoint → a brand-new tool. The frontier. See Wiring up a new endpoint.
- Add a new use of existing tools — a workflow, a batch action, a decision-tree entry that composes tools into something greater than the sum of its parts.
This is a local bridge: Claude ↔ your own running TradingView Desktop, over CDP. That boundary is the whole ethical and legal footing of the project, so contributions have to respect it.
In scope ✅
- Reliability, error handling, and better selectors for existing tools
- New tools that read/drive the locally running Desktop app via CDP
- CLI commands mirroring MCP capabilities
- Pine Script workflow improvements
- Tests and documentation
Out of scope ❌ — a PR that does any of these will be declined:
- Talking to TradingView's servers directly. All access goes through the local Desktop app.
- Bypassing auth or subscription gates. The tool assumes a valid, logged-in account.
- Scraping, caching, or redistributing market data. No databases, no CSV dumps of prices.
- Automated trading / live order execution. This is a chart-reading and development tool. (Replay trading is simulated and fine.)
- Reverse-engineering or bundling TradingView's proprietary code.
- Reaching other users' private data — scripts, watchlists, accounts.
Keep personal trading configs, strategies, and bots built on top of the bridge in your own fork. Unsure? Open an issue to discuss before writing code.
A report that lets a maintainer reproduce the problem gets fixed. A one-liner gets closed. Include:
- OS and TradingView Desktop version — plus install type (installer vs Microsoft Store / MSIX — this matters a lot on Windows).
-
The exact tool call and its full JSON result (
{ success: false, error: ... }and all). -
tv_health_checkoutput — proves the bridge is connected and shows the chart state. - What you expected vs what happened.
Search first. Popular bugs here have attracted 20+ duplicate fixes. If an open issue or PR already covers it, add your setup details there instead of opening a new one.
npm install
npm run lint # eslint — the no-undef guard catches unfinished refactors
npm run test:unit # offline unit tests (no TradingView needed)
npm run test:e2e # requires TradingView running with CDP on :9222
tv status # verify CDP connection (TradingView must be running)Core functions take an optional _deps parameter resolved via _resolve(_deps), so the logic is unit-testable without a live chart. Study src/core/replay.js or src/core/health.js for the pattern before writing your own.
TradingView's internal API surface is enormous, and this bridge only exposes a slice of it. Every session, tv_discover reports paths whose methods are reachable but not yet wrapped in a tool. Turning one of those into a tool is the most impactful thing you can contribute. Here's the loop.
Call the discovery tool:
tv_discover
It enumerates the known API roots and lists their methods — e.g. the chart widget exposes ~50 methods at window.TradingViewApi._activeChartWidgetWV.value(). The known roots today:
| Root | Path |
|---|---|
| Active chart widget | window.TradingViewApi._activeChartWidgetWV.value() |
| Chart widget collection | window.TradingViewApi._chartWidgetCollection |
| WebSocket layer | window.ChartApiInstance |
| Bottom toolbar | window.TradingView.bottomWidgetBar |
| Bar replay | window.TradingViewApi._replayApi |
| Alerts | window.TradingViewApi._alertService |
Scan the method list for something no existing tool covers — a getter you wish an agent could read, or an action you wish it could trigger.
Before writing any files, poke the method directly in the page context and see what it returns:
ui_evaluate code: "return window.TradingViewApi._activeChartWidgetWV.value().someMethod();"
Iterate here until you understand the shape of the data and any quirks (promises that need unwrapping, values wrapped in .value(), arguments, edge cases). This is your REPL — it costs nothing and teaches you the API.
Put the logic in src/core/<area>.js. Keep the evaluated JS defensive — wrap internal access in try/catch and return a clean, compact object:
// src/core/myfeature.js
import { evaluate } from '../connection.js';
export async function getMyThing({ _deps } = {}) {
const data = await evaluate(`
(function() {
try {
var chart = window.TradingViewApi._activeChartWidgetWV.value();
var thing = chart.someMethod();
return { ok: true, value: thing };
} catch (e) {
return { ok: false, error: e.message };
}
})()
`);
if (!data.ok) throw new Error(data.error || 'someMethod() unavailable');
return { success: true, value: data.value };
}Add the tool in src/tools/<area>.js — thin handler, validation via zod, always return through jsonResult:
// src/tools/myfeature.js
import { z } from 'zod';
import { jsonResult } from './_format.js';
import * as core from '../core/myfeature.js';
export function registerMyFeatureTools(server) {
server.tool(
'myfeature_get_thing',
'One clear sentence describing what this reads/does and when to use it',
{ detail: z.coerce.boolean().optional().describe('Return the verbose form (default false)') },
async ({ detail }) => {
try { return jsonResult(await core.getMyThing({ detail })); }
catch (err) { return jsonResult({ success: false, error: err.message }, true); }
}
);
}Then wire the registrar into src/server.js:
import { registerMyFeatureTools } from './tools/myfeature.js';
// ...
registerMyFeatureTools(server);-
Test it — add a unit test using the
_depsseam; verify live against a real chart and note what you ran. -
Mind the context budget — default to compact output; gate anything large behind an opt-in flag (
summary,study_filter,verbose). See Context Management. -
Update the count and docs — the tool count appears in
src/server.js(instructions header), the twoCLAUDE.mdfiles,README.md, andRESEARCH.md. Add your tool to the Tool Reference and, if it enables a new pattern, to Agent Workflows. -
Name it well — the agent picks tools by name and description.
area_verb_noun, present tense, specific. A vague name is a tool the agent never calls.
⚠️ These are undocumented internal APIs and can change without notice — a TradingView update can break any tool at any time. Fail gracefully ({ success: false, error }), never throw raw, and prefer feature-detection over assumptions.
- Single, clear purpose — one verb, one job. Compose in workflows, not in mega-tools.
- Compact by default — the agent pays for every byte. Offer detail as opt-in.
- Self-describing — the name + description alone should tell an agent when to reach for it.
-
{ success: true/false, ... }— always, even on failure. Include an actionableerror/hint. - Defensive against UI drift — try/catch around DOM and internal-API access.
- Testable — logic in
src/core, thin handler insrc/tools,_depsseam for units.
- One focused change per PR. Bundled PRs (feature + config + docs rewrite) tend to get closed in favor of the smallest equivalent.
- Search open PRs before writing code — comment on an existing one rather than duplicating it.
- Add tests for new functionality where possible.
npm run lintandnpm run test:unitmust pass.- Verify against a live TradingView Desktop and describe exactly what you ran and observed in the PR body. Real verification notes merge much faster.
Thanks for helping give agents more reach on a live chart. Open an issue to float an idea, or dive into Architecture Internals to see how the bridge is put together.
TradingView MCP Bridge · 84 tools · CDP bridge to TradingView Desktop · Community project, not affiliated with TradingView
Guides
Reference
Contribute
Repo