MCP Zero Shot Agentic Forecaster
Resumen Ejecutivo y Valor de Negocio
¿Qué es este Repositorio?
El MCP Zero Shot Agentic Forecaster es un motor de pronóstico de series temporales de grado de producción, basado en microservicios, expuesto a través del Model Context Protocol (MCP). Impulsado por modelos fundacionales de última generación (Google TimesFM 2.5 XReg y Amazon Chronos-2), permite que agentes de IA autónomos (máquinas de estado LangGraph, enjambres CrewAI, pilas NeSy gobernadas por OPA/Rego y bucles ReAct estándar) consulten pronósticos probabilísticos de demanda bajo demanda, sin entrenamiento de modelos fuera de línea, ajuste de hiperparámetros ni preparación de conjuntos de datos por SKU.
Valor de Negocio y ROI
Elimina la latencia de arranque en frío: Ofrece pronósticos probabilísticos zero-shot instantáneos para lanzamientos de nuevos productos, promociones y SKU con historial corto, sin canalizaciones de entrenamiento.
Control de riesgo acotado por cuantiles: Emite cuantiles de demanda calibrados $p_{10}$, $p_{50}$ y $p_{90}$, lo que permite a los agentes de compra autónomos equilibrar los buffers de stock de seguridad frente a los costos de capital.
Menor costo total de propiedad (TCO): Reemplaza las complejas canalizaciones de ajuste fino con un motor de respaldo unificado de 3 niveles, reduciendo drásticamente los requisitos de cómputo GPU y la deriva de infraestructura.
Resiliencia agéntica: Devuelve cargas útiles estructuradas
AgentFriendlyErrorcon sugerencias de corrección cuando las entradas no son válidas, lo que permite a los agentes llamantes autocorregirse en los bucles de ejecución sin fallar silenciosamente ni lanzar excepciones no controladas.
Cómo Funciona
Invocación del agente: Los agentes llamantes invocan
forecast_demandoforecast_batcha través de stdio/HTTP mediante la interfaz de herramientas MCP.Aplicación del contrato: Los esquemas Pydantic v2 realizan verificaciones rigurosas de límites numéricos finitos y temporales (
[Type-Safe Input Contract]).Inferencia no bloqueante: FastMCP descarga las operaciones pesadas de tensores a grupos de hilos mediante
asyncio.to_threadpara preservar la capacidad de respuesta de la puerta de enlace.Canalización unificada de 3 niveles: Siempre enruta a través de TimesFM 2.5 (Nivel 1), con respaldo a Chronos-2 (Nivel 2, conserva covariables si están presentes) y ARIMA111 (Nivel 3, descarta covariables). Ante OOM de CUDA o fallo, el motor activa la recuperación de memoria (
gc.collect()+torch.cuda.empty_cache()) antes de degradar al siguiente nivel.Saneamiento matemático: Aplica ordenamiento isotónico para garantizar la monotonicidad de los cuantiles de salida ($p_{10} \le p_{50} \le p_{90}$) y normaliza las puntuaciones de confianza epistémica antes de devolver cargas útiles JSON estructuradas.
Related MCP server: Geneva Forecasting MCP
Arquitectura del Sistema
El microservicio cumple una estricta separación de responsabilidades: la capa de herramientas MCP gestiona el transporte no bloqueante, la seguridad de memoria y el saneamiento de salidas a nivel de modelo, dejando las políticas de negocio específicas del dominio a los orquestadores de agentes posteriores.
graph TD
subgraph External Agent Orchestrator
Agent[LLM Agent / Swarm / State Machine<br/>LangGraph / OPA Sidecar / ReAct Loop]
end
subgraph MCP Microservice Boundary
Gateway[FastMCP Async Gateway Server<br/>mcp_server.py]
Sanitizer[Pydantic v2 Input Contract<br/>TimeSeriesInputPayload]
ErrorFormatter[AgentFriendlyError Formatter]
subgraph Engine Memory & Concurrency Boundary
ExecThread[Thread Executor<br/>asyncio.to_thread]
Engine[ZeroShotForecastingEngine<br/>src/models/forecaster.py<br/>Lazy-Load Lock Protected]
subgraph 3-Tier Fallback Model Chain
T1[Tier 1: TimesFM 2.5<br/>XReg / Univariate]
T2[Tier 2: Chronos-2<br/>Multivariate / Univariate]
T3[Tier 3: ARIMA111<br/>CPU Baseline Fallback]
end
IsoSanitizer[Isotonic Quantile Sanitizer<br/>Enforces p10 ≤ p50 ≤ p90]
end
end
Agent -->|FastMCP Tool Call<br/>forecast_demand / forecast_batch| Gateway
Gateway -->|1. Validate Schema| Sanitizer
Sanitizer -->|Validation Error| ErrorFormatter
ErrorFormatter -.->|Structured Error + Remediation| Agent
Sanitizer -->|2. Valid Payload| ExecThread
ExecThread -->|3. Route Request| Engine
Engine --> T1
T1 -.->|CUDA OOM / Fail| T2
T2 -.->|Fail| T3
T1 -->|Raw Quantiles| IsoSanitizer
T2 -->|Raw Quantiles| IsoSanitizer
T3 -->|Raw Quantiles| IsoSanitizer
IsoSanitizer -->|4. Validated ForecastResponse| Gateway
Gateway -->|5. Return JSON Payload| AgentDesglose de Componentes de la Arquitectura
Puerta de enlace FastMCP (mcp_server.py): Proporciona transporte JSON-RPC asíncrono y aplica límites de concurrencia por lotes (asyncio.Semaphore(4)).
Límite de contrato con seguridad de tipos (src/schemas/payloads.py): Aplica alineación temporal, garantías de números finitos y límites de contexto/horizonte.
Núcleo de pronóstico seguro para hilos (src/models/forecaster.py): Emplea bloqueo de doble verificación (threading.Lock()) para la carga diferida de modelos y gestiona la recuperación automática ante OOM de CUDA (gc.collect() + torch.cuda.empty_cache()).
Saneador de salidas isotónico: Procesa posteriormente los cuantiles brutos de los modelos fundacionales mediante ordenamiento monótono para eliminar anomalías estadísticas ($p_{10} > p_{50}$) antes de devolver las predicciones a los agentes.
Flujo de Ejecución del Sistema (Diagrama de Secuencia)
sequenceDiagram
autonumber
actor Agent as LLM Agent / Orchestrator
participant Gateway as FastMCP Gateway (Async)
participant Sanitizer as Pydantic Input Contract
participant Executor as Thread Executor (asyncio.to_thread)
participant Pipeline as 3-Tier Fallback Pipeline
participant Std as Isotonic Quantile Sanitizer
Agent->>Gateway: forecast_demand / forecast_batch (JSON)
Gateway->>Sanitizer: Validate TimeSeriesInputPayload
alt Validation Failure
Sanitizer-->>Gateway: AgentFriendlyError {error_code, expected, received, remediation}
Gateway-->>Agent: Structured Error Response
else Validation Success
Sanitizer->>Executor: Offload sync inference
Executor->>Pipeline: Execute prediction
Note right of Pipeline: Tier 1: TimesFM 2.5 → Tier 2: Chronos-2 → Tier 3: ARIMA111
alt CUDA OOM / Transient Failure
Pipeline->>Pipeline: gc.collect() + torch.cuda.empty_cache()
Pipeline->>Pipeline: Degrade to next tier (retain covariates where possible)
end
Pipeline->>Std: Apply _enforce_quantile_monotonicity()
Std-->>Executor: ForecastResponse {model_used, exogenous_dropped, warnings}
Executor-->>Gateway: Return validated response
Gateway-->>Agent: 200 OK with ForecastResponse
endPrincipios Arquitectónicos Fundamentales
Transporte Asíncrono No Bloqueante
Todos los pases de avance de tensores se ejecutan en un grupo de hilos mediante asyncio.to_thread, manteniendo el bucle de eventos de FastMCP receptivo a verificaciones de salud concurrentes e invocaciones de herramientas bajo carga.
# mcp_server.py
result = await asyncio.to_thread(engine.predict, validated_payload)Carga Diferida de VRAM
Los pesos del modelo se materializan solo en el primer uso mediante métodos de acceso; no se consume VRAM al inicio. El bloqueo de doble verificación seguro para hilos evita la instanciación duplicada en arranques en frío concurrentes.
# src/models/forecaster.py
def _get_timesfm(self):
if self._timesfm is None:
with self._timesfm_lock:
if self._timesfm is None:
import timesfm
logger.info(f"Lazily loading TimesFM-2.5 ({self.timesfm_repo_id}) onto {self._device}")
self._timesfm = timesfm.TimesFM_2p5_200M_torch.from_pretrained(self.timesfm_repo_id)
return self._timesfm
def _get_chronos(self):
if self._chronos is None:
with self._chronos_lock:
if self._chronos is None:
from chronos import BaseChronosPipeline
logger.info(f"Lazily loading Chronos-2 ({self.chronos_repo_id}) onto {self._device}")
self._chronos = BaseChronosPipeline.from_pretrained(
self.chronos_repo_id, device_map=self._device, dtype=torch.float32
)
return self._chronosMotor de Respaldo de 3 Niveles
El motor mantiene una única cadena de degradación determinista unificada, independientemente del contenido de la carga útil.
Nivel | Backend | Modo |
|
|
1 | TimesFM 2.5 | XReg / Univariado |
|
|
2 | Chronos-2 | Multivariado / Univariado |
|
|
3 | ARIMA111 | Línea base |
|
|
Ante un fallo de TimesFM (incluido torch.cuda.OutOfMemoryError):
gc.collect()+torch.cuda.empty_cache()Las señales exógenas se conservan para Chronos-2 mediante
_build_chronos_covariates()(covariables pasadas/futuras)exogenous_dropped = truesolo si el respaldo degrada al Nivel 3 (ARIMA111)La ejecución se enruta a Chronos-2
Si Chronos falla → línea base ARIMA111
Aplicación de Regularidad Temporal
Los validadores Pydantic v2 rechazan telemetría no válida en el límite:
Validador | Regla |
Límites de contexto |
|
Límites de horizonte |
|
Valores finitos |
|
Alineación exógena |
|
Indicadores binarios | los elementos de |
Saneamiento Isotónico de Cuantiles
Todos los backends (TimesFM, Chronos-2, AutoARIMA) emiten cuantiles brutos que ocasionalmente pueden cruzarse ($p_{10} > p_{50}$ o $p_{50} > p_{90}$) ante entradas OOD extremas. El motor aplica un paso de procesamiento posterior ligero _enforce_quantile_monotonicity() que realiza un ordenamiento isotónico por paso temporal: apila $(p_{10}, p_{50}, p_{90})$, ordena a lo largo del eje de cuantiles y devuelve los tripletes ordenados. Esto garantiza $p_{10} \le p_{50} \le p_{90}$ matemáticamente válidos para cada paso del horizonte de pronóstico sin distorsionar la forma distribucional.
Concurrencia por Lotes Acotada
La herramienta MCP forecast_batch ejecuta inferencia multi-SKU de forma concurrente mediante asyncio.gather acotado por un asyncio.Semaphore(4). Esto proporciona rendimiento paralelo mientras protege la memoria GPU/CPU de asignaciones de tensores concurrentes ilimitadas. Cada elemento adquiere el semáforo, valida su carga útil, descarga engine.predict a un grupo de hilos mediante asyncio.to_thread y devuelve una ForecastResponse estructurada con metadatos de respaldo por elemento. El bloque de resumen informa el total de elementos, el recuento de errores y el uso por backend (model_usage).
Interruptores de Circuito por Backend
Cada backend de modelo fundacional mantiene un interruptor de circuito independiente (CircuitBreakerState) para evitar fallos en cascada cuando un hub de modelos es inalcanzable o falla de forma consistente. Después de 5 fallos consecutivos, el interruptor se abre y enruta el tráfico inmediatamente al siguiente nivel de respaldo durante 60 segundos antes de permitir una llamada de prueba.
Backend | Umbral de fallos | Enfriamiento | Comportamiento abierto |
TimesFM 2.5 | 5 fallos | 60s | Lanza |
Chronos-2 | 5 fallos | 60s | Lanza |
Esto garantiza que una interrupción transitoria del HuggingFace Hub o una descarga corrupta de pesos no bloquee al agente indefinidamente.
Métrica de Confianza Normalizada
La puntuación de confianza utiliza una relación de incertidumbre relativa acotada en lugar de un piso lineal que comprime la varianza amplia a 0.0:
$$\text{Confidence} = \frac{1}{1 + \frac{p_{90} - p_{10}}{\vert p_{50}\vert + \epsilon}}$$
donde $\epsilon = 10^{-5}$. Propiedades:
Rango de salida $(0, 1]$: nunca negativa, nunca comprimida a 0
A medida que la dispersión $(p_{90} - p_{10}) \to 0$, la confianza $\to 1$ (límites ajustados)
A medida que la dispersión $\to \infty$, la confianza $\to 0$ asintóticamente (incertidumbre extrema)
Invariante a la escala mediante división por la magnitud mediana $|p_{50}|$
Agnóstico a la Arquitectura Agéntica
Como microservicio de herramientas MCP sin estado y vinculado a esquemas, este motor se integra sin fricción con cualquier orquestador de agentes, incluidas pilas Neuro-Simbólicas gobernadas por políticas OPA/Rego, máquinas de estado LangGraph, enjambres CrewAI o bucles ReAct estándar.
Especificaciones de Herramientas MCP y Contratos de API
forecast_demand
Predicción de una única serie temporal.
Solicitud (TimeSeriesInputPayload)
{
"target_series": [120.5, 115.0, 130.2, 125.8, 140.1],
"forecast_horizon": 30,
"price_index": [19.99, 19.99, 24.99, 24.99, 24.99, 24.99, ...],
"promo_flag": [0, 0, 1, 0, 1, 0, ...]
}Respuesta (ForecastResponse)
{
"model_used": "Chronos-2-Fallback",
"mean_prediction": [142.3, 145.1, 140.8, 148.2, 150.0],
"p10_quantile": [120.1, 122.4, 118.7, 125.3, 127.9],
"p50_quantile": [142.3, 145.1, 140.8, 148.2, 150.0],
"p90_quantile": [165.2, 168.5, 162.1, 170.4, 172.8],
"confidence_score": 0.87,
"horizon_length": 30,
"exogenous_dropped": false,
"warnings": ["CUDA unavailable; running on CPU. Expect degraded inference performance."]
}forecast_batch
Predicción multi-SKU basada en arreglos con resumen de respaldo por elemento.
Solicitud
{
"payloads": [
{"target_series": [10.0]*20, "forecast_horizon": 5},
{"target_series": [11.0]*30, "forecast_horizon": 3, "price_index": [20.0]*33}
]
}Respuesta
{
"results": [
{"model_used": "Chronos-2-Fallback", "mean_prediction": [...], ...},
{"model_used": "TimesFM-2.5", "mean_prediction": [...], ...}
],
"summary": {
"total": 2,
"errors": 0,
"model_usage": {"Chronos-2-Fallback": 1, "TimesFM-2.5": 1}
}
}AgentFriendlyError
Esquema de error autocorrectivo devuelto ante fallos de validación o ejecución.
{
"error_code": "VALIDATION_ERROR",
"message": "Input validation failed at 'price_index': Price array misalignment. Expected 25 elements (Context: 20 + Horizon: 5), got 2.",
"expected": "Payload matching TimeSeriesInputPayload schema (context 16-16000 finite values, aligned exogenous signals).",
"received": "{\"location\": \"price_index\", \"message\": \"Price array misalignment. Expected 25 elements (Context: 20 + Horizon: 5), got 2.\", \"context\": {\"expected\": \"25\", \"got\": \"2\"}}",
"remediation_suggestion": "Correct field 'price_index' (Price array misalignment. Expected 25 elements (Context: 20 + Horizon: 5), got 2.) and resubmit. Ensure context length is between 16 and 16000, values are finite (no NaN/Inf), and exogenous arrays align to len(target_series) + forecast_horizon."
}Códigos de error: VALIDATION_ERROR, MODEL_UNAVAILABLE, TRANSIENT_FAILURE, MODEL_FAILURE, INTERNAL_ERROR
Inicio Rápido y Configuración de MCP
Instalación
# Requires Python 3.11+
uv sync --extra gpu # or: pip install -r requirements.txtEntorno
# Optional: force CPU if GPU memory constrained
export MODEL_CONFIG_PATH=configs/model_config.yaml
export DATA_STORAGE_ROOT=data/El motor detecta automáticamente CUDA. Si no está disponible, recurre a CPU y emite una advertencia en el campo warnings.
Configuración del Cliente MCP (Claude Desktop / OpenCode / LangGraph / CrewAI)
Agregue a la configuración de su cliente MCP (claude_desktop_config.json, opencode.json o equivalente):
{
"mcpServers": {
"zero-shot-forecaster": {
"command": "python",
"args": ["mcp_server.py"],
"cwd": "/absolute/path/to/zero-shot-demand-foundation",
"env": {
"MODEL_CONFIG_PATH": "configs/model_config.yaml"
}
}
}
}Reinicie su cliente MCP. Las herramientas forecast_demand y forecast_batch se registrarán automáticamente con sus esquemas JSON completos.
Ejemplo de Invocación (Claude / Agente LLM)
{
"tool": "forecast_demand",
"arguments": {
"target_series": [120, 115, 130, 125, 140, 135, 150, 145, 155, 160, 155, 165, 170, 168, 172, 175, 180, 178, 185, 190],
"forecast_horizon": 7,
"price_index": [19.99, 19.99, 19.99, 19.99, 19.99, 19.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99, 24.99],
"promo_flag": [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
}
}Verificación y Pruebas
Ejecutar la Suite de Pruebas Completa (62 pruebas, AC-1 a AC-5)
uv run pytest tests/ -q
# or
python -m pytest tests/ -qSalida esperada:
.............................................................. [100%]
62 passed in ~3sMatriz de Cobertura de Pruebas
AC | Criterio | Función de prueba |
AC-1 | Bucle de eventos no bloqueante |
|
AC-2 | Carga diferida y conservación de VRAM |
|
AC-3 | Degradación elegante y eliminación de señales |
|
AC-4 | Recuperación de OOM de CUDA |
|
AC-5 | Cargas útiles de autocorrección del agente |
|
Pruebas heredadas (Compatibilidad hacia atrás)
Las 48 pruebas originales siguen pasando:
pytest tests/test_forecasting_engine.py tests/test_forecaster_router.py tests/test_mcp_server.py tests/test_schemas.py tests/test_metrics.py -qEstructura del proyecto (Post-refactorización)
zero-shot-demand-foundation/
├── configs/
│ └── model_config.yaml # Model IDs, device_map, num_samples
├── data/ # Git-ignored (CSV, ZIP)
├── scripts/
│ ├── download_m5.py # M5 dataset fetcher
│ └── download_favorita.py # Favorita dataset fetcher
├── src/
│ ├── models/
│ │ └── forecaster.py # ZeroShotForecastingEngine (refactored)
│ ├── schemas/
│ │ └── payloads.py # TimeSeriesInputPayload, ForecastResponse, AgentFriendlyError
│ └── utils/
│ ├── data_loader.py # DemandDataEngine, FavoritaDataLoader
│ └── metrics.py # WAPE, RMSSE, Pinball Loss, CRPS
├── tests/
│ ├── test_forecasting_engine.py # Updated for lazy loading
│ ├── test_forecaster_router.py # Updated fixtures
│ ├── test_mcp_server.py # Async + AgentFriendlyError
│ ├── test_metrics.py # Unchanged
│ ├── test_schemas.py # Unchanged
│ └── test_refactored_forecaster.py # NEW: AC-1..5 coverage
├── main.py # CLI evaluation entry point
├── mcp_server.py # FastMCP server (async, batch, errors)
├── requirements.txt
├── .gitignore # Ignores *.md, data/, __pycache__/
└── README.md # This fileLicencia
Licencia MIT. Consulte LICENSE para más detalles.
Referencias
Chronos-2: Ansari et al., Chronos: Learning the Language of Time Series, arXiv:2403.07815
TimesFM: Das et al., TimesFM: A Decoder-Only Foundation Model for Time-Series Forecasting, arXiv:2402.02592
M5 Competition: Makridakis et al., M5 Accuracy Competition, IJF 2022
Corporación Favorita: Kaggle Favorita Grocery Sales Forecasting
Model Context Protocol: Anthropic MCP Specification
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Forecast product demand using historical sales and market signals.
PredictOracle - 12 forecasting tools: time-series, scenario analysis, risk projections.
Built-environment forecasts, public benchmarks, and permit or zoning readiness through remote MCP.
Hosted MCP for e-commerce: live product catalog, stock, and pricing for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server powered by Meta's Prophet that enables LLMs to perform time-series forecasting, trend analysis, and predictive modeling on historical data. It provides LLM-friendly statistical summaries, automated business-rule validation, and ready-to-render Chart.js visualizations.MIT
- AlicenseAqualityDmaintenanceGeneva MCP brings production-grade forecasting directly into AI assistants and coding agents. Connect any MCP-compatible client to the Geneva Forecasting Engine and run rigorous time series forecasts through natural conversation.1MIT
- AlicenseBqualityCmaintenanceEnable any AI agent to forecast time-series data (e.g., sales, traffic) using Google's TimesFM or a zero-dependency statistical baseline.3Apache 2.0
- AlicenseNot gradedqualityBmaintenancePredictive supply-chain MCP server that forecasts material confirmation risks and enables AI clients to interact with the system via natural language.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/arashnicoomanesh/zero-shot-demand-forecasting'
If you have feedback or need assistance with the MCP directory API, please join our Discord server