Skip to content
SZ-MCP
Get Support

Code mode primitives

Both namespaces expose the same five primitives. wifi operates on the SmartZone WSG API, switches on SwitchM; nothing else differs between them.

PrimitivePurposeNetwork call
list_tagsTags with operation countsNo
search_endpointsKeyword search over the indexNo
list_endpoints_by_tagEvery endpoint under a tagNo
get_endpoint_detailsFull schema for one endpointFirst call per surface, per isolate
callExecute an authenticated requestYes

The first three read the index bundled into the Worker, so they are effectively free. get_endpoint_details loads the full spec from object storage the first time it is used for a surface in a given isolate. Only call reaches your controller.

Takes no arguments. This is the starting point for discovery.

const { tags } = await switches.list_tags();
ReturnsType
tagsArray of { name, description?, operationCount }

Returns every tag on the surface — 119 on wifi, 42 on switches. description is absent on every tag for the same reason the specs carry no operation descriptions.

There is no tag-group level above tags. An earlier list_tag_groups primitive, and a group argument on list_tags, were removed because the SmartZone specs define no tag groups, so both could only return an empty list.

const { results, count } = await wifi.search_endpoints({ query: 'wlan profile' });
ArgumentTypeDefaultNotes
querystringRequired. Minimum 2 characters
tagstringRestrict to one tag, exact match
methodenumGET, POST, PUT, PATCH, DELETE
limitnumber20Accepted range 1–50
ReturnsType
resultsArray of index entries, ranked best first
countTotal matches before the limit was applied

Query text is lower-cased and split on whitespace; each token is matched as a substring. Scoring adds +2 for a hit in operationId and +1 each for the search blob, a tag name and the path.

Because count is the pre-limit total, a count far above results.length means narrowing the query or adding a tag will serve you better than raising limit.

const { results, count } = await switches.list_endpoints_by_tag({ tag: 'Switch Health' });
ArgumentTypeDefaultNotes
tagstringRequired. Exact name from list_tags
methodenumFilter by HTTP method
limitnumber50Accepted range 1–200
offsetnumber0For paging through a large tag
ReturnsType
resultsIndex entries for this page
countTotal under the tag, ignoring limit and offset

Tag matching is exact and case-sensitive — pass the name verbatim as list_tags returned it.

Both search and browse return entries of this shape:

FieldNotes
methodUpper-case HTTP method
pathSpec path, with {placeholder} segments
operationIdPresent on all 1,354 operations
tagsTag names this operation belongs to
summaryOne line. Present on all but two WSG operations
descriptionAlways absent — the specs populate none
paramsSummaryParameter names grouped by location, e.g. path: id; query: listSize,index
hasBodyAlways false — see the caution under get_endpoint_details
deprecatedPresent only when true. No operation in either spec is marked deprecated
const details = await wifi.get_endpoint_details({ method: 'POST', path: '/rkszones' });
ArgumentTypeNotes
methodenumRequired
pathstringRequired. Must start with / and match the spec path exactly
ReturnsField
surface, method, pathEchoed back
operationId, summary, description, deprecatedFrom the spec
parametersArray — this is where the request body lives
requestBodyAlways null
responsesResponse definitions by status code
security, tagsFrom the spec

$ref pointers are inlined up to three levels deep. Beyond that, or on a cycle, the { $ref: "…" } object is left in place rather than expanded.

You will also see serviceTicket as a required query parameter on nearly every operation. Do not pass it — SZ-MCP attaches it server-side.

Unlike call, this primitive returns a plain object on failure:

ReturnMeaning
{ error: 'not_found', method, path }No such operation in the bundled index
{ error: 'details_unavailable', method, path }In the index, but absent from the stored full spec

The only primitive that reaches your controller.

const r = await wifi.call({
method: 'GET',
path: '/rkszones/{zoneId}/wlans',
pathParams: { zoneId: 'abc-123' },
query: { listSize: 100, index: 0 },
});
if (!r.ok) return { failed: r.status, body: r.body };
ArgumentTypeNotes
methodenumRequired. GET, POST, PUT, PATCH, DELETE
pathstringRequired. Spec path, starting /, no base prefix
pathParamsobjectValues substituted into {placeholder} segments, URL-encoded
queryobjectQuery parameters. Arrays append the key once per value
bodyanyJSON-serialised unless already a string. Ignored on GET and DELETE
headersobjectExtra request headers

Accept: application/json is sent always; Content-Type: application/json is added for requests that carry a body.

FieldNotes
oktrue for 2xx
statusHTTP status code
statusTextHTTP status text
headersResponse headers as an object
bodyParsed JSON when the response is JSON; raw text otherwise; null when empty
durationMsTime for the request, including any 401 retry
urlThe upstream URL with serviceTicket=<redacted>

A 401 discards the cached service ticket, mints a fresh one and retries exactly once. A second 401 is returned to you. No other status is retried.

When the failure happens before the request reaches SmartZone, call still returns rather than throwing — with status: 0:

statusTextbody.errorMeaning
sz_auth_errorno_credentialsNothing saved for this account. body.message says to save credentials on the dashboard
sz_auth_errorlogin_failedThe controller rejected the login, e.g. http_401
sz_auth_errorforbidden_hostThe saved host is not publicly routable
sz_auth_errorinvalid_hostController unreachable — DNS, timeout, refused connection, or TLS validation failure
sz_auth_errordecryption_failedStored password could not be decrypted
network_errornetworkUnexpected failure; body.message carries the detail

url is an empty string on all of these, since no request was made.