Skip to content
SZ-MCP
Get Support

Limits and quotas

Most surprising SZ-MCP behaviour is a limit doing its job. This page collects them, with what each one does when you reach it.

LimitValueOn reaching it
code_mode run budget30 seconds wall clock, shared across every call the program makesFrom 20 seconds, every call result carries a budget.warning telling the program to stop looping and return. At 30 seconds the run ends with a tool error: { "error": "timeout", "message": "code_mode exceeded its 30 s wall-clock limit. …", "writesSent": [...] }. Requests already sent are not cancelled; writesSent lists any writes
One call request to SmartZone15 secondsThe request is aborted; surfaces as a network_error envelope, and the time still counts against the run budget
Service ticket mint (login)15 secondsinvalid_host — the controller did not respond in time
API version detection15 seconds per requestDetection reads the controller’s unauthenticated apiInfo list, picks the newest version and logs in once. A timeout fails with invalid_host; a host that does not answer as a SmartZone gets not_smartzone and never receives the password
await_approval15 secondsReturns { status: 'pending' }; call it again or re-send with the approvalId later
Confirm token, dashboard approval10 minutesThe write is previewed again with a fresh token (token_expired) or a new approval

The run budget is per code_mode call, not per conversation. Every new call gets a fresh 30 seconds, which is why the right response to hitting it is to split the work rather than retry the same program.

LimitValueOn exceeding it
code_mode program source20,000 charactersRejected before execution: code must be under 20,000 characters
code_mode result200 KBReturned as { truncated: true, originalChars, hint, preview } with the first 100 KB
One controller response body32 MBbody becomes { error: 'response_too_large', message, preview } with the first 2,000 characters
MCP request body4 MB (OAuth endpoints 64 KB)413 with {"error": "payload_too_large"}
JSON-RPC batch10 requestsbatch_too_large error
Controller port8443 or 443 onlyforbidden_port
Endpoint note5–500 characters; 10 per endpoint, 500 per organisationnote_too_short, note_too_long, too_many_notes_for_endpoint, too_many_notes
Host / FQDN253 charactersRejected on save
SmartZone username200 charactersRejected on save
SmartZone password500 charactersRejected on save
Credential label100 charactersRejected on save

These bound what the discovery primitives return in one call. Neither is a cap on what exists — both report the full total separately.

PrimitiveDefaultMaximumTotal available
search_endpoints20 results50count gives the pre-limit total
list_endpoints_by_tag50 results200count gives the total under the tag

list_endpoints_by_tag takes an offset, so a tag larger than 200 operations is paged rather than truncated. search_endpoints has no offset — narrow the query or add a tag instead.

get_endpoint_details inlines $ref pointers to a depth of 3. Deeper references, and any cycle, are left as { $ref: "…" } rather than expanded.

ItemLifetimeNotes
Service ticket25 minutesCached in KV per organisation, deliberately shorter than SmartZone’s idle timeout. Flushed on credentials save, delete and Test connection
Full OpenAPI specPer isolate, until evictionLoaded from object storage on the first get_endpoint_details for that surface that misses the cache below; adds a few hundred ms to that one call
One endpoint’s details30 days in KV, plus the last 200 per isolateInvalidated when a new index is deployed. caveats and notes are added on every read, outside the cache
Web session cookie30 daysszmcp_session
MCP access token30 daysPrefixed szmk_
MCP refresh token90 daysRotated on every use; the old one is revoked
OAuth authorization code10 minutesSingle use
MCP client registration30 daysClaude re-registers automatically

call never throws on an HTTP error, and retries exactly one thing:

StatusBehaviour
401The cached ticket is discarded, a fresh one is minted, and the request is retried once. A second 401 is returned to you
429Retried up to 2 times for GET, PUT and DELETE, and for POST/PATCH only with retryOn429: true. Each retry waits for Retry-After, capped at 5 seconds (1 second when absent). retried counts them; a third 429 is returned to you
Everything elseReturned as-is. No automatic retry on 5xx or any other status

Those waits count against the run budget. A controller that keeps answering 429, or one that is flapping, surfaces directly to the model.

LimitValueOn reaching it
MCP client registrations20 per IP per hour429 with {"error": "rate_limited"}
Authenticator codes5 per 5 minutes per person (chat and dashboard together)totp_locked; the confirm token stays valid until it expires
Audit evidence pack6 per minute per organisation429
Alert test sends5 per hour per organisation429
Configuration bundle export and import (dashboard)10 per minute per organisation429
Controller tunnel creation5 per hour per organisation429

The registration limit bounds the Dynamic Client Registration endpoint only. Normal use registers once per connector, so reaching it usually means something is re-registering in a loop. code_mode calls themselves are not rate limited; the run budget bounds them.

LimitValueOn reaching it
MOPs per organisation100mop.save refuses a new one
Steps per MOP200mop.save refuses the MOP
Items one forEach step repeats over200The step fails without sending, and the run fails
Runs kept20 per MOP, 90 daysOlder finished runs are deleted, oldest first
An approved run’s writesSent for 12 hours after the run startsarming_expired: abort the run and start a new one. Past 12 hours a run can no longer be rolled back as a whole; undo its writes one by one with history.undo
Change windowUp to 24 hours (default 60 minutes)mop.save refuses the MOP
A step with no resultLost after 45 secondsThe run waits for you to retry or skip it
Active MOP schedules20 per organisationmop.schedule refuses another
A once scheduleAt most 30 days aheadRefused
A recurring schedule’s approval30 days by default, 90 days at mostRefused above 90 days; nothing fires after until
A scheduled run found late10 minutesRecorded as missed, never run late
Lint fixes in one MOP50Pick fewer findings
Post-change verificationWatches 15 minutes; at most 50 at onceA write past 50 is not verified, and the result says so
switches.restoreNeeds a backup of that switch from the last 15 minutesfresh_backup_required unless force
DataKeptThen
Write history (body, before-state, response)30 days, at most 5,000 writesDeleted; those writes can no longer be undone. Fields over 64 KB (body), 256 KB (before-state) or 16 KB (response) are dropped when stored, and such a write cannot be undone
Write log (who, what, result, body hash)365 daysDeleted
Post-change verifications30 days, at most 5,000Deleted
Config snapshot changes180 days, at most 50,000Deleted, oldest first
Controller admin audit log400 days, at most 100,000 rowsDeleted, oldest first
Streamed events, alarms, client sessions and connection attempts14 days (an admin can set 1–14)Deleted
Streamed application flows2 days (an admin can set 0–2; 0 stores none)Deleted
MetricsRaw 48 hours, hourly 8 days, daily 400 daysQueries further back run on the coarser tier
Alert history30 days; HARD transitions, recoveries, acknowledgements, downtime and rule changes 400 daysDeleted
Site notes5,000 per organisation, 50 per device or location, 2,000 characters eachRefused past the cap; an expired note is deleted 30 days after it expires
LimitValue
SmartZone controllers per organisationOne
MCP scopesOne — sz:call
MCP tools exposedOne — code_mode

Saving new credentials replaces the organisation’s controller. A person can belong to several organisations, each with its own controller, and each connector is bound to the organisation chosen when it was authorised.

Two ceilings sit outside this service and are worth naming, because they look like SZ-MCP limits from the inside:

  • Your SmartZone account’s permissions. Anything it cannot do returns a 403 from the controller. SZ-MCP cannot widen them; what it adds on top is the write guard, your role in the organisation and read-only mode — see Security model.
  • The controller’s own pagination. WSG list endpoints typically take listSize and index and return { list, hasMore, totalCount }. Those caps are SmartZone’s; SZ-MCP passes your query through unchanged.