aster-agent-gateway
An MCP (Model Context Protocol) server that gives AI agents read-only,
keyless access to Aster DEX public data - ~580 futures symbols
(including 24/7 TradFi perps: metals, equity indices, energy,
treasuries), ~68 spot pairs, funding, order books, klines, vault
deposit flows and tapi account views. No API keys, no auth, no
signing, no writes: every tool reads public endpoints only
(fapi.asterdex.com/fapi/v3, sapi.asterdex.com/api/v3,
tapi.asterdex.com/info, api.mainnet-beta.solana.com, plus optional
EVM RPCs), cached and rate-limited so an enthusiastic agent cannot
hammer the upstream.
Use cases
- Screen 731 funding rates in one call — ranked by annualized rate with funding regime and mark/index spread; the 793% outliers are visible instantly
- Trade TradFi 24/7 — metals, equity indices, energy, treasuries perps next to crypto, one consistent API
- Follow the vault money — deposit flows per vault: who is parking capital where
- Spot index dislocations — mark vs index divergence ranking across the whole board
- Morning scan — market overview + funding overview + OI snapshot, three cheap calls
Full walkthroughs: examples/use-cases.md.
Quickstart
Claude Code:
claude mcp add aster -- uvx aster-agent-gateway
stdio (default, for local agents):
uvx aster-agent-gateway
or from a checkout:
git clone https://github.com/alekskram/aster-agent-gateway
cd aster-agent-gateway
uv sync
uv run aster-agent-gateway
Claude Desktop / Cursor config:
{
"mcpServers": {
"aster": {
"command": "uvx",
"args": ["aster-agent-gateway"]
}
}
}
Hosted form — streamable HTTP on port 8904:
uvx aster-agent-gateway --http # 127.0.0.1:8904
curl http://127.0.0.1:8904/health # -> {"ok": true, "service": "aster-agent-gateway", ...}
Codex (~/.codex/config.toml)
[mcp_servers.aster]
command = "uvx"
args = ["aster-agent-gateway"]
ZCode — register the server (copy-paste)
# 1) start the gateway (keep it running)
uvx aster-agent-gateway --http --port 8904 &
# 2) register it (merges into ~/.zcode/cli/config.json)
python3 - <<'PY'
import json, os
p = os.path.expanduser("~/.zcode/cli/config.json")
os.makedirs(os.path.dirname(p), exist_ok=True)
cfg = json.load(open(p)) if os.path.exists(p) else {}
cfg.setdefault("mcp", {}).setdefault("servers", {})["aster"] = {
"type": "http", "url": "http://127.0.0.1:8904/mcp"}
json.dump(cfg, open(p, "w"), indent=2)
print("aster-agent-gateway registered:", p)
PY
Tools
All 13 tools are read-only (annotated readOnlyHint: true, destructiveHint: false).
| # | Tool | Signature | What it does |
|---|---|---|---|
| 1 | market_overview |
market_overview(limit=20, sort="volume") |
Futures panel from ONE ticker/24hr ALL call joined with exchangeInfo: TRADING markets, top volumes, status counts, fresh listings (onboardDate). |
| 2 | exchange_symbols |
exchange_symbols(venue="futures", symbol=None, include_junk=False) |
Symbol universe with filters/precisions incl. MIN_NOTIONAL, stepSize, leverageFilter; TEST*/SETTLING junk filtered by default. |
| 3 | order_book |
order_book(symbol, venue="futures", depth=10) |
fapi depth / sapi api/v3 depth; limit snapped to a priced tier (weight-aware). |
| 4 | klines |
klines(symbol, interval="1h", limit=100, market="futures", price_type="last") |
last/mark/index klines on fapi; spot via sapi. |
| 5 | trades |
trades(symbol, limit=20, venue="futures") |
Fresh keyless trades; spot path probed live (honest error dict if dead). |
| 6 | spot_overview |
spot_overview(limit=20) |
Spot pairs from sapi ticker/24hr + exchangeInfo; TEST* junk filtered. |
| 7 | funding_overview |
funding_overview(limit=20, sort="rate") |
All ~730 rates from premiumIndex + fundingInfo: mixed 1/2/4/8h intervals (flagged), cap/floor, interestRate, nextFundingTime. |
| 8 | tradfi_markets |
tradfi_markets(limit=20, window=None) |
TradFi-perp screener by asset class (metals/equity/energy/treasuries/forex) + tradfi_crypto_corr sub-block: local TradFi-vs-BTC correlation from klines. |
| 9 | funding_screener |
funding_screener(top=10, direction="both") |
One-call ranking by annualized funding, premium, mark-index spread + funding_regime headroom to cap/floor. |
| 10 | oi_snapshot |
oi_snapshot(symbols=None, top=10) |
Per-symbol openInterest (max 10 symbols/call). No keyless OI history (404) - stated honestly. |
| 11 | deposit_flows |
deposit_flows(chain_filter="all", limit=20) |
Solana vault signatures (keyless) + EVM vault Transfers when ASTER_EVM_RPC_URL* set + deposit_stats hourly/chain buckets. |
| 12 | account_view |
account_view(address, data="balance") |
tapi aster_getBalance/openOrders/userFills keyless for any address; privacy-empty returns an honest error dict explaining why. |
| 13 | mark_index_divergence |
mark_index_divergence(limit=20) |
mark vs index spread screener from ONE premiumIndex call + markPriceKlines-vs-klines crosscheck on the top 3. |
Why a gateway and not the raw API?
Aster's fapi/sapi/tapi endpoints are plain REST — the traps are in the semantics:
| Raw API gives you | You would have to build |
|---|---|
| per-market funding intervals that differ (1h to 8h) | correct annualization per symbol — a naive ×24×365 overstates 8h markets by 8× |
| funding cap/floor fields under live vs legacy names | name negotiation with fallback (this gateway reads fundingFeeCap/FundingFeeFloor and degrades honestly) |
| ~580 symbols mixing crypto, TradFi 24/7 perps and spot | chain/asset-class filtering, spot index dislocation ranking, capacity filtering where OI is not published |
| three separate API surfaces (futures/spot/tapi) + Solana | one tool surface with consistent symbol handling and per-field source tags |
Rate limits
Two REST buckets, locally enforced and weight-aware:
- fapi 2400 weight/min, sapi 6000/min (header
X-MBX-USED-WEIGHT-1Mread after every call). Above 80% of a bucket the client self-throttles; 429 backs off honoringRetry-After; a 418 (repeated 429 = IP ban) triggers a 60s refusal cooldown. Depth/kline limits snap to priced tiers so callers cannot accidentally burn weight. - Solana 10 req/min, tapi 30/min, EVM 20/min local budgets (separate ledgers, fail-fast honest errors).
TTL caches: exchangeInfo 3600s, fundingInfo 600s, premiumIndex and tickers 15s, depth 5s, klines 60s, trades 10s, openInterest 30s.
Data notes
- Every numeric from the API is a STRING upstream; parsed with a
never-raising helper -
nullalways means "not available", never zero. - Every upstream failure returns an error dict
{"error", "source", "reason"}, never a traceback. - No OI history exists keyless (
/futures/data/openInterestHist404s) - the gateway says so instead of inventing data. - EVM vault logs need
ASTER_EVM_RPC_URL(or per-chainASTER_EVM_RPC_URL_{BSC,ETH,ARB}); free public RPCs reject vault queries with -32005. Unset -> honest "no RPC configured". - tapi account privacy: most accounts are private; empty results are reported as privacy, not as data.
- Cached responses carry
age_seconds/fetched_atfreshness fields.
Part of the suite
Four sibling read-only MCP gateways, one style — keyless, cached, honest degradation:
| Gateway | Focus |
|---|---|
| dydx-agent-gateway | dYdX v4: verified trader PnL, funding/OI anomaly detectors, leaderboard |
| arcus-agent-gateway | 194 tokenized US equities on Robinhood Chain: quotes, holders, whale transfers |
| hyperliquid-agent-gateway | Hyperliquid: 233 perps + spot, funding carry, account risk, HyperEVM |
| aster-agent-gateway (you are here) | Aster DEX: ~580 futures incl. 24/7 TradFi perps, funding caps/floors |
All four are on glama.ai and PyPI — install any of them with uvx <name>.
License
MIT.
Metadata
Release files for aster-agent-gateway 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aster_agent_gateway-0.1.3.tar.gz | 181.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aster_agent_gateway-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 214.6 kB
Release files / aster_agent_gateway-0.1.3.tar.gz
| Download URL | aster_agent_gateway-0.1.3.tar.gz |
|---|---|
| Size | 181.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2e30d949fe40c503d4421265d958bcb43c749b4eb5392b3fe54aecd3db9836f8
|
|
BLAKE2b-256 checksum How to use checksums |
3c9b46f8d618cab4f640c0d97b666bfeefbc3ba0983a48a3333ee34a68eed656
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency logRelease files / aster_agent_gateway-0.1.3-py3-none-any.whl
| Download URL | aster_agent_gateway-0.1.3-py3-none-any.whl |
|---|---|
| Size | 33.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2ede4efdbd5bd835fb18803aa5fe6781ba80886fcfd409778c09df301e4884fc
|
|
BLAKE2b-256 checksum How to use checksums |
2c22c2e83ea416113ebe0f3e5ba6f4e397e3b73c0a3852cefbab949215093832
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency log