Getting Started with an Agent
KeeperHub exposes workflows, executions, and direct onchain execution as Model Context Protocol tools, so an agent can build and run automations without a browser.
1. Connect
The hosted server is at https://app.keeperhub.com/mcp. In Claude Code:
claude mcp add --transport http --scope user keeperhub https://app.keeperhub.com/mcpRun /mcp to complete OAuth in your browser. That mints a short-lived Bearer access token, which
is the right credential for an interactive agent.
For headless or CI environments where no browser redirect is possible, pass an organization API key instead:
claude mcp add --transport http --scope user keeperhub https://app.keeperhub.com/mcp \
--header "Authorization: Bearer kh_your_key_here"Create that key in the app under your avatar, then API Keys, then the Organisation tab.
Organization keys start with kh_. User keys (wfb_) authenticate webhook triggers and are not
interchangeable. See API Keys.
Confirm the connection by asking your agent to list your workflows.
2. Know the tools you need
The server exposes more than forty tools. Four cover the whole first loop:
| Tool | Does |
|---|---|
list_workflows | Find a workflow and its id |
execute_workflow | Start a run, returns an execution id |
get_execution | Read status, output, and transaction hashes for a run |
ai_generate_workflow | Scaffold a workflow from a plain-language description |
get_execution_status and get_execution_logs still resolve, but both are deprecated aliases of
get_execution. search_plugins is a deprecated alias of list_action_schemas, and get_template
of get_workflow. Prefer the current names.
The full list, including workflow CRUD, templates, integrations, and marketplace listings, is in the MCP Server reference.
3. Run a workflow
Ask the agent to run one. execute_workflow returns an execution id immediately rather than
waiting for the result, then get_execution reads the outcome.
A run reaches one of these terminal states:
| Status | Meaning |
|---|---|
success | Completed |
error | Failed from bad input, workflow logic, or an external dependency |
system_error | Failed inside KeeperHub infrastructure |
cancelled | Stopped before completing |
pending, running, and unconfirmed are non-terminal: keep reading until you see one of the
four above. Treat anything other than success as a failure. Checking only for error misses
system_error and cancelled.
4. Write onchain, safely
For a one-off onchain action with no workflow around it, use the direct execution
tools: execute_transfer, execute_contract_call, execute_check_and_execute, and
execute_protocol_action. The first three take a simulate flag. execute_protocol_action
has no dry run - it executes the action when called and silently ignores a
simulate flag if one is passed (it does not stop the broadcast) - so
treat it as a broadcast and make the call itself the smallest possible step. Where the
protocol exposes a read action (for example a chronicle/eth-usd-read or
morpho/get-position actionType), calling that first returns current state, but it cannot
tell you whether a particular write will revert; there is no substitute for a dry run here.
Know the wallet that signs direct executions. Broadcasts come from your organization’s
Turnkey wallet, not your own. Discover its address over REST with GET /api/user/wallet
(walletAddress for EVM, solanaAddress for Solana) or GET /api/integrations (canonical
EIP-55 checksummed address, preferred when an address must match exactly). Over MCP, call
list_integrations to find the web3 integration, then get_wallet_integration with that
integration’s id - it returns the address as walletAddress. What a direct execution debits
from the wallet is the value a write moves, not the gas: on sponsored chains a relayer pays
the network fee. (A step configured against a Safe spends the Safe’s balance instead.) See
User API and Integrations.
Always preflight the three simulate-capable tools:
- Call the tool with
simulate: true. - Continue only when the result reports
success: trueandwouldRevert: false. - Repeat the call with
simulateomitted, passing a freshidempotency_key. - Poll
get_direct_execution_statuswith the returnedexecutionIduntil it is terminal. Wait the number of seconds in thepollIntervalHintresponse body field (or theX-Poll-Interval-Hintheader on REST) between polls;0means the execution is terminal and you can stop. - Keep
transactionLinkfrom the terminal response as the onchain proof.
execute_protocol_action is not in that loop: it has no simulate step, so call it once with
an idempotency_key. A write action answers 202 with an envelope carrying executionId
and a status of completed, failed, or unconfirmed (plus transactionHash and
transactionLink when the write produced one). Only completed and failed are terminal:
when the status is unconfirmed the transaction is broadcast but not yet confirmed, so poll
get_direct_execution_status with the returned executionId until it is terminal - never
re-send an unconfirmed execution, the transaction may still land. (A read actionType
returns the read value instead, as above.)
Wallet holds USDC but no ETH? Call top_up_gas with chain_id and amount_usdc (up to
the per-call stablecoin cap, 100 USD by default, and 200 USD per organization per day) and an
idempotency_key. It converts USDC
into native ETH on the same wallet through three gas-sponsored transactions and has no dry
run. Read steps in the response: if the swap confirmed but the unwrap did not, the USDC is
already spent and WETH sits in the wallet, so do not call again. See
Gas Top-Up.
Simulation is EVM-only. On Solana mainnet (101) and devnet (103), a simulate: true call
resolves with isError: true rather than throwing. Parse the JSON in content[0].text and stop
when error is simulation_unsupported_chain:
{
"error": "simulation_unsupported_chain",
"message": "Direct-execution simulation is not supported on this chain.",
"chain_id": 101,
"hint": "Direct-execution simulation is EVM-only. Preflight with a Solana-aware client before broadcasting."
}Solana transfers can still broadcast; only the preflight is unavailable.
Per-workflow servers
Any listed marketplace workflow is also reachable as its own typed MCP server at
https://app.keeperhub.com/mcp/w/<slug>, exposing that single workflow with its real input schema
instead of the full toolset. See MCP Server.
Rate limits
| Context | Limit |
|---|---|
| MCP, per organization | 120 requests / minute |
Public MCP tools/call, per IP | 10 requests / minute |
| Direct execution, per API key | 60 requests / minute |
Rate-limited requests return 429 with a Retry-After header in seconds on HTTP transport
responses. Inside MCP tool calls where HTTP headers are not surfaced directly, the wait is
embedded into the error message as (Retry-After: <seconds>s)
(for example API call failed: 429 Too Many Requests (Retry-After: 30s) - ...).
That token appears only when the upstream response carries a Retry-After header, and a 429
whose body carries plan, limit and used is the monthly execution limit, which no amount of
waiting clears.
Wait at least that long, then back off exponentially. Pass a stable idempotency_key on writes
so a retry cannot double-spend.
Next
- MCP Server for the complete tool reference
- Zero to a Verified Onchain Transaction to take a new integration all the way to a transaction you have independently confirmed landed
- Platform Reference for chains, USDC addresses, and faucets
- Claude Code Plugin if Claude Code is your host