joyride-cli package and speaks
MCP over stdio.
It is a reading and requesting surface, not a full trading surface. Read
The server holds no signing key before
planning anything around it.
Connect a client
Install the CLI, sign in, then register the server with a client:--client accepts claude, codex, or cursor. Pass --force to overwrite
an existing entry, and joyride mcp uninstall --client <client> to remove it.
To register it by hand, the server entry is the joyride binary with the
mcp serve arguments:
joyride login wrote and sends it as a bearer for every downstream call. It
never runs Sign-In with Solana itself and never signs with the keystore. A
missing or expired stored session is a startup error: the server exits and
points back at joyride login. A token the venue later rejects is reported by
every tool. One tool, create_wallet, writes a new encrypted keystore when
JOYRIDE_KEYSTORE_PASSWORD is set in its environment; it never reads one. A wallet selected on the command line that does not match the
stored session is a fatal startup error, so one wallet’s session can never be
used to act as another.
What the RFQ tools expose
Package legs are ordered and their quantities are signed decimal strings:
positive buys the leg, negative sells it. Submitted order is canonical and is
never sorted.
request_rfq_quote requires a side: buy, sell or two_way. buy asks
for one price on the legs as written and sell for one price on their mirror
image; either shows the direction to the quoters, and only that side can then
be accepted. two_way asks for both prices and keeps the direction hidden
until the accept, though a quoter may still answer on one side only. There is
no default. The tool never chooses a direction, so an agent that has not been
told one should ask.
request_rfq_quote takes an optional client_ref idempotency key. When a
request’s outcome comes back unknown, re-sending the same key with the same
legs and side retries that request rather than opening a second one.
Market data and account reads are available through the server’s other tools
and resources. Order-book trading tools also exist from the exchange’s earlier
shape; the venue these pages document is RFQ, and nothing here teaches the
order book.
Three maker tools — watch_rfq_requests, respond_rfq_quote, and
decline_rfq_request — exist behind an operator switch and are absent from the
tool listing unless it is on. Quoting from MCP is limited by the same missing
key described below, so a desk should read TypeScript Maker SDK
instead.
The server holds no signing key
This is a design decision, not a gap to configure around. The MCP server is a pure auth client. It resumes a session token; it never opens the keystore and never produces an ed25519 signature. Accepting a quote and responding to a request are both signing operations, so in production:accept_rfq_quotecannot sign an acceptance.respond_rfq_quotecannot sign a maker quote. Its refusal says so in those words and points at the CLI.
joyride CLI, which holds the keystore, or in the
Joyride app. A workable division of labour is: let the agent find the package
and request the quote through MCP, then accept from the CLI with
joyride rfq accept.
A refused accept consumes nothing. No nonce is spent, no request state changes,
and the account’s other live requests are unaffected.
Why the accept tool stays visible
accept_rfq_quote remains in the tool list as an explicit capability boundary
for clients that already know its name. Calling it returns the keyless refusal
and the CLI/app handoff before the server reads the quote or touches the
trading client.
Do not add spend-ceiling variables to the MCP process in an attempt to enable
acceptance. They cannot supply the missing key, and no future signing mode is
advertised or implied. Apply acceptance limits on the signing surface you
actually use; for the CLI, see
joyride rfq accept.
What an agent can and cannot do
There is no cancel and no replace
A quote delivered to the venue is firm until itsexpires_at. Nothing pulls it
back, amends it, or replaces it, and the quote’s TTL is the only control over
how long that commitment stands.
For an agent on the taking side, the consequence is on the clock: a quote that
is read and reasoned about for too long expires, and the venue refuses an
accept that arrives with under two seconds of life left. Treat expires_at as
a deadline, not a hint, and re-request rather than accepting stale state.