Short index (orchestrators, no prose): see repo-root SKILL.md (same GitHub: SKILL.md) for command table, metering HTTP, env, and resource links in one file.
Metering is HTTP-first. The bds-agent commands below are a reference client for bds-agenthub-billing-metering: same GET /credits/plans origin, pay-signup (/signup/pay/quote → pay → /signup/pay/claim), device signup, and POST /credits/topup. You can implement the same flow in any language with fetch / wallet tooling.
This document lives in the bds-agent-py repository so it ships with the CLI and stays valid for anyone who clones this repo alone. It does not reference private workspace-only paths.
| Method | Use case |
|---|---|
uv tool install (recommended) |
From the repo root: uv tool install . — installs bds-agent into uv’s tool environment and places it on your user PATH (similar to pipx). After git pull or when the CLI does not reflect your tree, run uv cache clean then uv tool install --force . (uv often reuses wheels/build cache when the package version is unchanged). After any reinstall, restart the MCP host if you use bds-agent mcp. Optional: uv tool install --force --editable . to load bds_agent from this checkout without rebuilding wheels while you edit. Put uv’s tool bin on PATH (often ~/.local/bin). |
uv run (clone, no global install) |
From a clone: uv sync (uses uv.lock), then uv run bds-agent …. The CLI is not on your user PATH unless you prefix with uv run from the repo root (or a shell that has activated uv’s project env — not required). |
uv tool + MCP still stale: Confirm which -a bds-agent — the first hit should be uv’s shim (e.g. ~/.local/bin), not an older venv. Then uv cache clean, uv tool install --force ., and restart Cursor / Claude / the MCP connection.
Examples in this guide use plain bds-agent (after uv tool install). If you only use uv run from a clone, prefix commands accordingly (e.g. uv run bds-agent signup).
- Metering service running and reachable. It must expose
GET /credits/plans, device signup (/signup/...+ verify), pay-signup (/signup/pay/quote,/signup/pay/claim), andPOST /credits/topup, with EVM (and optional Tempo) verification configured:PAYMENT_CHAINS_JSON, treasuries, RPC, chain, seededcredit_plansas needed. See the bds-agenthub-billing-metering README. - Signup URL (before
bds-agent signup): the CLI uses the metering service origin (same host as signup APIs and credits:GET /credits/plans,POST /signup/initiate,POST /credits/topup). Default (Powerloom production):https://bds-metering.powerloom.io— override withBDS_AGENT_SIGNUP_URLorbds-agent signup --base-url …if you use a different deploy (e.g.http://127.0.0.1:8787self‑hosted). Browser signup and billing UI (Next static export) live on the same host at/metering— e.g.https://bds-metering.powerloom.io/metering. The URL used is saved assignup_base_urlinprofiles/<profile>.jsonfor latercreditscommands (it is not the same asbds_base_url/ snapshotter node; set those separately, e.g.bds-agent config initafter signup). - On-chain payment: a wallet funded on the same chain and token (or native gas token for
payment_kind: native_valueplans) as the chosenGET /credits/plansrow. See the metering README forPAYMENT_CHAINS_JSONand plan rows.
All paths use one origin (default https://bds-metering.powerloom.io). Override with BDS_AGENT_SIGNUP_URL or bds-agent signup --base-url ….
| Step | Method & path | Auth | Purpose |
|---|---|---|---|
| Discover SKUs | GET /credits/plans |
None | plans[]: id, chain_id, token_symbol, payment_kind (erc20 or native_value), prices; chains[] for RPC/recipient. |
| Pay-signup: quote | POST /signup/pay/quote |
None | JSON: agent_name, plan_id, chain_id, token_symbol, payer_address (0x), optional email. Returns signup_nonce, recipient, amount_atomic, token_contract or native instructions, rpc_hint, expires_at. |
| Pay-signup: pay | (chain) | — | ERC-20: Transfer to recipient for amount_atomic. Native / CGT: send tx.value per quote. |
| Pay-signup: claim | POST /signup/pay/claim |
None | JSON: signup_nonce, tx_hash. Returns api_key (sk_live_…). |
| Device signup | POST /signup/initiate → browser POST /verify → GET /signup/status |
Session token / poll | Human-in-the-loop; see below. |
| Balance / usage | GET /credits/balance, GET /credits/usage |
Authorization: Bearer <api_key> |
Rate limits and balance. |
| Top-up | POST /credits/topup |
Bearer + body with plan + tx hash |
After you already have a key; different from pay-signup. |
bds-agent credits plans = same JSON as GET /credits/plans (CLI pretty-print). bds-agent signup-pay = wraps quote → sign+broadcast → claim. bds-agent credits topup = builds/pays a top-up (not a new signup). Full request bodies and errors are in the bds-agenthub-billing-metering repo and its README.
No browser. You do not need signup (device flow) or an existing key—only a funded EVM wallet on the plan’s chain.
HTTP (any client): follow the table above: GET /credits/plans → pick id, chain_id, token_symbol → POST /signup/pay/quote with your wallet as payer_address → pay on-chain (ERC-20 or native per payment_kind in the quote) → POST /signup/pay/claim with signup_nonce and tx_hash. Store the returned api_key in your profile or env.
bds-agent (same steps, interactive):
-
Preview plans (no key):
bds-agent credits plans
-
Save a wallet for the profile (creates
~/.config/bds-agent/profiles/<profile>.evm.envwithEVM_PRIVATE_KEY,EVM_RPC_URL,EVM_CHAIN_ID):bds-agent credits setup-evm # or: --profile <name> / BDS_AGENT_PROFILE=... -
Pay and claim an API key (quote → pay → claim on the server):
bds-agent signup-pay --plan-id <id> --chain-id <eip155> --token-symbol <SYMBOL>
Use
--plan-id,--chain-id, and--token-symbolfrom the plans table. The CLI dispatches ERC-20transferor a native send depending on the quote’spayment_kind. Re-sync the CLI aftergit pull:uv sync(clone) oruv tool install --force .(global) — install table. -
Confirm balance:
bds-agent credits balance
Duplicate / binding: the quote binds payer_address; the on-chain from must match. If email is set on the quote, it must not already be taken.
When: you want email + human verification in a browser instead of pay-first.
First step: set the metering base URL, then run signup.
Production (typical):
export BDS_AGENT_SIGNUP_URL=https://bds-metering.powerloom.io
bds-agent signupSame thing via flag (no env): bds-agent signup --base-url https://bds-metering.powerloom.io
Local / self-hosted: use your billing origin instead, e.g. export BDS_AGENT_SIGNUP_URL=http://127.0.0.1:8787 or the matching --base-url.
- Enter email and agent name when prompted.
- Open the verification URL in a browser, enter the user code, complete captcha/TOS if required.
- While you verify, the CLI polls
GET /signup/statusabout every 5 seconds (gentle on metering rate limits). Transient502/503/504responses are retried with backoff (origin nginx may use 503 throttling by default;429means “slow down” and is handled the same way). - When the CLI resumes, choose a profile name (default is derived from the agent name).
Files created:~/.config/bds-agent/profiles/<profile>.json— API key, org id, metering base URL~/.config/bds-agent/active_profile— so later commands know which profile is active
Duplicate email: if this email already has an active API key on the server, POST /signup/initiate returns 409 — use your existing profile or contact support.
bds-agent credits balance
# or: bds-agent credits balance --profile <profile>
bds-agent credits plans # no API key requiredHTTP: with Authorization: Bearer, POST /credits/topup with a completed on-chain purchase for a plan (tx hash for verification on the service). Not the same as pay-signup (no new org/key).
bds-agent: use the same EVM wallet as pay-signup / multi-chain top-up:
bds-agent credits setup-evm --profile <profile> # if not already
bds-agent credits topup --profile <profile>The CLI selects a plan, submits the payment, then registers the tx with the metering service. On success, balance increases. Repeat for another purchase.
Node-only (no Python): the powerloom-bds-univ3 skill repo includes scripts/credits-topup.mjs: it calls GET /credits/plans, matches PLAN_ID / CHAIN_ID / TOKEN_SYMBOL, broadcasts ERC-20 or native per the plan, then POST /credits/topup with your existing POWERLOOM_API_KEY.
Some deployments still document pathUSD on Moderato (42431) and a Tempo-specific charge path. If credits topup on your service expects Tempo credentials (see GET /credits/plans and operator docs), configure the per-profile Tempo file:
bds-agent credits setup-tempo --profile <profile>File: ~/.config/bds-agent/profiles/<profile>.tempo.env — used only to pay for credits; /mpp/... data requests use the API key only. Enter private key; TEMPO_RPC_URL and TEMPO_CHAIN_ID default from GET /credits/plans when reachable. Fund with the plan’s token on the correct chain, then:
bds-agent credits topup --profile <profile>Powerloom production commonly uses the EVM path (setup-evm) and native_value or ERC-20 rows from GET /credits/plans, not Tempo, for top-up—use §4. Buy more credits: EVM top-up above unless your operator points you at Tempo.
bds-agent credits balance --profile <profile>| Mechanism | Effect |
|---|---|
active_profile file |
Default profile when you omit --profile |
--profile / -P on bds-agent or bds-agent credits … |
Override for that invocation |
BDS_AGENT_PROFILE |
Same as --profile when set in the environment |
Instead of exporting many variables in every shell, store optional fields on the same profile file as your API key: ~/.config/bds-agent/profiles/<name>.json.
| Profile field | Same meaning as env |
|---|---|
bds_base_url |
BDS_BASE_URL — snapshotter full node origin (no trailing slash). |
bds_api_endpoints_catalog_json |
BDS_API_ENDPOINTS_CATALOG_JSON — local path or HTTPS URL to endpoints.json (e.g. raw GitHub). |
bds_sources_json |
BDS_SOURCES_JSON — path to sources.json. |
bds_market_name |
BDS_MARKET_NAME — data market name when using sources.json. |
powerloom_rpc_url |
POWERLOOM_RPC_URL — Powerloom chain JSON-RPC for bds-agent run on-chain CID verification (verify: true). |
powerloom_protocol_state |
POWERLOOM_PROTOCOL_STATE — optional ProtocolState address (eth_call to) for bds-agent run verification. |
powerloom_data_market |
POWERLOOM_DATA_MARKET — optional DataMarket contract address (first argument to maxSnapshotsCid on ProtocolState). |
Precedence (each setting): non-empty environment variable wins; otherwise the profile value is used. This applies to agent.yaml ${VAR} interpolation (e.g. ${BDS_BASE_URL}) and to bds_agent.catalog.resolve_catalog().
When agent.yaml sets verify: true, the runner checks each event’s verification block against ProtocolState.maxSnapshotsCid(dataMarket, projectId, epochId) (the call is executed on ProtocolState and uses your DataMarket address as the first argument — see docs/AGENT_YAML.md → Verification). Configure JSON-RPC via verify_rpc_url, POWERLOOM_RPC_URL, or profile powerloom_rpc_url. Optional overrides: ProtocolState — verify_protocol_state, POWERLOOM_PROTOCOL_STATE, powerloom_protocol_state; DataMarket — verify_data_market, POWERLOOM_DATA_MARKET, powerloom_data_market. If unset, the stream’s verification.protocolState and verification.dataMarket are used. Mismatch triggers a console warning and an alert with rule: verification to your sinks.
CLI helpers
| Command | Purpose |
|---|---|
bds-agent config init |
First-time setup: writes bds_base_url, bds_api_endpoints_catalog_json, and Powerloom verification defaults on the profile — powerloom_rpc_url (https://rpc-v2.powerloom.network/), powerloom_protocol_state, powerloom_data_market (BDS mainnet alpha Uniswap V3 ETH deployment; same roles as POWERLOOM_RPC_URL / POWERLOOM_PROTOCOL_STATE / POWERLOOM_DATA_MARKET). Skips any key that is already set; use --force to replace all of these with the packaged defaults. |
bds-agent config show |
Print stored BDS fields and the effective env overlay for the active profile. |
bds-agent config set <field> <value> |
Set one optional field (see table above). |
bds-agent config unset <field> |
Remove a field from the profile JSON. |
Use --profile / BDS_AGENT_PROFILE with these commands to edit a specific profile file.
The agent runtime loads a language-agnostic JSON catalog of BDS HTTP routes (paths, methods, params, metering flags). It is authored next to api/router.py in the snapshotter-computes repo as api/endpoints.json and is the single source of truth for bds-agent run (validate source.endpoint), bds-agent query, bds-agent mcp, and bds-agent create (bds_agent.catalog.resolve_catalog).
Either export env vars or use bds-agent config set … (writes the profile JSON). CI and one-off runs often keep using env vars to override a developer profile.
| Variable | Purpose |
|---|---|
BDS_API_ENDPOINTS_CATALOG_JSON |
Local filesystem path or HTTPS URL to endpoints.json (the loader fetches JSON from URLs). Use a path for air-gapped use; a raw GitHub URL matches the compute branch catalog without cloning. |
BDS_SOURCES_JSON |
Path to curated-datamarkets/sources.json (or a copy). The loader selects a data market, reads compute.commit, and fetches api/endpoints.json from raw GitHub at that commit. |
BDS_MARKET_NAME |
Which dataMarkets[].name to use with BDS_SOURCES_JSON (default BDS_MAINNET_UNISWAPV3). |
GITHUB_TOKEN / GH_TOKEN |
Optional. Passed to raw GitHub requests if the repo or file requires authentication. |
Resolution order (first match wins): explicit endpoints_path= / sources_path= in code → BDS_API_ENDPOINTS_CATALOG_JSON (env, else profile bds_api_endpoints_catalog_json) → BDS_SOURCES_JSON (env, else profile bds_sources_json). Market name: argument → BDS_MARKET_NAME env → profile bds_market_name → default. If nothing matches, the loader raises an error listing these options.
Cache: Successful fetches are written under ~/.config/bds-agent/cache/endpoints_<commit>.json so repeated runs do not hit the network every time.
Signup and credits commands do not load this catalog today; you only need these variables when using features that validate or enumerate BDS routes.
endpoints.json can list more routes than you want query, MCP, or run to use. By default the CLI restricts the catalog to paths under /mpp (same rule for agent.yaml source.endpoint when you run an agent).
| Variable | Purpose |
|---|---|
BDS_AGENT_CATALOG_PATH_PREFIXES |
Comma-separated path prefixes for that filtered view. Unset → /mpp only. all → use every route in the loaded catalog. |
How non-/mpp HTTP routes are exposed and authenticated is up to the snapshotter / API deployment — not configured here.
Used by bds-agent query and bds-agent create. Configuration is agent-wide (not per BDS profile): ~/.config/bds-agent/llm.json.
| Mechanism | Effect |
|---|---|
--backend / -b on a command that supports it |
Highest precedence (when wired). |
BDS_AGENT_LLM_BACKEND |
e.g. anthropic, openai, ollama. |
llm.json "backend" field |
Written by bds-agent llm use …. |
| Auto-detect | If nothing is set: prefers ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN, then OPENAI_API_KEY, then a reachable local Ollama (/api/tags). Otherwise configure explicitly. |
Scope (current): The anthropic backend implements only the Anthropic Messages API — POST …/v1/messages, anthropic-version header, x-api-key, response content blocks. It is not the OpenAI Chat Completions API; use backend openai or ollama for those protocols.
The client sends the base URL as the origin only (it appends /v1/messages).
| Variable | Purpose |
|---|---|
ANTHROPIC_API_KEY |
API secret (x-api-key). |
ANTHROPIC_AUTH_TOKEN |
Same role as ANTHROPIC_API_KEY if your environment uses this name instead (either one may be set). |
ANTHROPIC_BASE_URL |
API origin (default https://api.anthropic.com). |
ANTHROPIC_MODEL |
Model id (see Anthropic model names in their docs). |
Interactive setup: bds-agent llm setup anthropic (writes llm.json; file mode 0600 where supported).
Smoke test: bds-agent llm ping (sends a minimal completion).
| Variable | Purpose |
|---|---|
OPENAI_API_KEY |
Bearer token for POST …/chat/completions. |
OPENAI_BASE_URL |
Default https://api.openai.com/v1. |
OPENAI_MODEL |
Model id. |
Used by bds-agent query, bds-agent create, and bds-agent llm ping when BDS_AGENT_LLM_BACKEND=ollama, llm.json has "backend": "ollama", or auto-detect finds a running Ollama (and no API keys take precedence). If you also have ANTHROPIC_API_KEY / OPENAI_API_KEY, set BDS_AGENT_LLM_BACKEND=ollama or run bds-agent llm use ollama so the local model is chosen.
| Variable | Purpose |
|---|---|
OLLAMA_HOST |
Host or full URL (default 127.0.0.1:11434). |
OLLAMA_MODEL |
Tag name on the server. |
OLLAMA_NUM_CTX |
Optional context size (passed as Ollama options.num_ctx). Use when query / create prompts exceed the default window (large endpoints.json catalog). |
| Command | Purpose |
|---|---|
bds-agent llm status |
Show config path, effective backend, env hints. |
bds-agent llm list |
Which backends look configured. |
bds-agent llm use <backend> |
Set active backend in llm.json. |
bds-agent llm setup anthropic |
Prompt for base URL, model, API key. The base URL prompt defaults to https://api.anthropic.com (not any prior custom origin in llm.json; a note is printed if those differ). |
bds-agent llm setup openai |
Prompt for OpenAI-compatible endpoint. |
bds-agent llm setup ollama |
Prompt for host and model name. |
bds-agent llm ping |
One completion to verify connectivity. |
Maps a plain-English question to one route from endpoints.json plus path/query parameters using the shared LLM (bds_agent.llm). Output is JSON on stdout: path, sse, arguments, optional rationale.
Requirements
| Requirement | Notes |
|---|---|
| Catalog | Same as run / mcp: BDS_API_ENDPOINTS_CATALOG_JSON or BDS_SOURCES_JSON (+ optional BDS_MARKET_NAME) or profile fields (config init). |
| LLM | bds-agent llm setup … / env keys (ANTHROPIC_API_KEY, etc.) or --backend. |
Flags
| Flag | Purpose |
|---|---|
--backend / -b |
LLM backend name. Optional if bds-agent llm use … or llm.json already set it — only pass to override one command. Same precedence as BDS_AGENT_LLM_BACKEND. |
--execute / -x |
After resolving, call the BDS API (Bearer + metering). Requires profile API key and BDS_BASE_URL (or --base-url / profile bds_base_url). Metered routes consume credits. |
--profile / -P |
Profile for --execute (and for consistency with other commands). |
Examples
bds-agent query "all trades snapshot for epoch block 12345678"
bds-agent query "stream all trades" --backend anthropic
bds-agent query "latest all-pool trades per finalized epoch" -x --base-url https://bds.powerloom.io/apiThe model only chooses among filtered catalog paths (default /mpp — see Catalog path filter above). It must return a path that exactly matches a catalog entry (including {placeholders}). SSE routes default max_events to 5 if omitted. This command does not use MCP; it uses the same filtered catalog and HTTP stack as bds-agent mcp tools.
Turns a natural-language agent description into a validated agent.yaml using the same LLM stack as bds-agent query (bds_agent.create: JSON Schema from AgentConfig, rule/sink summaries, endpoints.json excerpt). Output is written to disk; then run it with bds-agent run.
Requirements
| Requirement | Notes |
|---|---|
| Catalog | Same as query / run / mcp: BDS_API_ENDPOINTS_CATALOG_JSON or BDS_SOURCES_JSON (+ optional BDS_MARKET_NAME) or profile fields. |
| LLM | bds-agent llm setup …, env keys, or --backend. |
Flags
| Flag | Purpose |
|---|---|
--backend / -b |
LLM backend name. Optional if bds-agent llm use … or llm.json already set it — only pass to override one command. Same precedence as BDS_AGENT_LLM_BACKEND. |
--output / -o |
Write to this file path. Default: ./gen-yaml/<name>.yaml (directory auto-created; gitignored by default so generated configs don't clutter the repo). |
Examples
bds-agent create "Alert me on stdout when any Uniswap swap exceeds $50k USD"
bds-agent create "Slack webhook alerts for volume spikes on all pools" --backend openai -o ./my-agent.yamlNote: This command does not invoke MCP; it only shares the catalog and LLM backends with mcp and query.
- Catalog + BDS origin + profile — same as
bds-agent query/mcp(e.g.bds-agent config init, orBDS_BASE_URL+BDS_API_ENDPOINTS_CATALOG_JSON/BDS_SOURCES_JSON). bds-agent create "…"— writes./gen-yaml/<name>.yaml(or-opath).bds-agent run <file>.yaml --profile NAME— loadsagent.yaml, opens an SSE client tosource.endpointonsource.base_urlwhensource.typeisbds_stream, runs rules on each epoch payload, delivers alerts to sinks.
Typical NL-generated DEX agents use bds_stream + /mpp/stream/allTrades and stdout or webhooks. Rule parameters (min_usd.threshold, etc.) accept plain numbers or strings like 50k; see docs/RULES.md.
The stream is not free: it is /mpp/..., which is metered on deployments that use Bearer API keys and signup billing (MPP_BILLING_MODE=signup_api on the snapshotter). The core API middleware deducts once when the SSE request is accepted (per connection), not per data: line in the SSE body.
Credit policy (product): 1 credit per stream open is priced at parity with 720 successful GET /mpp/snapshot/... calls (1/720 credit each); the stream session is intended to deliver up to 720 epochs of events for that credit. Implementation: the metering service backing your deployment debits from the API key’s balance when the snapshotter accepts the request (one debit per stream connection, not per SSE event). How path maps to debit size is deployment-specific. Resuming a partially delivered entitlement (e.g. after disconnect) without paying again is not implemented in this CLI—it depends on server and metering behavior. The bds-agent client surfaces X-BDS-Credit-Balance when the server returns it.
If you need cost to scale linearly with every epoch and no bundled “session,” use GET /mpp/snapshot/allTrades/{epoch} per epoch instead of the long-lived stream. On snapshotter deployments that bill via Tempo / pympp (MPP_BILLING_MODE=tempo), snapshot routes use MPP_CHARGE_AMOUNT and /mpp/stream/... uses MPP_STREAM_AMOUNT—configure with your operator.
Runs a Model Context Protocol server on stdio (for Cursor, Claude Desktop, Claude Code CLI, and other MCP clients). Tools are generated from the same endpoints.json catalog as bds-agent run (see API endpoint catalog above). Each catalog route becomes one MCP tool; GET snapshot routes use fetch, SSE routes return a bounded list of events ( max_events, default 5, max 50).
Requirements
| Requirement | Notes |
|---|---|
| Profile + API key | Same Authorization: Bearer as bds-agent run (--profile / BDS_AGENT_PROFILE / active_profile). |
BDS_BASE_URL |
Snapshotter full node origin (or --base-url). Same as source.base_url in agent.yaml. |
| Catalog env | BDS_API_ENDPOINTS_CATALOG_JSON or BDS_SOURCES_JSON (+ optional BDS_MARKET_NAME) — same resolution as bds_agent.catalog.resolve_catalog. |
Important: Do not print to stdout from wrappers around this command — stdout is reserved for MCP JSON-RPC. The CLI logs warnings to stderr only.
This server uses stdio only. The MCP client does not connect to a URL; it starts bds-agent mcp as a subprocess. There is no separate “deploy the MCP server” step beyond installing the CLI and configuring the client.
Before you wire the client
- Complete pay-signup (§1) or device
signup(§2) so the profile has anapi_key. - Point the profile at BDS + catalog:
bds-agent config init(recommended) or setBDS_BASE_URLandBDS_API_ENDPOINTS_CATALOG_JSON/BDS_SOURCES_JSON— same asbds-agent run(see API endpoint catalog and Profiles and flags above). - Optional sanity check:
bds-agent config showand confirmbds_base_urland catalog fields (or env overlay).
Client configuration
- Set
command(andargs) so the child process runsbds-agent mcp. Preferbds-agentonPATH(afteruv tool install .). If you only have a clone, useuvwithargs:["run", "bds-agent", "mcp"]andcwdset to thebds-agent-pyrepository root (wherepyproject.tomllives). - Pass
env:- Minimal:
BDS_AGENT_PROFILE=<profile>ifconfig init(or manualconfig set) already storedbds_base_urland catalog URLs on that profile. - Explicit:
BDS_BASE_URL,BDS_API_ENDPOINTS_CATALOG_JSON(path or HTTPS URL) orBDS_SOURCES_JSON+BDS_MARKET_NAME, plusBDS_AGENT_PROFILEas needed.
- Minimal:
Where to edit config
-
Cursor: MCP settings (project or user) — add a server that runs the command above; restart the app after changes.
-
Claude Desktop (macOS):
~/Library/Application Support/Claude/claude_desktop_config.json—mcpServersentry withcommand,args,env; restart Claude Desktop. -
Claude Code CLI: register a local MCP with
claude mcp add— the name you choose appears in/mcp(e.g. connected + tool count). Run from a directory where env is correct, or rely on profile +config initas above.Recommended if
bds-agentis onPATH(e.g. afteruv tool install .— see Install the CLI above; useuv cache clean+uv tool install --force .when updating from a clone):claude mcp add bds-agent-local -- bds-agent mcp
bds-agent-localis only a display label; use any name you like.Without a global
bds-agent, run throughuvfrom the repo (absoluteuvpath if shims are not visible to the Claude Code process), withcwd= repo root:claude mcp add bds-agent -- /path/to/uv run bds-agent mcp
uv runresolves the project fromcwd; setcwdto the checkout that containspyproject.toml, or install withuv tool install .once and usebds-agent mcponly.The project may store MCP entries in
.claude.json(paths are project-scoped in the UI). After adding,/mcpshould list the server as connected and expose one tool per filtered catalog route (see Catalog path filter above).
What “success” looks like
- The client lists MCP tools whose names start with
bds_(one tool per filtered catalog route). Names are derived from the path template: path parameters are folded in (e.g.bds_mpp_ethPricevsbds_mpp_ethPrice_block_number) so variants do not collapse to duplicatebds_*/bds_*_2pairs. - Calling a GET tool returns JSON from BDS or a documented HTTP error (e.g. 402 if credits are exhausted).
- SSE tools accept
max_events(1–50) and return a bounded list of stream events.
If tools do not appear, verify catalog resolution and profile/env. If the client cannot start the server, verify command/cwd, and ensure nothing writes to stdout except the MCP process itself.
Use the API key from your profile (see Profiles and flags above) for Authorization: Bearer.
BDS_BASE_URL is the HTTP origin (no trailing slash) of the snapshotter full node you call: the service that exposes the protocol resolver (timeseries / snapshot primitives) and mounts compute-module routers (FastAPI) for market-specific routes such as metered /mpp/.... Use the same origin as source.base_url in agent.yaml.
| API | Behavior |
|---|---|
stream(...) |
Long-lived SSE to /mpp/stream/...; StreamChunk.credit_balance when the server sends X-BDS-Credit-Balance. With signup-api billing, credits are deducted when the stream request is allowed (see Metering and SSE above). |
fetch(...) |
Single GET (e.g. /mpp/snapshot/...); FetchResult.credit_balance and FetchResult.data; non-2xx responses (including 402) raise BdsClientError. |
stream reconnects: after an error, waits reconnect_delay and retries (max_reconnects, default 0 = unlimited). After a normal end of the SSE body, failures are reset and the next connection starts without that delay.
If the metering server has DEV_TOPUP_SECRET set:
bds-agent credits topup --amount 5 --dev-secret <secret>--amount is in credit units, not token amount.
| Issue | What to check |
|---|---|
| No credentials | Run pay-signup (§1) or device signup (§2); ensure profiles/<profile>.json exists and active_profile or --profile |
| Pay-signup / quote fails | plan_id + chain_id + token_symbol must match one GET /credits/plans row; payer_address must match the tx from |
signup-pay on-chain reverts |
Wallet funded on correct chain; native vs ERC-20 per quote payment_kind |
| Tempo top-up fails | MPP_TEMPO_RECIPIENT on metering; wallet funded; credits plans matches chain/token |
--profile not recognized |
Use bds-agent credits --profile NAME balance or bds-agent credits balance --profile NAME (both supported) |
| MCP tools empty / server exits | Catalog not resolved — set BDS_API_ENDPOINTS_CATALOG_JSON or BDS_SOURCES_JSON; ensure BDS_BASE_URL and a valid API key profile |