pipsocketDOCS
Guides / MCP

MCP tools

Every tool of the MCP server, the scope it needs, what it takes and what it calls.

Trading tools go to the account's terminal as REST calls; account and hook tools do what the dashboard does; build_alert_message runs on its own. Your app sees every tool your best role across the connection's workspaces allows: someone who is only ever a member sees the read tools.

Answers

Every tool answers the same shape, as structured content and as the same JSON in text:

{ "status": 202, "retry_after": null, "body": { "request": "req_5f0c2a9e41d7b3a8c6e2f190", "state": "pending", "...": "..." } }
  • status: the HTTP status the REST API (or, for account and hook tools, the dashboard) answers.
  • retry_after: the REST answer's Retry-After header in seconds, or null when it has none. Account and hook tools always have null.
  • body: the REST (or dashboard) body, as it is.

A 4xx or 5xx status is a tool error (isError). A 2xx never means filled: read the body's state, as over REST.

Ids and workspaces

Accounts (acc_...) and hooks (hk_...) are named by their own id: ids are unique across workspaces, so a call acts in the workspace the account or hook belongs to and takes no workspace. Only create_hook and connect_account_link name a workspace (ws_...). list_accounts and list_hooks cover every workspace where the connection can read, each item naming its workspace, or just the workspace you pass.

Each tool is marked for your app: read-only tools change nothing, destructive ones can close, cancel, stop or send live trades, and the rest (changes) change setup without trading. Your app may ask you before the destructive ones.

Read

Needs read in the workspace of the account or hook, unless it says otherwise.

ToolScopeMarkedTakesDoes
list_workspacesnoneread-onlynothingThe connection's workspaces: id, name, your role and the scopes it has there now.
list_accountsreadread-onlyworkspace?MT5 accounts: id, workspace, login, server, status and host location.
get_account_statusreadread-onlyaccountThe account's record, and what its engine reports now (live: null when the host can't be reached).
get_accountreadread-onlyaccountGET /v1/accounts/{account}: balance, equity, margin.
list_positionsreadread-onlyaccountGET .../positions
list_pending_ordersreadread-onlyaccountGET .../orders
list_history_dealsreadread-onlyaccount, from, toGET .../history/deals
list_history_ordersreadread-onlyaccount, from, toGET .../history/orders
list_symbolsreadread-onlyaccountGET .../symbols
get_symbolreadread-onlyaccount, symbolGET .../symbols/{symbol}
get_tickreadread-onlyaccount, symbolGET .../symbols/{symbol}/tick
get_requestreadread-onlyaccount, requestGET .../requests/{request}: a trade request and how it ended.
get_kill_switchreadread-onlyaccountGET .../kill-switch
list_hooksreadread-onlyworkspace?TradingView hooks, with status, applied, revision and targets. The URL is masked.
get_hookreadread-onlyhookOne hook, URL masked.
list_hook_alertsreadread-onlyhook, state?, reason?, account?, symbol?, before?, limit?The hook's alert log, newest first, up to 100 a page. Pass the answer's next as before for the next page.
get_hook_alertreadread-onlyhook, alertOne alert, its outcome on each target account and each engine's trace.
list_symbol_mapsreadread-onlyaccountThe account's TradingView symbol mappings.
list_broker_symbolsreadread-onlyaccount, names?The broker's symbols on the account; with names (comma-separated), their specifications and default pip sizes.
list_ownedreadread-onlyaccountWhat the account's hooks own on it: positions, orders, lanes and managed stops.
connect_account_linkreadread-onlyworkspace, server?, login?A dashboard link that opens the connect dialog for the workspace, filled in. You connect the account there.
build_alert_messagenoneread-onlythe builder's choices, all optional (below)The JSON message for a TradingView alert, as the dashboard's builder writes it, with problems and warnings.

? marks an optional argument. from and to are broker server time in seconds, as over REST.

Trade

Needs trade in the account's (or, for resend_alert, the hook's) workspace. A trade tool takes the REST call's path values and body fields as arguments, named as on its REST page, plus account.

ToolScopeMarkedTakesDoes
check_ordertraderead-onlyaccount and the order's fieldsPOST .../orders/check: MT5's dry run. Sends nothing to the trade server.
place_ordertradedestructiveaccount, idempotency_key and the order's fieldsPOST .../orders
modify_ordertradedestructiveaccount, order, idempotency_key and the new valuesPATCH .../orders/{order}
cancel_ordertradedestructiveaccount, order, idempotency_keyDELETE .../orders/{order}
set_position_levelstradedestructiveaccount, position, idempotency_key, sl, tpPATCH .../positions/{position}
close_positiontradedestructiveaccount, position, idempotency_key and the close's fieldsPOST .../positions/{position}/close
close_bytradedestructiveaccount, position, idempotency_key, position_byPOST .../positions/{position}/close-by
engage_kill_switchtradedestructiveaccount, deviation?POST .../kill-switch
lift_kill_switchtradedestructiveaccountDELETE .../kill-switch
resend_alerttradedestructivehook, alert, accounts, idempotency_keySends an earlier alert again, as a new one, to these target accounts (1 to 20): live trades. Only targets whose delivery is settled and wasn't partly done.

For the account tools, idempotency_key is your own key for the request, sent as the Idempotency-Key header and scoped to the account, exactly as over REST. For resend_alert it's a key of the hook's: the same key with the same alert and accounts answers the one resend it made, for 7 days, and the same key with a different alert or accounts is refused 409 (key_reused). It's required wherever it's listed. How to retry is on retries and errors.

Manage

Needs manage in the account's or hook's workspace (create_hook: the workspace it names).

ToolScopeMarkedTakesDoes
start_accountmanagechangesaccountStarts the account's terminal.
stop_accountmanagedestructiveaccountStops the terminal: Pipsocket sends nothing to the account until it's started. Positions, pending orders and their stops stay at the broker as they are; to close them, use the kill switch first.
restart_accountmanagechangesaccountRestarts the terminal.
create_hookmanagechangesworkspace, name, maxAgeS?, tvIpsOnly?, quota?, notify?, targets?Makes a hook in the workspace. Every target must be an account of that workspace. Answers the hook and its url (below).
update_hookmanagechangeshook, name?, maxAgeS?, tvIpsOnly?, quota?, notify?The hook's own settings.
pause_hookmanagechangeshookAlerts are recorded, not acted on. status is pausing until the hook and every engine have it, then paused.
resume_hookmanagechangeshookNew alerts trade again.
delete_hookmanagedestructivehookDeletes the hook. done: false means removal goes on in the background. Owned positions and managed stops stay until they close (list_owned).
rotate_hook_urlmanagedestructivehookA new secret: the old URL stops once the hook has it. Answers the new url (below).
get_new_hook_urlmanageread-onlyhookThe URL this connection just made (below).
add_hook_targetmanagechangeshook, account, shortName?, enabled?, settings?Adds a target account of the hook's workspace, with its settings.
update_hook_targetmanagechangeshook, account, shortName?, enabled?, settings?Changes a target.
remove_hook_targetmanagedestructivehook, accountRemoves a target.
test_hookmanageread-onlyhook, messageA dry run of a message on the hook's targets: checked and sized by each engine, never traded. The message is sent as written: give real values, not {{placeholders}}.
set_symbol_mapmanagechangesaccount, from, to, pipSize?Maps a TradingView symbol or ticker (BITSTAMP:BTCUSD) to a broker symbol on the account.
delete_symbol_mapmanagechangesaccount, fromRemoves a mapping.
release_ownedmanagedestructiveaccount, hook, tag?, symbolReleases a hook lane's ownership on the account: its positions are no longer the hook's.

Hook settings and targets take the dashboard's own fields; anything a tool doesn't know is refused, not ignored. Each account and hook tool answers the dashboard's status and body for the same action.

Pausing or deleting a hook doesn't close what it already opened: its positions and managed stops stay until they close.

start_account, stop_account and restart_account are asked once. After a 503 the outcome is unknown, and the account stays busy until its lease runs out: read get_account_status rather than asking again. 409 means another change to the account is still going: wait, then read it.

Building an alert message

build_alert_message takes the dashboard builder's choices, not the message's own fields (those are on alert messages). Every argument is optional: left out, it builds a buy at market with each account's own size, on the chart's symbol. Values may be numbers or TradingView placeholders such as "{{close}}".

ArgumentTakes
modeindicator or strategy
actionopen, close, reverse, modify, cancel, close_all or kill_switch
sidebuy, sell or all
symbol, tagText. symbol is the chart's by default.
size{ "kind": "default" }, or { "kind": "lots" | "risk_percent" | "risk_amount", "value": ... }
sl, tp{ "unit": "pips" | "points" | "price" | "percent", "value": ... }, or null
ladderTake-profit rungs: [{ "unit": ..., "value": ..., "part": ... }], or null
entryA pending entry: { "type": "limit" | "stop" | "stop_limit", "at": { "unit": "price" | "offset_pips" | "offset_points", "value": ... }, "limit"?: ..., "expires"?: ... }, or null
trailingIn pips: { "kind": "set", "value": { "distance": ..., "step"?: ..., "start"?: ... } }, { "kind": "clear" } or { "kind": "off" }
breakEvenIn pips: { "kind": "set", "value": { "trigger": ..., "offset"?: ... } }, { "kind": "clear" } or { "kind": "off" }
portionFor a close: { "kind": "all" }, or { "kind": "percent" | "lots", "value": ... }
accountsThe hook's targets the alert is for (account ids or target short names); every target when left out
maxAge, slippageThe alert's age limit for entries, in seconds, and the slippage for market orders, in points
srcThe template's short id in its event ids (up to 8 lowercase letters and digits); a new one when left out

A buy risking 1% with a 25 pip stop:

{ "action": "open", "side": "buy", "size": { "kind": "risk_percent", "value": 1 }, "sl": { "unit": "pips", "value": 25 } }

It answers { "message": "...", "problems": [...], "warnings": [...] } in body: paste message into the alert as it is, placeholders and all. A message with problems would be refused on every alert.

To dry-run it with test_hook, send a copy with each {{placeholder}} replaced by what TradingView would send: the symbol, and the current UTC time for {{timenow}} (written like 2026-11-08T14:00:00Z). The time must be now: an entry older than its age limit (30 seconds unless the hook or message sets another) is refused stale, as a real alert would be. The test is sent as written: a placeholder left in a time or a number is refused before anything is checked, and one left in text goes through as those characters, so replace them all.

Hook URLs

A hook's URL carries its secret: whoever holds it can send trades. Over MCP it's shown only to the connection that made it, and only briefly:

  • create_hook and rotate_hook_url answer the URL once the hook has the new secret, usually at once. Until then url is null: call get_new_hook_url a few seconds later.
  • get_new_hook_url answers the URL only if this connection made the hook's current secret in the last 15 minutes. Otherwise it answers 409 with a reason:
    • not_applied_yet: the hook doesn't have the secret yet. Ask again in a few seconds.
    • superseded: another rotation replaced it. Tell the person; don't rotate again.
    • expired: more than 15 minutes, or this connection didn't make it. Reveal it in the dashboard (it asks for your password).
  • A lost answer to create_hook or rotate_hook_url is recovered with list_hooks and get_new_hook_url, never by creating or rotating again.

The URL is never in a list, a hook's details or the audit log. It does go into your chat with the app, so treat that chat as you would the URL.

Set up TradingView from a chat

Ask for the whole thing at once: "Set up a hook that trades my EMA strategy on BTCUSD on my FBS account, 1% risk, 25 pip stop." With manage and trade ticked, an app can:

  1. list_accounts to find the account and its workspace.
  2. list_broker_symbols for the broker's name for BTCUSD, and set_symbol_map to map TradingView's symbol to it.
  3. create_hook in that workspace, with the account as its target; get_new_hook_url if url was null.
  4. build_alert_message for the message, and test_hook to dry-run a copy of it, with real values in place of the placeholders, on the account.

Then you paste the URL and the message into the TradingView alert. See TradingView alerts.