vike
Tools

list_series

Enumerate every stored data series the remote vike-datahub server holds, each with its cheap coverage, so an agent can pick a real date range before it writes a profile.

list_series answers the question every backtest starts with: what data is actually there? It returns one row per stored series with the span and row count that series covers, which is what a profile's [data] table can name.

Read-only and remote. tools_spec advertises it with readOnlyHint: true, idempotentHint: true and openWorldHint: true — it changes nothing, the same call twice gives the same answer, and it reaches off this machine to do it.

Arguments

None. Its inputSchema declares an object with no properties, so the call is the empty object.

{ "name": "list_series", "arguments": {} }

What comes back

Server::call_tool routes to tool_list_series, which connects to the datahub, calls DatahubClient::inventory, and projects each row into JSON:

{
  "series": [
    {
      "kind": "bar", "venue": "binance", "symbol": "BTCUSDT", "interval": "1m",
      "first_ts": 1704067200000, "last_ts": 1735689600000, "rows": 525600
    }
  ]
}

Seven fields, four from vike_data::series::SeriesId and three from SeriesCoverage. The SeriesId tuple is exactly what the store's leaf directory encodes — kind=…/venue=…/symbol=…[/interval=…] — so interval is present for bars, which sub-partition by bar step, and null for tick series. The layouts each kind implies have their own pages under the data-kind reference, and the store itself is described in The history store.

Coverage is cheap on purpose. SeriesCoverage's own doc states it is computed from the manifest file-index with no DataFusion scan, which is why an inventory over a large store is a metadata read rather than a query.

Four fields the projection drops

SeriesCoverage also carries bytes, parts and dates, and SeriesId carries group. tool_list_series projects none of them.

A grouped series reports an empty symbol

SeriesId::group is Some(g) for a grouped series — one part file holding many symbols, told apart by a row-level symbol column instead of one series per symbol. Its doc is explicit that symbol is empty in that case, deliberately, so a consumer scanning by id.symbol fails visibly rather than silently scanning "". The tool does not project group, so such a row arrives here as a blank symbol with no replacement label. SeriesId::label — group if grouped, else symbol — is the accessor that resolves it, and it is not on this wire. Treat a blank symbol as "grouped, ask the store", never as "no symbol".

It needs a reachable datahub

The address comes from vike-cli mcp --addr <host:port>, defaulting to DEFAULT_ADDR, 127.0.0.1:7878. If nothing is listening there the tool returns a clean error result whose text begins cannot connect to datahub at — never a panic and never a dead stdio session. remote_run_tools_without_a_reachable_datahub_are_clean_errors pins that for this tool alongside run_sweep and run_walk_forward, by pointing the server at a port that refuses immediately.

The vike-datahub server is the process that holds the store; see its binary page for how it is run and Connect an agent for wiring the MCP server up in the first place.

Where it sits in a session

list_series is the first of the three remote read tools an authoring loop uses: this one says what data exists, list_strategies says which compiled strategy names a profile can resolve, and list_indicators says what a Rhai script may actually call. Only then does the profile you hand run_backtest name a series that is really in the store over a range that is really covered.

What series does the datahub have for binance, and how far back does the 1m BTCUSDT bar data go?

On this page