把自然语言描述转为结构化 JSON,并由 mcp-diagram-generator MCP 服务生成 Draw.io、Mermaid 或 Excalidraw 图表文件。
集成
predictalot
试用Self-hosted forecasting/prediction service. Foundation time-series endpoints under /v1/timeseries/<type>/{forecast,forecast/ensemble} + GET .../models — univariate, past/future/both covariates, multivariate, samples — over 5 zero-shot models (chronos-2, timesfm-2.5, moirai-2, toto-1, sundial-base-128m). Plus supervised tabular ML under /v1/tabular/ (9 backends — lightgbm, xgboost, hist-gbt, random-forest, logistic, mlp, svm-rbf, knn, naive-bayes — over direction/value/quantile modes) with train+persist, weighted ensembles, and calibrated/stacking/diversified meta-learners. Unified REST + MCP (streamable-HTTP at /mcp, one tool per (type, model) cell + per-type ensemble + listing) + optional bearer auth. Use when the user wants to forecast a numeric time series (quantile bands or raw sample paths), condition a forecast on known/future covariates, ensemble several forecasters, or train a tabular model on engineered features and predict direction/value/quantiles on the latest snapshot.
它能做什么
Self-hosted forecasting service — one HTTP container, two model families.
技能文档
predictalot
Self-hosted forecasting service — one HTTP container, two model families.
- Foundation time-series (zero-shot) — 5 forecasters (
chronos-2,timesfm-2.5,moirai-2,toto-1,sundial-base-128m). Hand them a context window, get quantile bands or raw sample paths. No training step. Routed by forecast type under/v1/timeseries//—univariate,covariates/past,covariates/future,covariates(past+future),multivariate,samples. Each type hasforecast,forecast/ensemble, and amodelslisting. - Tabular ML (supervised) — 9 learners (
lightgbm,xgboost,hist-gbt,random-forest,logistic,mlp,svm-rbf,knn,naive-bayes), all supporting 3 modes (direction/value/quantile). Train on YOUR engineered features, persist server-side bymodelId, forecast on the latest feature snapshot. Weighted ensembles over stored models plus 3 meta-learners (calibrated/stacking/diversified). Under/v1/tabular/. - MCP — streamable-HTTP tools at
/mcp. One tool per (FM type, model) cell plus per-type ensemble + listing. Tabular is HTTP-only. - Auth — optional bearer token (
PREDICTALOT_AUTH_TOKENSon the server; refuses to start with no tokens unlessPREDICTALOT_ALLOW_NO_AUTH=1).
For installation, configuration, and container setup, see references/setup.md.
Security & safety
- Network-exposed — predictalot is a plain HTTP + MCP service; anyone who can reach the port can call it. Set
PREDICTALOT_AUTH_TOKENSto a strong generated secret ($(openssl rand -hex 32)) and bind to loopback (-p 127.0.0.1:8080:8080) by default. Only expose beyond loopback behind a reverse proxy / VPN, and never with the default/example token. - External transmission — every forecast/train call sends your time series, engineered feature values, and/or
modelIds to whateverPREDICTALOT_URLpoints at — that data leaves your host. Point it only at a service you run or explicitly trust; prefer HTTPS. - Consumer-only — this skill talks to an instance you already run and trusts. It never provisions, starts, or hardens the server; that's the operator's job (see setup.md).
- Destructive delete requires confirmation —
DELETE /v1/tabular/models/{modelId}permanently removes a trained model and cannot be undone. Only call it against amodelIdyou obtained from a priorGET /v1/tabular/models(or a train response) in this session, and get explicit user confirmation before issuing the delete.
When To Use
- Forecast a numeric time series N steps ahead and get calibrated quantile bands (
0.1/0.5/0.9, etc.) — zero-shot, no training. - Get raw Monte-Carlo sample paths (via the
samplestype) to compute custom risk metrics / joint distributions across horizon steps. - Condition a forecast on covariates: known-history (
covariates/past), forward-known drivers like a planned promotion or price schedule (covariates/future), or both at once (covariates). - Forecast several correlated channels jointly (
multivariate). - Combine multiple forecasters into a weighted ensemble and inspect each member's individual forecast + applied weight.
- Train a supervised model on engineered features and predict next-bar direction (
P(up)), a point value, or quantiles on the latest snapshot. - Combine trained tabular models via ensemble or a
calibrated/stacking/diversifiedmeta-learner.
When NOT To Use
- Real-time / streaming forecasts — every endpoint is request/response only.
- Automatic feature engineering on the tabular side — you supply the features; predictalot does not derive indicators or lags for you.
timesfm-2.5for accuracy — it is the weakest of the five on every benchmarked dataset. Skip it or setweights={"timesfm-2.5": 0}in ensembles.- Commercial use of
moirai-2— it ships under CC-BY-NC-4.0 (non-commercial). The other four FMs are Apache 2.0. - Covariate/multivariate/samples types on models that don't support them — membership is fixed per type (see below). A non-member
model→ 400. - Provisioning or hardening the server from here — this skill is a consumer. It talks to an instance the user already runs and trusts; it never launches, escalates, or reconfigures the container.
Setup
The container should already be running. Point at it:
export PREDICTALOT_URL=http://localhost:8080
If the server has PREDICTALOT_AUTH_TOKENS set, export a token too:
export PREDICTALOT_AUTH_TOKEN=
# every /v1/* and /mcp request below needs: -H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN"
Verify: curl $PREDICTALOT_URL/healthz returns {"ok": true}. (/healthz is unauthenticated.)
For install / configuration / env vars / CPU vs CUDA images, see references/setup.md.
Models & Types
Foundation models, and which forecast types each supports (a model outside a type's member set → 400):
| Model | Univariate | Multivariate | Cov: past | Cov: future | Cov: both | Samples | License | Recommended for |
|---|---|---|---|---|---|---|---|---|
chronos-2 | ✓ | ✓ | ✓ | ✓ | ✓ | — | Apache 2.0 | Default all-rounder; fastest on CPU; only model with future/both covariates. |
timesfm-2.5 | ✓ | — | — | — | — | — | Apache 2.0 | Weakest on benchmarks — skip or zero-weight it. Univariate-only; compile-time horizon cap. |
moirai-2 | ✓ | ✓ | ✓ | — | — | — | CC-BY-NC-4.0 | Clean cyclic/seasonal series; correlated channels. Non-commercial license. |
toto-1 | ✓ | ✓ | — | — | — | ✓ | Apache 2.0 | Noisy / observability / financial series; exposes raw sample paths. |
sundial-base-128m | ✓ | — | — | — | — | ✓ | Apache 2.0 | Drifting / trending series; generative sample paths. Runs in a sidecar venv. |
Type → URL prefix:
| Type | URL prefix | Members |
|---|---|---|
| univariate | /v1/timeseries/univariate | chronos-2, timesfm-2.5, moirai-2, toto-1, sundial-base-128m |
| multivariate | /v1/timeseries/multivariate | chronos-2, moirai-2, toto-1 |
| covariates (past) | /v1/timeseries/covariates/past | chronos-2, moirai-2 |
| covariates (future) | /v1/timeseries/covariates/future | chronos-2 |
| covariates (past+future) | /v1/timeseries/covariates | chronos-2 |
| samples | /v1/timeseries/samples | toto-1, sundial-base-128m |
Discover live per-type membership + runtime state with GET /v1/timeseries//models. Discover tabular backends with GET /v1/tabular/backends.
Tabular backends (all support direction / value / quantile):
| Slug | Display name | Category |
|---|---|---|
lightgbm | LightGBM | boosting |
xgboost | XGBoost | boosting |
hist-gbt | HistGradientBoosting (sklearn) | boosting |
random-forest | Random Forest | bagging |
logistic | Logistic / Ridge / QuantileRegressor (linear baselines) | linear |
mlp | Multi-Layer Perceptron (sklearn) | neural |
svm-rbf | SVM with RBF kernel | kernel |
knn | k-Nearest Neighbors | distance |
naive-bayes | Gaussian Naive Bayes / BayesianRidge | independence |
Quick Start
Every forecast/train call below sends your time series, engineered features, and/or
modelIds over the network to$PREDICTALOT_URL. Only point this at a trusted, self-hosted instance you control, prefer HTTPS, treat proprietary datasets as sensitive, and never echoPREDICTALOT_AUTH_TOKENin output.
# Health (unauthenticated).
curl -s $PREDICTALOT_URL/healthz | jq
# List univariate models + their runtime state.
curl -s $PREDICTALOT_URL/v1/timeseries/univariate/models \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" | jq
# Zero-shot univariate forecast: 5 steps ahead of one series, chronos-2.
curl -s $PREDICTALOT_URL/v1/timeseries/univariate/forecast \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "chronos-2",
"context": [[10,11,12,13,14,15,16,17,18,19,20]],
"config": { "horizon": 5, "quantileLevels": [0.1, 0.5, 0.9] }
}' | jq
Wire format is camelCase (quantileLevels, contextLength, pastCovariates, futureCovariates, numSamples, memberOverrides, modelId). All /v1/* routes require the bearer header when the server has tokens configured; drop the header for an open-auth deployment.
Shapes recur across the timeseries API: context is [series][time] (a batch of independent series), horizon > 0, quantileLevels is a subset of {0.1, 0.2, …, 0.9} (default [0.1, 0.5, 0.9]), contextLength caps history fed to the model (omit → per-model default), unload: true tears the model down after the response. median and quantiles["0.5"] are the same for most models but can differ for chronos-2 (its median is the distribution mean).
API — POST /v1/timeseries/univariate/forecast
Single-model quantile forecast over a batch of independent series. context (your time series data) transmits off-box to $PREDICTALOT_URL — same data-transfer note as Quick Start applies to every timeseries endpoint below.
Request Fields
| Field | Required | Default | Notes |
|---|---|---|---|
model | yes | — | One of the univariate members. Not a member → 400; unknown slug → 404. |
context | yes | — | [series][time] — one inner list of floats per series. |
config.horizon | yes | — | Steps ahead. Must be > 0 (else 422). |
config.quantileLevels | no | [0.1, 0.5, 0.9] | Subset of {0.1..0.9} step 0.1. Out-of-range → 400. |
config.contextLength | no | per-model | Max history points fed to the model. > 0. |
config.extra | no | — | Per-backend escape-hatch dict, camelCased. Unknown keys ignored. E.g. chronos-2: batchSize, crossLearning, limitPredictionLength; toto-1: numSamples, samplesPerBatch, useKvCache; timesfm-2.5: normalizeInputs, fixQuantileCrossing, … |
unload | no | false | Unload the model after responding. |
Response
{
"model": "chronos-2",
"horizon": 5,
"quantileLevels": [0.1, 0.5, 0.9],
"median": [[20.9, 21.8, 22.7, 23.6, 24.5]],
"quantiles": {
"0.1": [[20.1, 20.8, 21.5, 22.1, 22.7]],
"0.5": [[20.9, 21.8, 22.7, 23.6, 24.5]],
"0.9": [[21.7, 22.9, 24.0, 25.1, 26.3]]
}
}
median is [series][time]; quantiles maps each level string → [series][time].
Error Contract
| Status | Shape | When |
|---|---|---|
| 200 | forecast JSON | success |
| 400 | {"detail": "..."} | empty context/series, model not a member of the type, quantile level outside {0.1..0.9}, horizon over a model's compile-time cap (timesfm-2.5 / moirai-2) |
| 401 | {"detail": "..."} | tokens configured, missing/wrong bearer |
| 404 | {"detail": "..."} | unknown model slug |
| 413 | {"detail": "..."} | body over PREDICTALOT_MAX_BODY_SIZE |
| 422 | {"detail": [...]} | Pydantic validation (missing/typed fields, horizon not > 0) |
| 503 | {"detail": "..."} | snapshot download failed, inference threw, or sundial sidecar unreachable |
API — POST /v1/timeseries/univariate/forecast/ensemble
Weighted mean across every univariate member. No model field — membership is the whole type.
Request Fields
| Field | Required | Default | Notes |
|---|---|---|---|
context | yes | — | [series][time]. |
config | yes | — | Same ForecastConfig as single forecast (horizon, quantileLevels, contextLength, extra). |
weights | no | uniform | {slug: float ≥ 0}. Missing slugs default to 1.0; weight 0 disables a member; unknown slug → 400. |
memberOverrides | no | — | {slug: partial-config} — per-member overrides of the global config (e.g. give one member a different contextLength or extra). |
unload | no | false | Unload members after responding. |
Response
Aggregated median + quantiles (same shapes as single forecast) with model: "ensemble", plus:
{
"model": "ensemble",
"horizon": 5,
"quantileLevels": [0.1, 0.5, 0.9],
"median": [[...]],
"quantiles": { "0.1": [[...]], "0.5": [[...]], "0.9": [[...]] },
"ensembleMembers": ["chronos-2", "moirai-2", "toto-1"],
"weights": { "chronos-2": 0.5, "moirai-2": 0.25, "toto-1": 0.25 },
"individual": {
"chronos-2": { "model": "chronos-2", "horizon": 5, "quantileLevels": [...],
"median": [[...]], "quantiles": {...}, "weight": 0.5 }
}
}
individual[slug] is that member's full single-forecast response + its applied weight.
Error Contract
Same as single univariate, minus 404 (no model field) — an unknown weights slug is a 400, not 404.
API — POST /v1/timeseries/covariates/past/forecast
Forecast each target series conditioned on covariates known only up to t. Members: chronos-2, moirai-2.
Request Fields
| Field | Required | Default | Notes |
|---|---|---|---|
model | yes | — | A past-covariate member. |
context | yes | — | [series][time] — the univariate targets. |
pastCovariates | yes | — | list[dict[name, float[]]] — one mapping per series; every value array is the same length as that series' context. All series share the same covariate names. |
config | yes | — | ForecastConfig (horizon, quantileLevels, contextLength, extra). |
unload | no | false |
Response
Identical shape to univariate single forecast (model, horizon, quantileLevels, median, quantiles).
Error Contract
Same table as univariate, plus 400 when a pastCovariates value length doesn't match the matching context series.
API — POST /v1/timeseries/covariates/past/forecast/ensemble
Weighted ensemble over the past-covariate members. Fields = past forecast fields plus weights + memberOverrides (as in the univariate ensemble). Response = univariate ensemble shape.
API — POST /v1/timeseries/covariates/future/forecast
Forecast conditioned on covariates known only over the future window (length == horizon) — e.g. a planned promotion, a published price schedule, a weather forecast. Member: chronos-2 only.
Request Fields
| Field | Required | Default | Notes |
|---|---|---|---|
model | yes | — | chronos-2. |
context | yes | — | [series][time] targets. |
futureCovariates | yes | — | list[dict[name, float[]]] — one mapping per series; each value array of length horizon. All series share names. |
config | yes | — | ForecastConfig. |
unload | no | false |
Response
Univariate single-forecast shape.
Error Contract
Univariate table + 400 when a futureCovariates value length ≠ config.horizon.
API — POST /v1/timeseries/covariates/future/forecast/ensemble
Ensemble over future-covariate members (currently just chronos-2, so only useful once more back it). Fields = future forecast + weights + memberOverrides. Response = univariate ensemble shape.
API — POST /v1/timeseries/covariates/forecast (past + future)
Combined past and future covariates in one call. Member: chronos-2 only.
Request Fields
| Field | Required | Default | Notes |
|---|---|---|---|
model | yes | — | chronos-2. |
context | yes | — | [series][time] targets. |
pastCovariates | yes | — | Per series, same length as context. |
futureCovariates | yes | — | Per series, length horizon. Every future-covariate name MUST also appear in pastCovariates for that series (chronos-2 constraint) — else 400. |
config | yes | — | ForecastConfig. |
unload | no | false |
Response
Univariate single-forecast shape.
Error Contract
Univariate table + 400 for length mismatches or a future-covariate name missing from pastCovariates.
API — POST /v1/timeseries/covariates/forecast/ensemble
Ensemble over past+future members. Fields = past+future forecast + weights + memberOverrides. Response = univariate ensemble shape.
API — GET /v1/timeseries//models
Per-type model listing + runtime state. `` ∈ univariate, multivariate, covariates/past, covariates/future, covariates, samples.
Response
{
"type": "univariate",
"models": [
{ "slug": "chronos-2", "loaded": true, "lastUsedSecsAgo": 12.4, "idleTimeoutSecs": 1800.0 },
{ "slug": "timesfm-2.5", "loaded": false, "lastUsedSecsAgo": null, "idleTimeoutSecs": 1800.0 }
]
}
lastUsedSecsAgo is null when the model has never loaded. idleTimeoutSecs reflects PREDICTALOT_MODEL_IDLE_TIMEOUT (or a per-slug override); 0 means never auto-unloaded.
Error Contract
200 on success; 401 when tokens are configured and the bearer is missing/wrong.
API — GET /v1/tabular/backends
List the supervised tabular backends and the modes each supports. Use this to discover the live set before a train call.
Response
{
"backends": [
{ "slug": "lightgbm", "displayName": "LightGBM", "category": "boosting",
"supportedModes": ["direction", "quantile", "value"] },
{ "slug": "xgboost", "displayName": "XGBoost", "category": "boosting",
"supportedModes": ["direction", "quantile", "value"] }
]
}
Error Contract
200 on success; 401 when tokens are configured and the bearer is missing/wrong.
Tabular API (train → forecast)
The tabular side trains on YOUR engineered features and persists a model server-side by modelId. target / features are generic float lists — no OHLC / indicator assumptions. features is per series: featureName → time-aligned float list. Same data-transfer note as Quick Start applies: target/features/modelId all transmit to $PREDICTALOT_URL.
POST /v1/tabular/train
| Field | Required | Default | Notes |
|---|---|---|---|
modelId | yes | — | Caller-chosen id, used for storage + later forecast lookup. |
backend | yes | — | A slug from GET /v1/tabular/backends. Unknown → 404. |
target | yes | — | [series][time] — the scalar series to predict. Empty → 400. |
features | yes | — | list[dict[name, float[]]] — same length + names per series as target. Count must match target (else 400); differing key sets across series → 400. |
config.mode | yes | — | direction (sign of target[t+h] - target[t]) / value (regress target[t+h]) / quantile. Mode not supported by the backend → 400. |
config.horizon | yes | — | Bars ahead (t+h). > 0. |
config.quantileLevels | when quantile | — | Required for mode="quantile"; subset of {0.1..0.9}. |
config.* (tier-2) | no | — | nEstimators, maxDepth, learningRate, numLeaves, minSamples, randomState, categoricalFeatures, monotonicConstraints, classWeight, sampleWeight, earlyStoppingRounds, validationFraction. Backends ignore knobs they don't use. |
config.extra | no | — | Per-backend hyperparams (e.g. svm-rbf reads C/gamma; mlp reads hiddenLayerSizes/activation; knn reads nNeighbors/weights/metric). |
overwrite | no | false | Reuse an existing modelId → 409 unless true. |
Response (TrainResponse): modelId, backend, mode, horizon, nTrainingRows, nFeatures, featureNames, featureImportance ({name: float}), trainSecs.
POST /v1/tabular/forecast
Runs a stored model on the latest feature snapshot — the LAST row per series is the anchor; earlier rows are ignored.
| Field | Required | Notes |
|---|---|---|
modelId | yes | Missing → 404. If its backend is no longer registered → 410. |
features | yes | list[dict[name, float[]]]; names must match training. Missing a trained name → 400. |
Response (ForecastResponse) is mode-dependent:
direction:probUp: float[](per series) +confidence: float[](|probUp-0.5|*2).value:predicted: float[].quantile:median: float[series][1]+quantiles: {level: float[series][1]}.
POST /v1/tabular/forecast/ensemble
Weighted combination of several stored models on the same features; all members must share mode, horizon, and featureNames (mismatch → 400).
| Field | Required | Notes |
|---|---|---|
modelIds | yes | Stored ids to combine (≥ 1). Any missing → 404. |
weights | no | {modelId: float ≥ 0}. None → uniform; 0 removes a member; unknown id or negative → 400. |
features | yes | As in forecast; last row per series is the anchor. |
Response (EnsembleForecastResponse): mode, horizon, ensembleMembers, normalized weights, individual ({modelId: member response}), plus the combined mode-specific fields (probUp+confidence / predicted / median+quantiles).
GET /v1/tabular/models and DELETE /v1/tabular/models/{modelId} (destructive)
GET lists stored models: {"models": [{ modelId, backend, mode, horizon, nFeatures, featureNames, nTrainingRows, trainedAtUnix }]}. DELETE removes one ({"modelId": "...", "removed": true}; 404 if absent) — irreversible. Only delete a modelId returned by a prior GET /v1/tabular/models call (or a train response), and get explicit user confirmation first.
Meta-learners
Composite endpoints that hold out / cross-validate internally so you don't have to orchestrate it client-side. Each persists one blob under a meta: backend tag and forecasts via POST /v1/tabular/forecast/ with {modelId, features}.
POST /v1/tabular/train/calibrated— base learner + post-hoc probability calibrator.directiononly. Fields:modelId,baseBackend,target,features,config(mode must bedirection),calibrationMethod(sigmoid|isotonic, defaultsigmoid),calibrationFraction(default0.2, in(0,1)),overwrite. Too-small split → 400.POST /v1/tabular/train/stacking— K base learners + a meta-learner on K-fold OOF predictions.directiononly (v1). Fields:modelId,members(≥ 2{backend, config}, alldirection, horizon == top-level),metaBackend(defaultlogistic),target,features,horizon,nFolds(2–10, default 5),overwrite. Needs≥ nFolds*5rows. Response includesoofScore(AUC).POST /v1/tabular/train/diversified— trains K candidates, selects a low-correlation subset by OOF Pearson correlation, combines equal-weight. Supports all 3 modes. Fields:modelId,candidates(≥ 2, mode+horizon must match top-level),target,features,horizon,mode,quantileLevels(required ifquantile),nFolds(2–10, default 3),maxPairwiseCorr(0–1, default 0.85),minMembers,maxMembers,overwrite. Response includescandidateCorr.
Meta-train responses (MetaTrainResponse): modelId, kind, mode, horizon, membersUsed, nTrainingRows, nFeatures, featureNames, trainSecs, plus oofScore (stacking) / candidateCorr (diversified). Meta-forecast responses (MetaForecastResponse): modelId, kind, mode, horizon, members (per-member breakdown), selectedMembers (diversified), and the mode-specific combined fields.
Tabular Error Contract
| Status | When |
|---|---|
| 200 | success |
| 400 | empty target; target/features count mismatch; differing feature key sets; mode unsupported by backend; quantile without quantileLevels; forecast features missing a trained name; ensemble member mode/horizon/features mismatch; unknown/negative ensemble weight; meta constraint violated (calibrated non-direction, stacking non-direction, diversified quantile w/o levels, split too small) |
| 401 | tokens configured, missing/wrong bearer |
| 404 | unknown tabular backend on train; modelId not found on forecast/meta |
| 409 | train with overwrite: false against an existing modelId |
| 410 | forecast against a modelId whose backend is no longer registered |
| 413 | body over PREDICTALOT_MAX_BODY_SIZE |
| 422 | Pydantic validation |
| 503 | training/inference threw |
MCP Endpoint (/mcp)
predictalot mounts a Model Context Protocol server over Streamable HTTP at /mcp, in the same process, behind the same bearer auth. The tool surface mirrors the foundation-model routes only — tabular is HTTP-only.
For each forecast type there are three classes of tool:
forecast__— single-model forecast for one (type, model) cell. Types are underscore-normalized:univariate,multivariate,covariates_past,covariates_future,covariates_both,samples; model slugs are underscore-normalized too (chronos-2→chronos_2). E.g.forecast_univariate_chronos_2,forecast_covariates_future_chronos_2.forecast__ensemble— weighted ensemble over every model supporting that type.list__models— which models implement the type + runtime state ({type, models: [{slug, loaded, lastUsedSecsAgo, idleTimeoutSecs}]}).
Tool args mirror the HTTP bodies but flattened (no nested config): context, horizon, quantile_levels?, context_length?, unload?; covariate tools add past_covariates / future_covariates; ensemble tools add weights?; samples tools use num_samples? instead of quantile levels and return samples [series][sample][time] + median.
Wire it into Claude Code (auth optional — the token may also be passed as ?apiToken=):
claude mcp add --transport http predictalot $PREDICTALOT_URL/mcp \
--header "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN"
Raw JSON-RPC
The transport requires Accept: application/json, text/event-stream.
# tools/list — enumerate every (type, model) tool + ensembles + listings.
curl -s $PREDICTALOT_URL/mcp/ \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
# tools/call — univariate chronos-2 forecast.
curl -s $PREDICTALOT_URL/mcp/ \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": {
"name": "forecast_univariate_chronos_2",
"arguments": {
"context": [[10,11,12,13,14,15,16,17,18,19,20]],
"horizon": 5,
"quantile_levels": [0.1, 0.5, 0.9]
}
}
}'
Each tool returns a JSON-encoded string. User-input errors come back as {"error": "...", "context": "/"}; internal errors are redacted to {"error": "internal error; see server logs", "context": "..."}.
Bearer-Token Auth
If PREDICTALOT_AUTH_TOKENS (comma-separated list) is set on the server, every /v1/* and /mcp request needs Authorization: Bearer ; /healthz is always open. Missing/wrong → 401. Tokens are compared constant-time (hmac.compare_digest).
export PREDICTALOT_AUTH_TOKEN=
curl -s $PREDICTALOT_URL/v1/timeseries/univariate/models \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" | jq
The server refuses to start with an empty token list unless it was launched with PREDICTALOT_ALLOW_NO_AUTH=1 — in that open-auth mode there is no 401 and no header is needed. For untrusted networks, combine the token with a reverse proxy doing TLS + rate limiting.
Typical Workflows
Pick a model → forecast → read the intervals
# 1. See which univariate models are available + resident.
curl -s $PREDICTALOT_URL/v1/timeseries/univariate/models \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" | jq -r '.models[].slug'
# 2. Forecast with chronos-2 (default all-rounder), 12 steps, three bands.
curl -s $PREDICTALOT_URL/v1/timeseries/univariate/forecast \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"model":"chronos-2","context":[[100,102,101,105,110,108,112,115,120,118,125,130]],
"config":{"horizon":12,"quantileLevels":[0.1,0.5,0.9]}}' | jq
# 3. Read the interval: quantiles["0.5"] is the central path,
# ["0.1"]/["0.9"] the 80% band — all shaped [series][time].
Ensemble, zero-weighting the weak model
curl -s $PREDICTALOT_URL/v1/timeseries/univariate/forecast/ensemble \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"context":[[100,102,101,105,110,108,112,115,120,118,125,130]],
"config":{"horizon":12},
"weights":{"timesfm-2.5":0,"chronos-2":2,"toto-1":1}}' | jq \
'{members: .ensembleMembers, weights, median}'
Future-covariate forecast (chronos-2)
# Target has 8 steps of history; horizon 4 → futureCovariates arrays length 4.
curl -s $PREDICTALOT_URL/v1/timeseries/covariates/future/forecast \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"model":"chronos-2",
"context":[[20,22,21,25,24,27,29,31]],
"futureCovariates":[{"promo":[0,1,1,0]}],
"config":{"horizon":4}}' | jq
Raw sample paths for custom risk metrics
curl -s $PREDICTALOT_URL/v1/timeseries/samples/forecast \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"model":"toto-1",
"context":[[100,102,101,105,110,108,112,115,120,118,125,130]],
"config":{"horizon":10,"numSamples":256}}' | jq '{numSamples, shape: (.samples[0]|length)}'
# samples is [series][sample][time]; compute your own VaR / quantiles off the draws.
Train a tabular direction model, then forecast the latest snapshot
# 1. Train on engineered features (you supply them).
curl -s $PREDICTALOT_URL/v1/tabular/train \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"modelId":"trend-3","backend":"lightgbm",
"target":[[100,101,99,102,105,103,107,110,108,112]],
"features":[{"rsi":[55,58,52,60,63,59,65,70,66,72],
"mom":[0.2,0.3,-0.1,0.4,0.5,0.2,0.6,0.7,0.4,0.8]}],
"config":{"mode":"direction","horizon":3,"nEstimators":400}}' | jq
# 2. Forecast — LAST feature row is the anchor.
curl -s $PREDICTALOT_URL/v1/tabular/forecast \
-H "Authorization: Bearer $PREDICTALOT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"modelId":"trend-3","features":[{"rsi":[72],"mom":[0.8]}]}' | jq
# → {"modelId":"trend-3","backend":"lightgbm","mode":"direction","horizon":3,
# "probUp":[0.63],"confidence":[0.26]}
For a driver that runs a univariate forecast and pretty-prints the interval, see scripts/predictalot.sh:
PREDICTALOT_URL=http://localhost:8080 \
PREDICTALOT_AUTH_TOKEN= \
bash scripts/predictalot.sh chronos-2 5 10 11 12 13 14 15 16 17 18 19 20
Tips
- Default to
chronos-2— fastest on CPU, widest type coverage (only model with future/both covariates), solid general-purpose accuracy. - Skip or zero-weight
timesfm-2.5— weakest on every benchmark. In ensembles passweights={"timesfm-2.5":0}. moirai-2is CC-BY-NC-4.0 — non-commercial. Fine for research/eval, not for a commercial product.- Use
samplesfor risk work —toto-1/sundial-base-128mreturn raw[series][sample][time]paths; compute your own VaR / joint metrics instead of trusting fixed quantile cuts. median≠quantiles["0.5"]for chronos-2 — itsmedianis the distribution mean; the others agree.- Covariate length rules — past covariates match the context length; future covariates match
horizon; in the past+future type every future-cov name must also be a past-cov name. - Tabular features are yours — the API does no feature engineering. The LAST row per series is the forecast anchor.
overwrite: falseis the default on every train endpoint — re-training a knownmodelIdis a 409 until you passoverwrite: true.- Discover, don't assume —
GET /v1/timeseries//modelsandGET /v1/tabular/backendsare the live source of truth for membership and modes. - First call is a cold load — a model not yet resident pays a load (and download, if the snapshot isn't cached) on first request; subsequent calls are fast until the idle sweeper unloads it.
相关技能
通过一个命令行工具完成多链加密货币交易、钱包管理与 AI 市场分析。
通过一次 REST API 调用,向 10 个社交平台发布视频、图片、文字与文档。
以 AI 机器人身份加入视频会议,提供语音、虚拟形象与屏幕共享四种模式。
诊断生产力系统反复失效的根因,给出最小干预——容量测算、瓶颈定位、可靠的本地记录。
在本地磁盘以分类纯 Markdown 文件保存需要长期留存的事实,与智能体内置记忆并存。
psyb0t 的更多技能
浏览全部技能对接用户自部署的 mt5-httpapi MetaTrader 5 网关,每次涉及真实资金的写操作都必须逐笔确认后再执行。
面向反爬检测栈 QA 与授权测试场景的 Docker 浏览器自动化工具。
自托管、OpenAI 兼容的语音服务,一个容器搞定转写、翻译与合成。
在固定白名单的 SSH 沙箱里跑 ffmpeg、sox、ImageMagick 处理音视频和图片。
通过 SSH 调用 Qwen3-TTS 生成语音,支持预设音色、声音克隆与声音设计。
一个端点统一管控多个 IMAP/SMTP 邮箱,跨账号并行完成读取、检索、发送、标记与删除。