Docs / Developer tools

MCP workflows

Example end-to-end prompts for building, optimizing, and sharing strategies through an MCP client, plus the indicator line-naming format.

Common AI-driven workflows you can execute through any MCP client. Use these as starting prompts once your client is connected — you describe the goal in plain language, and your assistant chains the tool calls to reach it.

A plain-language request becomes a chain of tool calls — create, add indicator, add rules, backtest — that build the strategy and return its result Your prompt plain language create_strategy add_indicator add_signal_rule run_backtest executes Result
One request, many tool calls. Your assistant decides the sequence; each tool maps to a platform action, and the result comes back for it to read and report.

Workflow 1: Build a strategy from scratch#

Prompt: "Create a BTC/USDT strategy on the 1h timeframe.
Add RSI with length 14 and EMA with length 200.
Enter long when RSI crosses above 30 and price is above the 200 EMA.
Exit when RSI crosses below 70.
Set a 2% trailing stop-loss and take profit at 5% and 10%.
Run a backtest."
Prompt: "Create a grid search template from my strategy [ID].
Set RSI length range 10-20 step 2.
Set EMA length range 50-200 step 50.
Show me the variation count, then run the grid."

Workflow 3: Research a strategy end-to-end#

The grid tools form a research loop the assistant is expected to close on its own. The steps below describe the whole loop; each step maps to one MCP call listed in tools.

Prompt: "Research strategy [ID] end-to-end.
Start with a Zoom-In grid, check variation count, launch it, wait for
the verdict. If the verdict is robust_plateau, label the top variation
'promising'. If the plateau sits at the edge, refine with explore_higher
or explore_lower and repeat."

The recommended tool sequence:

  1. create_grid_template(strategy_id, kind="zoom_in") — safest starting shape; auto-clamped to the plan cap so submission is a single call.
  2. check_variations(template_id) — sanity-check {count, limit} before spending tokens.
  3. create_grid(template_id) — launches every variation.
  4. Poll get_grid(grid_id) until completed flips to true (the backtest workers run asynchronously).
  5. get_grid(grid_id) — read the robustness verdict and top clusters from cluster_analysis.
  6. If the verdict is robust_plateau or weak_plateau:
    • refine_grid(grid_id, kind="zoom_in") — a finer-step search inside the plateau. Returns {template_id}; go back to step 2.
  7. If the top plateau sits at the edge of the tested range:
    • refine_grid(grid_id, kind="explore_higher") or refine_grid(grid_id, kind="explore_lower") to search a fresh window on the frontier.
  8. set_grid_labels(grid_id, [...]) — tag the winner so you can find it later. Common conventions: promising, archive-me, per-symbol tags like btc-1h. Call list_grid_labels() first to reuse the caller's existing vocabulary before inventing new labels.
  9. list_grids(label=["promising"], min_sharpe=1.5, sort_by="robustness") — later, narrow to a shortlist without pulling the whole account. Every filter argument maps to an indexed column, so filtering server-side is the cheap path.
NOTE

refine_grid returns a template_id, not a grid. Follow with create_grid to actually launch the refined search. This split lets you review the mutated ranges (via get_grid_template) before spending tokens.

Workflow 4: Version & share the best result#

Prompt: "Review the grid search results for my strategy [ID].
Share the top strategy if sharpe is > 2.0 and max drawdown
is greater than -20%. Commit with the message
'Optimized RSI and EMA parameters from grid search'."

Getting indicator line names right#

A signal condition references an indicator's output line as {IndicatorName}.{line} — where IndicatorName is the name the indicator was given, not a fixed pattern. A short-named RSI produces RSI.rsi; a descriptively named one might produce RSI_btcusdt_30m.rsi. So do not construct line names by hand — read them.

IMPORTANT

Have your assistant call get_strategy first to read the exact line names available, then reference those in add_signal_rule. If a line does not exist, the API rejects the rule and returns the list of available_lines — so a wrong guess is caught, but reading them up front avoids the round-trip.

The condition JSON shape those rules take — trigger_line, trigger, threshold_value / threshold_line, and the operators — is documented in the tools reference.

Was this page helpful?