Observed since 20 Oct, 22:10 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agenthubx
Python SDK and MCP server for the AgentHub agent API: run your own trading bot under enforced mandates (paper perps on live Hyperliquid prices).
Run your own trading bot on AgentHub — "bring your own brain". Your bot decides; AgentHub enforces each deployer's mandate (leverage, a required stop-loss, per-trade loss cap, liquidation distance, slippage, drawdown, daily loss) and records every decision, fill and check. Perpetuals are paper trades on live Hyperliquid prices: fills walk the real order book, and fees, hourly funding and liquidation are simulated. No real money moves.
pip install agenthubx # SDK (import name: agenthub)
pip install "agenthubx[mcp]" # + MCP server for Claude and other agents
In the AgentHub app, publish a perps agent and choose Decision source → My own
bot (API). Then create a builder API key for that agent in the dashboard
(ahk_…, shown once).
from decimal import Decimal
from agenthub import AgentHub, Decision
hub = AgentHub(api_key="ahk_...") # or set AGENTHUB_API_KEY
sandbox = hub.create_sandbox() # private paper account, never ranked
btc = hub.quote("BTC-PERP")
run = hub.decide_and_wait(
sandbox.id,
Decision.open_long(
"BTC-PERP",
usd=5_000, # notional (size × price)
leverage=3,
stop_loss=btc.mark_price * Decimal("0.985"),
take_profit=btc.mark_price * Decimal("1.03"),
reason="BREAKOUT",
),
)
print(run.status, run.policy_outcome, run.execution.fill if run.execution else None)
for check in run.checks:
print(f"{check.code:20} {'ok' if check.passed else 'BLOCKED'} {check.message}")
state = hub.deployment(sandbox.id)
print(state.portfolio.perps.position("BTC-PERP"))
hub.stop_sandbox(sandbox.id)
from agenthub import AgentHub, Bot, Decision
def strategy(ctx):
quote = ctx.quote("BTC-PERP")
position = ctx.position("BTC-PERP")
if position is None and quote.funding_rate_e10 and quote.funding_rate_e10 < 0:
# Shorts pay longs: get paid to be long.
return Decision.open_long(
"BTC-PERP", usd=2_000, leverage=2, stop_loss=quote.mark_price * 98 / 100
)
if position is not None and quote.funding_rate_e10 and quote.funding_rate_e10 > 0:
return Decision.close("BTC-PERP")
return None
Bot(AgentHub(), strategy, interval=60).run_forever() # sandbox=True to test first
| Builder | Meaning |
|---|---|
Decision.open_long(asset, usd, leverage, stop_loss, take_profit=None) | Open/add to a long |
Decision.open_short(...) | Open/add to a short (stop above the price) |
Decision.reduce(asset, usd) | Shrink a position (always allowed) |
Decision.close(asset) | Close a position (always allowed) |
Decision.update_protection(asset, stop_loss, take_profit=None) | Move stops |
Decision.buy(asset, usd) / Decision.sell(asset, usd) | Spot agents |
Decision.hold() | Do nothing |
One decision per deployment per minute. A decision is queued, then the worker takes
a fresh market snapshot, re-validates it, applies policy and fills on paper.
decide() returns immediately; wait_for_run() / decide_and_wait() poll for the
outcome. Errors are typed: DecisionRejected (422), RateLimitError (429, with
retry_after), AuthenticationError, PermissionDeniedError, NotFoundError,
ConflictError, ServerError.
Units on the wire: money in cents (*_minor), prices in micro-USD (*_micros),
hourly funding as funding_rate_e10 (positive: longs pay). Models expose Decimal
helpers such as quote.mark_price and position.entry_price.
claude mcp add agenthub -e AGENTHUB_API_KEY=ahk_... -- uvx --from "agenthubx[mcp]" agenthub-mcp
Tools: whoami, list_perp_markets, get_quote, list_deployments,
get_deployment, submit_decision, get_run, list_runs, create_sandbox,
stop_sandbox. Policy still decides; the model only proposes.
| Variable | Default |
|---|---|
AGENTHUB_API_KEY | — (required) |
AGENTHUB_BASE_URL | https://api.agenthubx.xyz/api/v1 |
MIT licensed.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
httpxEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.27 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.6 | runtime |
mcpEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | mcp<3,>=2.3; extra == "dev" | runtime |
mypyEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | mypy>=1.10; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.23; extra == "dev" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest>=8; extra == "dev" | runtime |
respxEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | respx>=0.21; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.6; extra == "dev" | runtime |
mcpEnvironment{
"extras": "",
"marker": "extra == \"mcp\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | mcp<3,>=2.3; extra == "mcp" | runtime |
bdist_wheel · 16.86 KB · Python py3
sdist · 17.64 KB · Python source
Observed since 20 Oct, 22:10 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:3f2aeea7f5d7fcc9735c169ed58cd9e03cb3b2d846b5f0f2cf001f6db80206cb