Limits and quotas
Most surprising R1-MCP behaviour is a limit doing its job. This page collects them, with what each one does when you reach it.
Timeouts
Section titled “Timeouts”| Limit | Value | On reaching it |
|---|---|---|
code_mode run budget | 30 seconds wall clock, shared across every API call the program makes | The run is cut off. At 20 seconds the budget snapshot on each response gains a warning — the program is expected to return partial results and continue in a fresh run |
One call_r1 request | 15 seconds | Surfaces as a structural error envelope; the measured time is still billed to the run budget |
| RUCKUS token mint | 15 seconds | timeout — the R1 token endpoint didn’t respond |
| One Data Studio request | 20 seconds | statusText: "timeout" on the ds_* response |
await_request poll loop | 60 seconds by default, settable 1–120 | Reports the last activity state it saw rather than failing outright |
| Write Guard confirmation | 10 minutes from the preview | Confirming a stale preview returns a fresh preview instead of executing |
A 404 while awaiting is not a failure
Section titled “A 404 while awaiting is not a failure”await_request polls an asynchronous R1 operation to completion. R1 returns
404 for an activity it has accepted but not yet made resolvable, so a 404 is
treated as not yet, not as failure — the loop keeps polling until its own
timeout bounds the wait. Once any poll has returned a real activity body, a
subsequent timeout is a genuine one.
Retries
Section titled “Retries”call_r1 never throws on an HTTP error; it returns a response you can inspect.
What it retries automatically:
| Status | Behaviour |
|---|---|
| 401 | Exactly one refresh-and-retry |
| 429 | Auto-retried for GET, PUT, DELETE only — at most 2 retries, honouring Retry-After, with the wait capped at 5 seconds. POST and PATCH are not replayed unless you pass retryOn429: true |
| 406 | Retried once with the versioned media type R1 named. If the 406 names none, it surfaces as-is |
| 415 | A body-less request is retried once with the Content-Type R1 named |
call_r1_gql requests are POSTs, so they are never auto-retried on a 429
unless you opt in — and opting in is only safe for reads, since Service Validation
has real mutations.
Every response carries retried, so the retry count is always visible.
Stored artifacts
Section titled “Stored artifacts”Everything R1-MCP stores for you is bounded, per user.
| Artifact | Cap | Retention | At the cap |
|---|---|---|---|
Snapshots (venue_extract) | 20 | 30 days | Refuses — snapshot_limit_reached |
Backups (backup_create) | 50 | Indefinite | Refuses — backup_limit_reached, and nothing frees itself |
| MOPs / test plans you author | 50 | Untouched drafts age out after 30 days | Refuses — mop_limit_reached |
| Copy MOPs the engine compiles | 100 | 30 days | Evicts the oldest |
| Test beds | 50 (100 devices each) | 365 days | Refuses |
| Limit | Value | On exceeding it |
|---|---|---|
| Snapshot config | 5 MB | snapshot_too_large — restrict domains and re-extract |
| Backup config | 5 MB | backup_too_large — back up fewer domains separately |
| MOP steps | 200, or 400 for an API-only MOP | The plan is rejected as plan_invalid; split it by domains |
| Runs kept per MOP | 20 | Oldest dropped |
| Run retention | 7 days for a MOP, 90 days for a test plan | Swept |
A compiled copy plan gets the raised 400-step cap because it is API-only. An
over-cap plan is the signal to plan each subset of domains into its own MOP.
Batches and pages
Section titled “Batches and pages”| Limit | Value |
|---|---|
device_cli commands per batch | 20, run sequentially in the held session |
search_endpoints results | 10 by default, 20 maximum |
| Autopilot wall clock | maxWallMin — 30 minutes by default, 120 maximum |
| Autopilot runs | One at a time, per user |
A long configuration job is applied as several batches of twenty into the same held session, not as one giant push. Autopilot expiry pauses a run; it never fails it.
Webhook event retention
Section titled “Webhook event retention”The webhooks feature stores what it receives, per user, with retention that varies by event class. This is why a month-old client event is gone while a month-old incident is not.
| Event class | Kept | Row cap |
|---|---|---|
Client stream (event) | 7 days | 20,000 |
AP infrastructure (ap_event) | 30 days | 5,000 |
RADIUS / auth (radius) | 30 days | 4,000 |
| Activity — “what changed before the outage” | 90 days | 2,000 |
| Admin audit | 90 days | 2,000 |
| Incidents | 365 days | 1,000 |
| Test / unknown | 7 days | 400 |
Purging is lazy — it happens on insert, scoped to the class that just arrived — and each class purges against its own budget. The high-volume client stream therefore cannot evict a rare incident or admin row to make room for itself.
Anything you ask about outside these windows isn’t missing data; it is data that was never retained. Derived stores have their own windows: the client registry keeps 180 days, roam pairs 90 days, event counters 120 days.
Watches
Section titled “Watches”| Limit | Value |
|---|---|
| Watch expiry | 24 hours by default |
| Maximum | 168 hours (7 days) |
Expiry is mandatory — there is no permanent watch.
Feature gates are a kind of limit too
Section titled “Feature gates are a kind of limit too”A tool you cannot see is not a broken tool. R1-MCP exposes a single MCP tool —
code_mode — and inside it the r1 object carries 13 always-on primitives.
Everything else appears only when its feature is enabled.
get_reference itself appears only once you have at least one feature on.
After enabling a feature, reconnect the connector in Claude so it picks up the new tool list.