Start here
- Read the authentication and secure setup tutorial and check current capabilities.
- Confirm the owner’s existing identity and the owner-approved scope. Do not create a replacement account.
- Stop for the human at each browser passkey step. Connect with an API key through the owner’s browser approval, below; never ask for a passkey, a session bearer or a DFNS credential, and never approve yourself.
- Begin with read-only checks. Before trading, require an
activeCanton Party binding and separate explicit owner approval for the exact action. Installation and a key grant neither.
Connect with an API key
The venue gives an agent an API key through a one-time browser approval (the RFC 8628 device grant).POST /v1/agent-connect/startwithclientNameandscopes(read, orreadandtrade). The answer carriesconnectCode,userCode,verificationUrl,expiresInSeconds(600) andintervalSeconds(5).- Show the owner
verificationUrlanduserCode. The owner opens the page, signs in with a passkey, checks that the code matches and approves. POST /v1/agent-connect/completewithconnectCodeeveryintervalSeconds. It answersauthorization_pendinguntil the owner approves,slow_downwhen you ask faster (add five seconds to your interval),expiredafter ten minutes or once the key was collected, andapprovedwithapiKeyexactly once. Start polling right after step 1: the owner may approve before you show the code again.- Send
Authorization: Bearer <apiKey>on account and order routes. Store the key in a file only you can read; never put it in command-line arguments, logs or chat.
Use the Edel MCP server
Testnet target:https://mcp-testnet.edel-api.xyz/mcp. This is a separately deployed, stateless
Streamable HTTP service. The endpoint must be provisioned and verified by this venue’s rollout;
source configuration alone is not evidence that it is live.
Direct remote client (preferred)
- Obtain an expiring key with the device-grant flow above. For the local convenience command, run
bun run --cwd apps/mcp connect, open the printed verification URL and approve its code in the browser. The command saves the approved key only in the client file~/.edel/mcp-key.json(mode 0600). - Configure your remote MCP client with the URL and an
Authorization: Bearer <apiKey>header on every request. Load the value from your private client file or secret store; never put a real key in chat, a command-line argument, source control or logs. Configuration syntax varies by client:
- Call
edel_connectwith the approved scopes to confirm the current key metadata, thenedel_statusfor account readiness.edel_marketsandedel_priceread snapshots; live updates use WebSockets. - An expired or revoked key is refused by the same trader auth middleware as REST. Run the local connect command again and update the remote header. No MCP session id grants access.
edel_connect
only confirms the supplied key; it does not start a browser grant or save a key on Railway.
Optional local bridge
An MCP client that starts stdio processes may runbun run --cwd apps/mcp start with MCP_PUBLIC_URL
set to the remote MCP URL. The local edel_connect tool runs browser approval and saves the client key;
other tools forward over HTTP with that key. Without MCP_PUBLIC_URL, the local tools call REST directly.
Direct remote clients do not require this bridge. The local edel_connect rechecks stored credentials
with the API and consumes settled grants before answering; reconnect: true forces fresh approval.
Tools and their REST operations
The MCP stays at parity with the public REST API, deposits and withdrawals excepted (owner rule, 2026-09-19). Every public operation is called by a tool with the same request fields and error codes, or excluded for one of the closed reasons below; a test fails the build when either drifts. The server fillsaccountId from the approved key; every other request field is a tool input with its REST name.
Closing submits a reduce-only market order through
POST /v1/orders. Take profit and stop loss travel
as autoClose (takeProfitPriceAtoms, stopLossPriceAtoms) on edel_place_order and on each
edel_place_order_batch entry. The public contract has no standalone trigger arm, cancel or replace
route and no timeInForce on /v1, so no tool offers them.
edel_place_order requires a caller-supplied clientOrderId. Choose it once per owner-approved logical
order and reuse it with identical arguments on every retry, including after a lost response. Never generate
a new identity just because the API did not answer: it may already have accepted the order.
Read-only history tools use the approved key: edel_order_history reads orders, edel_trade_history reads
fills, and edel_position_history reads position episodes. Each returns one page (default 50, maximum 100),
nextCursor and projection freshness; pass cursor to fetch the next page. All accept marketId; order
and position history also accept status.
edel_funding reads that same paginated position history with market/status filters and labels its basis
cumulative_per_position_episode: fundingPaidAtoms is cumulative funding paid per episode. It is not
per-payment funding history; the API does not serve that ledger, and this tool never invents payment rows.
What a key can do
A key never deposits, withdraws, changes the Party binding, approves another agent or manages keys, and it
does not read transfers or affiliate data or edit favorites. Those routes answer
403 with apiKeyRejection
set to passkey_required; a read key placing an order gets
scope_insufficient. A key expires (24 hours by default, 7 days at most) and the owner can revoke it. A
refused key answers 401 with apiKeyRejection set to expired, revoked, unknown or malformed:
connect again.
Identity is not account readiness
The human owner approves every required DFNS User Action with their passkey; an API key never replaces
that approval. Funding and withdrawals stay with the owner. No step here guarantees a successful live flow.
Keep connect codes and private identifiers in memory, never in command-line arguments, logs, files or chat.
The API key is the one credential you keep in a file, and only you may read that file.