How code mode works
R1-MCP’s tools/list returns exactly one tool: code_mode. Understanding
what happens inside it explains most of R1-MCP’s behavior — including why it
sometimes takes a few seconds to answer a simple question.
The problem it solves
Section titled “The problem it solves”RUCKUS One has more than 1500 API endpoints. Exposing one MCP tool per endpoint would produce a tool list no model can choose from reliably, and tool definitions large enough to crowd out the actual conversation.
The approach
Section titled “The approach”code_mode accepts a small TypeScript program. Inside that program, an r1
object provides primitives for discovering and calling endpoints. Claude writes
the program, R1-MCP runs it in a sandboxed V8 isolate, and only the result
comes back into the conversation.
The payoff: Claude can loop, filter, and join across many API calls in one round trip, and only the answer — not thousands of intermediate JSON rows — enters the context window.
The workflow
Section titled “The workflow”A typical request follows this path:
- Orient —
r1.list_tag_groups()/r1.list_tags()to find the right corner of the API taxonomy. - Search —
r1.search_endpoints("...")orr1.list_endpoints_by_tag(...)against a bundled index of every operation. Results carry hints about the request body, response shape, pagination style, and required parameters, so a follow-up lookup is usually unnecessary. - Read the details —
r1.get_endpoint_details(...)when the hints aren’t enough, returning the full schema plus any curated caveats. - Call —
r1.call_r1(...)substitutes path parameters, builds the query string, attaches your bearer token, and sends the request.
For “how do I…?” questions rather than “which endpoint?” questions, there’s
r1.search_docs(...) — full-text search over the RUCKUS One online user guide,
returning ranked snippets with links to the source topic.
See Core tools for the full list.
Your credentials never leave the server
Section titled “Your credentials never leave the server”The program Claude writes runs on Cloudflare, not in Claude. When it calls
call_r1, R1-MCP mints a RUCKUS token server-side using your encrypted
credentials and attaches it. Claude sees the API response; it never sees your
client secret or your bearer token. See Security model.
Errors don’t throw
Section titled “Errors don’t throw”call_r1 never throws on an HTTP error. It returns a response object with
ok, status, and the body — so the program can inspect the failure and adapt
rather than dying. If Claude ever reports a specific R1 status code and error
body back to you, that’s why.
Retries
Section titled “Retries”- 401 — exactly one automatic refresh-and-retry. Your RUCKUS token is cached with a TTL just under its real expiry, so this is rare.
- 429 — automatically retried for idempotent methods (GET, PUT, DELETE),
honoring
Retry-After, capped at a few seconds and a small number of attempts. POST and PATCH are not auto-retried unless explicitly opted in, because replaying a create or a partial update is not safe.
Responses report how many retries happened.
The run budget
Section titled “The run budget”Each code_mode run carries a wall-clock budget shared across every API call
it makes. As the budget gets consumed, responses carry a warning, and the
program is expected to wrap up and continue in a fresh run.
This is why a very broad request (“audit every venue”) may come back in stages rather than as one enormous answer. Asking for a narrower scope is usually faster than asking for everything at once.
Caching
Section titled “Caching”Endpoint details are cached in three tiers — an in-memory LRU, a KV cache keyed by spec version, and the full spec in object storage. The KV key includes the spec version, so a RUCKUS spec update invalidates stale entries automatically.
Which spec is live
Section titled “Which spec is live”The bundled API index records which RUCKUS consolidated OpenAPI spec it was built from, and that metadata is surfaced to Claude at request time. If you need to know exactly which spec version answered your question, ask — Claude can see it.
Notes on endpoints
Section titled “Notes on endpoints”r1.save_endpoint_note(...) lets you attach a short note to an endpoint — a
quirk the spec doesn’t capture. Notes are private to you and resurface on
future get_endpoint_details calls for that endpoint, so a hard-won discovery
isn’t lost. An admin can promote a note to be visible to everyone.