Skip to content

Worked examples

Server: atelier-mcp · Form: natural-language ask → tool sequence → results

Each flow is a full engagement: what you ask the client, the tools it drives to satisfy the ask, and the results it reads back between steps. You speak in natural language; the client picks the tools and chains them, reading each result before the next and adapting as it goes. Results are illustrative — live values vary.

Health first, cleanup last

A robust flow opens with platform_health and, for a deploy, closes with stop_collector. The flows below assume a reachable platform.

Errors are results, not failures

A backend error comes back as {"ok": false, "error": "..."} — an ordinary tool result the client reads and adapts to in the same loop. Flow 2 shows this: a non-converged fit becomes a looser-tolerance refit.


Flow 1 — Deploy a collector and confirm data is landing

Ask — "Stand up a Binance BTC spot collector in a low-latency region and tell me once it's actually producing data."

This is a remote bring-your-own deploy: deploy_collector registers the service and mints an agent JWT, and you run your own agent container against the gateway with that JWT. The client drives:

platform_healthlist_cex_optionsquery_colocationdeploy_collectorcollector_healthstop_collector

Step 1 — confirm the platform answers

{ "tool": "platform_health", "arguments": {} }
{ "overseer": "ok", "overdex_server": "ok", "overwatch": "ok", "pulsar_clickhouse": "ok" }

Step 2 — resolve the venue and its native symbol format

The client consults the deployable options before it commits to a symbol string, since each venue names symbols differently.

{ "tool": "list_cex_options", "arguments": {} }
{
  "venues": [
    {
      "exchange": "binance",
      "label": "Binance",
      "symbol_format": "concatenated uppercase",
      "symbol_example": "BTCUSDT",
      "market_types": ["spot"],
      "orderbook_depths": [5, 10, 20, 50, 100, 500, 1000],
      "default_orderbook_depth": 50,
      "datatypes": [
        { "name": "orderbook", "available": true },
        { "name": "trades", "available": true }
      ]
    }
  ]
}

Binance names BTC spot as BTCUSDT, supports spot, and offers depth 50.

Step 3 — pick the region

{ "tool": "query_colocation", "arguments": { "exchange": "binance" } }
{
  "count": 1,
  "exchanges": [
    { "exchange": "binance", "region": "ap-northeast-1", "score": 0.96 }
  ]
}

Step 4 — register the remote collector

{
  "tool": "deploy_collector",
  "arguments": {
    "exchange": "binance",
    "symbols": ["BTCUSDT"],
    "market_type": "spot",
    "region": "ap-northeast-1"
  }
}
{
  "service_id": "63060972",
  "binding_id": "cfb7688a",
  "gateway_url": "http://gateway:50443",
  "token": "your-agent-jwt"
}

The deploy returns the service_id, the binding_id, the gateway URL, and an agent JWT. Nothing is running yet: this is a bring-your-own collector, so you launch the agent container yourself, pointing it at the returned gateway URL and passing the JWT.

Step 5 — run your own agent container against the gateway

A minimal container sketch — set the gateway URL and the JWT from the deploy result, and give it the same binding id:

docker run --rm \
  -e ATELIER_GATEWAY_URL=http://gateway:50443 \
  -e ATELIER_AGENT_TOKEN=your-agent-jwt \
  -e ATELIER_BINDING_ID=cfb7688a \
  your-agent-image

The JWT is a credential scoped to this binding. Treat it like a password: keep it out of shared configs and version control.

Step 6 — confirm data is landing

A fresh deploy has no lake rows for the first few minutes, so collector_health leads with liveness and reads starting rather than reporting a failure.

Just after the container starts:

{ "tool": "collector_health", "arguments": { "service_id": "63060972" } }
{
  "service_id": "63060972",
  "verdict": "starting",
  "liveness": { "connected": true, "heartbeat_age_s": 4, "ws_latency_ms": 22.1 },
  "landing": { "rows_last_5m": 0, "total_rows": 0,
               "expected_first_data_by": "2026-07-04T18:05:00Z" }
}

A few minutes later, once rows land:

{ "tool": "collector_health", "arguments": { "service_id": "63060972" } }
{
  "service_id": "63060972",
  "verdict": "healthy",
  "liveness": { "connected": true, "heartbeat_age_s": 3, "ws_latency_ms": 21.4 },
  "landing": { "rows_last_5m": 8421, "total_rows": 33110, "last_row_age_s": 2 }
}

The verdict flips to healthy once fresh rows land, and the client tells you data is flowing.

Step 7 — tear it down

{ "tool": "stop_collector", "arguments": { "service_id": "63060972" } }
{ "service_id": "63060972", "stop": "requested" }

Stop the collector when you are done to release the binding. Between deploy and stop you can pause and resume the task with collector_command (task_pause, task_resume).


Flow 2 — Fit and forecast a model

Ask — "Fit a Hawkes model to Kraken ETH trades and forecast the next 10 events."

This flow adapts mid-loop: the first fit does not converge at the tight default tolerance, so the client reads the error and refits with a looser one. The client drives:

list_datasetsfit_pricingfit_hawkesget_fitforecast_fit

Step 1 — pick a dataset

Hawkes fits want an event stream, so the client picks a trades dataset.

{ "tool": "list_datasets", "arguments": {} }
{
  "datasets": [
    { "dataset_id": "ds_9f3a…", "exchange": "kraken", "symbol": "ETH-USD",
      "datatype": "trades" }
  ]
}

Step 2 — check the fit price

A fit is metered in compute tokens against your identity, so the client reports the price before it runs one.

{ "tool": "fit_pricing", "arguments": {} }
{ "fit": { "unit": "compute_token" } }

Step 3 — first fit (does not converge)

{ "tool": "fit_hawkes", "arguments": { "dataset_id": "ds_9f3a…" } }
{ "ok": false, "error": "the fit did not converge" }

The error is an ordinary result. The client reads it and loosens the tolerance — the default (1e3) is tight for real data.

Step 4 — refit with a looser tolerance

{
  "tool": "fit_hawkes",
  "arguments": { "dataset_id": "ds_9f3a…", "tolerance": 10000 }
}
{
  "fit_id": "fit_7c21…",
  "converged": true,
  "branching_ratio": 0.182,
  "n_train": 561,
  "tolerance_used": 10000
}

A branching ratio of 0.182 says the series is self-exciting — it rejects a plain Poisson model.

Step 5 — read the full fit

fit_hawkes omits the chart series to keep the result small. The client fetches the full artifact — params, diagnostics, and series — with get_fit.

{ "tool": "get_fit", "arguments": { "fit_id": "fit_7c21…" } }
{
  "fit_id": "fit_7c21…",
  "converged": true,
  "branching_ratio": 0.182,
  "series": { "intensity": [ ], "residuals": [ ] }
}

Step 6 — forecast from the fit

{
  "tool": "forecast_fit",
  "arguments": { "fit_id": "fit_7c21…", "n_forecast": 10 }
}
{
  "fit_id": "fit_7c21…",
  "n_forecast": 10,
  "median_cumulative_gap_ms": 48183,
  "band": { "p25": [ ], "p75": [ ] }
}

The client reports a 10-step forecast with a final cumulative gap near 48 seconds and a p25/p75 band around it. Forecasts are reproducible for a given seed; raise mc_paths for a tighter band.


Flow 3 — Audit an existing stream

Ask — "How complete is the Coinbase BTC/USDT order book?"

A short two-step read: the client resolves the stream in the governance catalog, then scores it. The client drives:

governance_catalogstream_scorecard

Step 1 — find the stream

{
  "tool": "governance_catalog",
  "arguments": { "exchange": "coinbase", "datatype": "orderbook" }
}
{
  "streams": [
    { "exchange": "coinbase", "market_type": "spot", "symbol": "BTC/USDT",
      "datatype": "orderbook", "presence": "present" }
  ]
}

Step 2 — score it

{
  "tool": "stream_scorecard",
  "arguments": {
    "exchange": "coinbase", "market_type": "spot",
    "symbol": "BTC/USDT", "datatype": "orderbook"
  }
}
{
  "exchange": "coinbase", "symbol": "BTC/USDT", "datatype": "orderbook",
  "completeness": { "grade": "critical", "ratio": 0.049 },
  "quality": { "max_severity": "none" }
}

Completeness is critical (4.9%) while quality is clean — the stream is sparse, not corrupt. Add window_secs to recompute completeness live over a trailing window.


Compose the whole engagement

Ask — "Stand up a Binance BTC collector in a low-latency region, confirm it's landing data, audit an established stream, fit a Hawkes model to a trades dataset, forecast from it, then tear the collector down."

A capable client chains the flows above into one engagement, reading each result before the next and adapting as it goes:

flowchart LR
  H[platform_health] --> L[list_cex_options]
  L --> Q[query_colocation]
  Q --> D[deploy_collector]
  D --> CH[collector_health]
  CH --> G[stream_scorecard]
  G --> F[fit_hawkes]
  F --> FC[forecast_fit]
  FC --> S[stop_collector]
One engagement: check health, resolve the venue and region, deploy a remote collector, watch it land data, audit a stream's governance, fit a Hawkes model, forecast from the fit, and stop the collector.

Each arrow is a tool call whose result the client reads before the next, adapting as it goes — a looser tolerance on a non-converged fit, starting versus healthy on a fresh deploy.