Skip to content

Seven hummingbot-api route groups have no MCP tool; connectors, backtesting and archived-bots are the ones that matter #220

Description

@fengtality

Method

Mapped every client.<router> call in mcp_servers/hummingbot_api/tools/ against the route groups hummingbot-api registers. Seven groups have no MCP tool at all:

archived-bots   backtesting   connectors   docker   scripts   storage   system

Three of those are real gaps. Four look deliberate.


1. connectors (4 routes) — the cheapest fix, and the one I would do first

GET /connectors/
GET /connectors/{connector_name}/trading-rules
GET /connectors/{connector_name}/order-types
GET /connectors/{connector_name}/config-map

/trading-rules returns exactly what an agent needs before sizing an order. Live, from hyperliquid_perpetual:

{"BTC-USD": {"min_order_size": 1e-05, "max_order_size": 1e+56,
             "min_price_increment": 0.1, "min_base_amount_increment": 1e-05,
             "min_notional_size": 10.0, "supports_limit_orders": true, ...}}

Agents currently guess at venue minimums and precision, and find out by failing. min_notional_size is precisely the check that would have caught Token amount is too small to open a position before submitting rather than after.

Four read-only GETs, nothing to gate, no new machinery. Highest value per line of code in this list.

2. backtesting (3 routes) — the most leverage

POST       /backtesting/run
GET POST   /backtesting/tasks
GET DELETE /backtesting/tasks/{task_id}

The dashboard ships a whole BacktestingTab, so this capability exists for a human and not for an agent. An agent designing a controller config today goes straight from "here is a config" to real money, with nothing in between.

The lp_rebalancer sizing incident is the argument: a config that was wrong in three separate ways (total_amount_quote sized at half, position_offset_pct with the wrong sign, position_width_pct read as a half-width) reached a live bot because nothing could exercise it first.

Needs a little design — run returns a task, so the tool has to expose polling rather than block.

3. archived-bots (10 routes) — "how did my last bot actually do" is unanswerable

GET    /archived-bots/
GET    /archived-bots/{db_path}/performance
GET    /archived-bots/{db_path}/executors
GET    /archived-bots/{db_path}/orders
GET    /archived-bots/{db_path}/controllers
DELETE /archived-bots/{db_path}
... +4 more

search_history covers live executors only. Once a bot is stopped and archived, its performance, executors and orders are reachable here and nowhere an agent can see.

Concrete case from today: a bot was deployed, ran, and was stop-and-archived. Reconstructing what it did meant going to docker logs and the raw API by hand. An agent asked the same question has no path at all.

Probably an extension of search_history rather than a new tool.


The four I would leave alone

Listing them so nobody re-derives this later:

  • scripts (5) — v1 script strategies. Condor is controller/executor-based; this is the older path.
  • docker (10) — pull images, clean exited containers, container lifecycle. Operator work, and risky to hand an agent. Gateway's own lifecycle is already covered by manage_gateway_container, which goes through client.gateway, not client.docker.
  • system (1) — /system/resources.
  • storage (1) — single route.

Note on how this was found

Two of these tools already existed and simply were not registered — manage_gateway_config and manage_gateway_container were implemented in tools/gateway.py, given schemas and formatters, imported into server.py as _impl, and never wrapped in @mcp.tool(). An agent that went looking for manage_gateway_config concluded it did not exist. That is fixed separately; this issue is about routes with no implementation at all, so the same audit does not turn them up.

Worth adding a test in the same spirit as tests/test_dangerous_gate_names_resolve.py: assert that every hummingbot-api route group either has an MCP tool or is on an explicit "deliberately not exposed" list, so a new router cannot be added silently and a wrapper cannot go missing again.

Related: #218 (dashboard has no memory surface).

🤖 Generated with Claude Code

https://claude.ai/code/session_0166iQoxKce23GkUwuQJxdkr

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions