Agent Connect

Developer Resources

MCP Tools

List accounts, read their rules, request transactions, and check the results.

On This Page

Model Context Protocol (MCP) lets your client use Agent Connect tools. Every agent uses the same MCP URL, shown in the app under Connect your agent and on the dashboard’s Connect MCP Client page. The credential decides which agent the client reaches, and the endpoint routes requests to accounts the client can access, using each account’s name. See Connect Your Agent to add the URL to your client.

Discover Accounts First

Call get_accounts, then pass the exact returned name in the account argument of later calls.

Omitting account selects the first enabled account. Use an explicit name to keep the target consistent.

Read Tools

ToolPurpose
get_accountsList accounts the client can access, with each one’s NEAR, EVM and Solana addresses.
get_agentRead the selected account’s agent information.
get_authorization_statusCheck account access.
get_balancesRead the account’s confidential balance and what is available to send.
get_tokensDiscover token identifiers and metadata.
get_policyRead the saved account policy and its USD budget usage.
get_network_statusRead the Agent API's dependency status: one_click, custody and near.
swap_quoteRequest a swap quote.
withdraw_previewPreview a withdrawal.
get_deposit_statusCheck a deposit's status by its correlation_id. Any other operation's id is refused with operation_not_found.
get_operation, refresh_operationRead an existing operation, or ask the API to re-observe it now.
get_historyRead the account's own history: withdrawals, swaps, transfers, deposits, native signatures and the owner's signed changes (policy updates, freezes, grants and more). A grant record shows only the grant's id, label and times. Each entry carries the description the agent gave. A deposit address nothing was paid into (still waiting, expired or cancelled) is not listed; read it with get_deposit_status.
get_auditRead the provider's audit trail.
list_approvals, get_approvalRead pending approval requests and decisions.
get_policy_proposalRead a policy change this agent proposed.
send_feedbackTell the Agent Connect team what failed, confused or worked. Once per day.

For get_balances, use source: confidential. Public balance reads are unavailable.

Each balance entry has balance_raw and available_raw (with balance and available in whole units). available_raw is the balance less the amount of queued, timelocked or awaiting-approval work that has not left yet, counted by the API. Use it for Max. The tools do no balance arithmetic of their own: a request above what is available is refused by the API with insufficient_balance, whose available_amount (atomic units) is the most you can send.

An Agent API refusal passes through what the API said beside its code: layer, detail, source (the field it is about) and, for amount_too_low, min_amount, the route minimum in atomic units of the asset sent. Every tool error also carries layer and a one-sentence next_step:

layernext_step
policyDo not retry. Ask the owner to change the rules (propose_policy_change); for a schedule refusal, retry with the same idempotency_key at available_at.
budgetDo not retry. Ask the owner to raise the USD budget, or wait for the period to reset.
balanceSend at most available_amount, or ask the owner to fund the account.
providerRetryable: send the same request again later with the same idempotency_key. Otherwise change the amount or pair; repeating will not help.
requestFix what detail and source.pointer name, then send it again.
grant, authAsk the owner to reconnect or sign again.
apiRetry shortly with the same idempotency_key.
{ "error": { "code": "insufficient_balance", "layer": "balance", "available_amount": "400000", "next_step": "…" } }

A swap, withdrawal or transfer that the budget or a limit refuses on a request that runs now creates no operation: there is nothing to poll, no FAILED status and no charge. A timelocked request is judged again when it is dispatched and can fail then. A FAILED operation whose failure_code is insufficient_balance does not release its charge: only the provider's own details.never_executed or details.never_submitted proves nothing was spent.

Budget, Previews and Fees

The USD budget caps spending per day, week and month, each counted from when the owner turned that cap on (a monthly cap repeats on the same date and time each month, UTC). Each window's resets_at is when its current period ends and the whole cap is available again. A window without a cap has no period, so its limit_usd, spent_usd, remaining_usd and resets_at are all null. Swaps (by input value), withdrawals and transfers count. Deposits back in do not credit the budget. get_policy shows the usage.

withdraw_preview and swap_quote are not refused for anything the real request would be refused for: neither the account's rules (the action switch, destination, schedule, per-asset limits, actions per hour and the USD budget) nor the request's own balance check. A token get_tokens does not list (unsupported_token) or an invalid recipient address (invalid_address) is refused as the real request is, before the provider is asked, and does not count toward the custody quota. Otherwise a preview goes to the provider and returns the quote. Each rule or balance check the real request would fail is listed in warnings, under the error code the real request would get. A frozen, archived or deleted account gets no preview: both tools are refused with wallet_frozen, agent_archived or agent_deleted, without counting toward the custody quota. The API sets no preview cap of its own: every withdraw_preview that reaches the provider counts as one of the wallet's 1,000 custody operations per rolling 24 hours, rule warning or not. Swaps, withdrawals, transfers, confidential moves and calls count too; swap quotes do not. Over the quota the API refuses with provider_limit_reached and meta.available_at when it is known. A preview returns:

FieldMeaning
spendamount_usd of the request and the account budget, with remaining_usd per window.
feeamount_usd and percent, or null when no fee is known. On chain near a withdrawal's fee is the provider's estimate when it is stated in the withdrawn asset, otherwise amount minus quote.amount_out. A bridged withdrawal's fee is null: quote.amount_out is in the destination chain's asset, so compare it with amount using that listing's decimals from get_tokens.
warningshigh_fee when the fee is above 5%, judged only where fee is valued, so a bridged withdrawal never gets it and its absence says nothing about the cost. asset_delivered_as_is when a non-USDC asset is withdrawn to hypercore. A refusal code when the real request would be refused with it: policy_action_denied, policy_destination_denied, policy_schedule_denied (with available_at), spend_price_unavailable, spend_budget_exceeded, policy_transaction_limit_exceeded, policy_limit_exceeded, policy_action_limit_exceeded or insufficient_balance (with available_amount).

Read warnings before you submit. If a refusal code is there, the real request will be refused with it. Tell the user, reduce the amount (insufficient_balance names available_amount), wait for resets_at or available_at, or ask the owner to change the account rules. A preview without such a warning is a snapshot, not a guarantee. A concurrent request can still use the budget first, and a request held by a timelock is charged when it is dispatched.

Hyperliquid (HyperCore)

Withdrawing USDC to chain hypercore credits the Hyperliquid account directly. Any other asset arrives as that asset in HyperCore spot, not as USDC perps margin, and the preview warns with asset_delivered_as_is. Swap to USDC first when the goal is perps margin.

Operations That Change Funds

ToolPurpose
swapExchange supported assets.
withdrawWithdraw through a supported external route.
confidential_transferTransfer confidential funds to a NEAR Intents account.
create_cross_chain_depositCreate a supported cross-chain deposit route. The returned address is single-use: it takes one deposit. A second send to it is not credited or refunded and may be lost, so create a new deposit for each transfer. The response carries deposit.single_use: true.

Swaps, withdrawals, and cross-chain deposits use confidential: true; omitted values default to true. Public execution is unavailable. There are no balance-conversion tools.

NEAR (nep141:wrap.near) withdrawn to chain near arrives as native NEAR, like a NEAR wallet: the recipient needs no wrap.near registration. There is no option to withdraw wNEAR. A near.com nearcom: address is not on any chain, so withdraw and withdraw_preview refuse it; send to it with confidential_transfer.

Operations depend on authorization, policy, balance, and provider support.

A transfer's to is a NEAR Intents account: a named account, a 64-hex implicit account or a 0x address. A near.com address such as nearcom:example.near works too; the nearcom: prefix is stripped. Use confidential_transfer to send to its confidential balance.

Native Account Tools

Each agent account also has its own NEAR account, one EVM address for every EVM chain, and a Solana address outside NEAR Intents. get_accounts and get_agent return them as near_account_id, evm_account_id, and solana_account_id.

These are not deposit addresses. Funds sent to them stay on that chain and never reach the account's balance. To add funds, use create_cross_chain_deposit (or Add funds in the dashboard). Both tools return an addresses_notice that tells the agent this. Fund a native address only for native use: for example, withdraw native USDC on Polygon to evm_account_id before the agent signs Polymarket orders.

These tools use those keys:

ToolPurposePolicy switch
near_sign_messageSign a NEP-413 message (site login) with the agent's NEAR key. The service supplies the message, recipient and 32-byte nonce.native.near.sign_message lists the recipient (account or domain)
near_transferSend native NEAR from the agent's NEAR account.native.near.transfer
near_callCall a NEAR contract from the agent's NEAR account.native.near.call lists the contract
evm_sign_typed_dataSign EIP-712 typed data.native.evm.sign_typed_data lists the domain
evm_sign_messageSign an EIP-191 personal message.native.evm.sign_message
evm_sign_transactionSign an EVM transaction.native.evm.sign_transaction
solana_sign_messageSign an off-chain Solana message.native.solana.sign_message
solana_sign_transactionSign a Solana transaction.native.solana.sign_transaction

Every native tool is off until the owner switches it on in the account policy; otherwise it returns native_method_denied (signing_policy_denied for near_sign_message). A typed-data domain in native.evm.sign_typed_data can also restrict primary_types (for example only HyperliquidTransaction:Withdraw); a type outside that list is refused with native_method_denied. Each signature is recorded in the account history as type native; a typed-data record also carries the matched domain and the signed message (message_json). Most money rules do not apply to them: the USD budget, timelocks, the schedule and human review are skipped. NEAR that near_transfer sends, or near_call attaches as its deposit, must land where the account's destinations allow, or it is refused with policy_destination_denied; the policy's asset limits on nep141:wrap.near still apply. A near_call can still move anything the contract holds for the agent, and a typed-data signature or signed transaction can move everything at that EVM or Solana address. Signing tools return the signature and never broadcast it. near_transfer and near_call take an idempotency_key and settle asynchronously; follow them with get_operation. Freezing the account stops every native tool. None of them can target intents.near or intents.far.

Amounts and Token IDs

Send amounts as strings containing whole numbers in the token’s smallest unit. Use get_tokens to find the token ID and decimal places. A ticker may identify different assets across networks.

With six decimals, 1.25 becomes "1250000". Use exact decimal conversion, not floating-point rounding.

Idempotency and Pending Operations

Requests that change funds require an idempotency_key, which identifies the request when you retry it. Use the same key only when retrying that request with unchanged parameters. Changed parameters or a different payment need a new key.

For pending, uncertain, or owner-action-required responses, use get_operation or refresh_operation instead of another write. Owner-action-required responses include the owner interface URL.

get_operation and refresh_operation both return status and failure_code (null when none, otherwise a cause such as settlement_overdue or deposit_expired). Until the operation succeeds, details.expected_amount_out is an estimate of what will arrive (for a deposit, the 1Click quote, which stays beside amount_out once settled); details.amount_out is the final figure and appears only on SUCCESS (or a partly REFUNDED operation). For a deposit it is set only from an observed delivery and can be 0; never read the quote as delivered. A move the provider refused with amount_too_low keeps the route minimum it stated: details.min_amount for a swap or withdrawal, deposit.min_amount for a deposit, in atomic units of the asset sent. refresh_operation also asks the API to re-observe the request with the provider and chain now.

StatusMeaning
QUEUED, PENDING_APPROVAL, PENDING_SIGNATUREAccepted and waiting on the timelock, an owner approval or a signature.
PROCESSINGSubmitted and settling. Normal for the bridge leg of a withdrawal.
PENDING_DEPOSITOnly for a deposit that is waiting for funds.
UNCERTAINNot yet proven. Keep polling the same operation id with refresh_operation and never resubmit under a new idempotency key.
NEEDS_REVIEWAutomatic settlement stopped. Read failure_code.
SUCCESS, FAILED, REFUNDEDFinal.

Outages

get_network_status returns the status of the services the Agent API depends on: one_click (quotes and routes), custody and near. Each is operational, degraded, down or unknown, with a reason and the actions it affects. The status is advisory; no request is refused because of it. Read it after provider_unavailable; the refusal is retryable, so when a component the request needs is down, wait and send the same request again with the same idempotency key. route_unavailable is different: there is no route for this pair or amount, so repeating will not help; try another amount or pair.

Human review is optional for every owner type. When enabled, the owner approves or rejects requests through Agent Connect. Other account rules still apply.

Proposing Policy Changes

An agent cannot change its own policy, but it can ask. propose_policy_change takes changes, a reason the owner reads, and an optional expires_in_minutes (5 minutes to 7 days, default 24 hours). changes uses the same edits as the dashboard: timelock, USD budget caps, human review, schedule, destination rules, saved destinations and native switches. Read get_policy first; a change the current policy cannot take is refused straight away, and so is one already in effect (proposal_no_change).

The proposal appears in the owner's Activity Log. Review stages the changes in the pending-changes panel, where the owner sees the diff and signs it with their own wallet or passkey; Reject closes it. The proposal turns approved once a newer applied policy carries every proposed change; one nobody answers expires. Poll get_policy_proposal with the returned proposal_id to see pending, approved, rejected or expired. An account holds at most 10 pending proposals.

Feedback

send_feedback sends usage feedback to the Agent Connect team. It takes a category (bug, confusing, missing_feature, works_well or other), a message of up to 2000 characters, and optionally the tool, operation_id and error_code it is about. Each agent can send one per rolling 24 hours. A second send is refused with feedback_limit_reached, which carries available_at. Feedback goes to the Agent Connect team, not to the owner, and it changes nothing about any account. Never put keys, secrets, signatures or personal data in it.

Authentication

The default is OAuth. A client with no token receives a 401 challenge and opens your browser. You sign in, choose which agent the client uses, and sign the grants for the accounts it can reach. The agent is chosen at sign-in, not by the URL.

For agents that cannot open a browser, the dashboard can issue an API key. Send it as Authorization: Bearer $AGENT_CONNECT_KEY, reading it from an environment variable. A key lasts 30 days and is bound to the agent it was issued for.

Both methods check account grants, which give the connection permission to use specific accounts, and whether access has been revoked. Keep live credentials out of prompts, public examples, and logs.

Technical Overview · Troubleshooting