88bd4e7bde
- exchanges/macro: cot.py + cot_contracts.py + fetchers.py copiati 1:1 con rewrite import mcp_common -> cerbero_mcp.common, mcp_macro -> cerbero_mcp.exchanges.macro - nuovo MacroClient stateless wrapper: trasporta solo fred_api_key/finnhub_api_key, niente HTTP session (i fetchers usano async_client ad-hoc) - tools.py: 11 tool (get_treasury_yields, get_yield_curve_slope, get_breakeven_inflation, get_economic_indicators, get_macro_calendar, get_market_overview, get_equity_futures, get_asset_price, get_cot_tff, get_cot_disaggregated, get_cot_extreme_positioning) — niente write, niente leverage_cap - routers/macro.py: prefix /mcp-macro, 11 route POST /tools/* - builder branch macro: stesse credenziali per testnet/mainnet (env ignorato); registry istanzia 2 entry, costo trascurabile (wrapper stateless) - test migrati: test_cot.py + test_fetchers.py (test_server_acl.py skippato V1-only) - nuovo test test_build_client_macro_no_env_distinction in test_exchanges_builder.py Suite: 224 passed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
"""Router /mcp-macro/* — read-only data provider.
|
|
|
|
Macro non distingue testnet/mainnet (FRED/Finnhub sono endpoint pubblici unici),
|
|
ma manteniamo la signature `Environment` per uniformità con gli altri router.
|
|
Tutti i tool sono READ — niente write, niente leverage_cap.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Literal
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
|
|
from cerbero_mcp.client_registry import ClientRegistry
|
|
from cerbero_mcp.exchanges.macro import tools as t
|
|
from cerbero_mcp.exchanges.macro.client import MacroClient
|
|
|
|
Environment = Literal["testnet", "mainnet"]
|
|
|
|
|
|
def get_environment(request: Request) -> Environment:
|
|
return request.state.environment
|
|
|
|
|
|
async def get_macro_client(
|
|
request: Request, env: Environment = Depends(get_environment)
|
|
) -> MacroClient:
|
|
registry: ClientRegistry = request.app.state.registry
|
|
return await registry.get("macro", env)
|
|
|
|
|
|
def make_router() -> APIRouter:
|
|
r = APIRouter(prefix="/mcp-macro", tags=["macro"])
|
|
|
|
@r.post("/tools/get_economic_indicators")
|
|
async def _get_economic_indicators(
|
|
params: t.GetEconomicIndicatorsReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_economic_indicators(client, params)
|
|
|
|
@r.post("/tools/get_macro_calendar")
|
|
async def _get_macro_calendar(
|
|
params: t.GetMacroCalendarReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_macro_calendar(client, params)
|
|
|
|
@r.post("/tools/get_market_overview")
|
|
async def _get_market_overview(
|
|
params: t.GetMarketOverviewReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_market_overview(client, params)
|
|
|
|
@r.post("/tools/get_asset_price")
|
|
async def _get_asset_price(
|
|
params: t.GetAssetPriceReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_asset_price(client, params)
|
|
|
|
@r.post("/tools/get_treasury_yields")
|
|
async def _get_treasury_yields(
|
|
params: t.GetTreasuryYieldsReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_treasury_yields(client, params)
|
|
|
|
@r.post("/tools/get_equity_futures")
|
|
async def _get_equity_futures(
|
|
params: t.GetEquityFuturesReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_equity_futures(client, params)
|
|
|
|
@r.post("/tools/get_yield_curve_slope")
|
|
async def _get_yield_curve_slope(
|
|
params: t.GetYieldCurveSlopeReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_yield_curve_slope(client, params)
|
|
|
|
@r.post("/tools/get_breakeven_inflation")
|
|
async def _get_breakeven_inflation(
|
|
params: t.GetBreakevenInflationReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_breakeven_inflation(client, params)
|
|
|
|
@r.post("/tools/get_cot_tff")
|
|
async def _get_cot_tff(
|
|
params: t.GetCotTffReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_cot_tff(client, params)
|
|
|
|
@r.post("/tools/get_cot_disaggregated")
|
|
async def _get_cot_disaggregated(
|
|
params: t.GetCotDisaggregatedReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_cot_disaggregated(client, params)
|
|
|
|
@r.post("/tools/get_cot_extreme_positioning")
|
|
async def _get_cot_extreme_positioning(
|
|
params: t.GetCotExtremeReq,
|
|
client: MacroClient = Depends(get_macro_client),
|
|
):
|
|
return await t.get_cot_extreme_positioning(client, params)
|
|
|
|
return r
|