Skip to content
SZ-MCP
Get Support

Examples

You do not write these programs yourself — Claude does, from a plain-language request. They are here so you can see what it is composing on your behalf, and so you can ask for something shaped like one.

Each example is the body of an async arrow function, which is what code_mode takes.

Start here. These are requests that map onto the programs below:

List the AP zones on my SmartZone and how many APs are in each.

Find the endpoint that creates a WLAN and tell me what fields it requires.

How many switches are in each switch group?

Show me every DHCP-related endpoint on the wireless API.

These use SZ-MCP’s monitoring functions rather than raw API calls, so there is no program below for them. Claude previews any alert rule change before it saves it: creating, importing and installing rules are dry runs until applied. Board changes (creating a board, adding, changing or removing a panel) are saved at once; turning a panel into an alert is a dry run first.

Install the starter alert checks, then show me what they would flag right now.

Backtest an alert for radio airtime above 80% over the last week and tell me how noisy it would have been.

Put the Lobby zone in downtime for two hours while we replace its switch.

Export our alert rules as YAML.

What does SmartZone alarm 302 mean, and what should I do about it?

Build me a board for the switches: ports up, PoE, errors, and switch alarms.

Turn the PoE panel on that board into an alert.

Show clients per zone over the last 24 hours.

See How alerts work, Alert rules, Boards and Metrics and the scrape endpoint.

Two read-only helpers answer the questions a help desk asks most. Claude calls them for you. You can also pick the A client’s journey and Which switch port is it on? prompts from the ”+” menu.

Why does the laptop aa:bb:cc:dd:ee:ff keep dropping off the Wi-Fi?

What happened to the iPhone on the guest network this morning?

Which switch port is 172.16.128.40 plugged into, and is anything wrong with it?

Which switch port is the AP in room 214 on?

A client journey lists one client’s joins, roams, failed attempts, IP renewals and disconnects in time order, with the disconnect reason and the AP and band for each. Most of this comes from Northbound streaming. Without it, SmartZone’s API holds only the client’s IP renewals, its current connection and a few hours of ended sessions, and Claude will say so.

A port lookup finds the device in the switches’ MAC tables. It then checks the port’s LLDP neighbour, so it can tell the device’s own port from an uplink the device is only seen behind. It reports the port’s link, speed, PoE, error counters, VLANs and 802.1X settings, plus the other devices on the port, and lists what to check first.

Claude can also run tests on the devices themselves. They are read-only and take 5 to 15 seconds each:

Ping our RADIUS server from the lobby AP.

Traceroute from AP 00:E6:3A:3B:34:80 to 1.1.1.1.

Show the routing table of the core ICX switch.

SmartZone accepts only IP addresses as targets, not hostnames.

The simplest useful call — a GET with pagination parameters, checking ok before touching the body.

async () => {
const r = await wifi.call({
method: 'GET',
path: '/domains',
query: { listSize: 100, index: 0 },
});
if (!r.ok) return { error: r.status, body: r.body };
return {
total: r.body?.totalCount,
names: r.body?.list?.map(d => d.name),
};
}

WSG list endpoints typically return { list, hasMore, totalCount }, which is what makes the shape above work across most of the surface.

Discover an endpoint, then read its schema

Section titled “Discover an endpoint, then read its schema”

Discovery and inspection in one run — no round trip back to the model between the two steps.

async () => {
const hits = await wifi.search_endpoints({ query: 'wlan', limit: 5 });
if (hits.results.length === 0) return { found: 0 };
const top = hits.results.find(e => e.method === 'POST') ?? hits.results[0];
const details = await wifi.get_endpoint_details({
method: top.method,
path: top.path,
});
// The body schema is in requestBody; parameters holds path, query and header ones.
const body = details.requestBody?.schema;
const required = details.parameters?.filter(p => p.required).map(p => p.name);
return { endpoint: `${top.method} ${top.path}`, required, body };
}

The search hit itself already names the body’s fields in requestBodyHint; get_endpoint_details adds the full schema. See Code mode primitives.

The run budget is 30 seconds of wall clock, shared by every call the program makes, and every call result carries a budget warning once 20 seconds have gone. Bound the loop explicitly rather than trusting hasMore to terminate it.

async () => {
const all = [];
const listSize = 100;
let index = 0;
for (let page = 0; page < 10; page++) {
const r = await wifi.call({
method: 'GET',
path: '/domains',
query: { listSize, index },
});
if (!r.ok) return { error: r.status, body: r.body, collected: all.length };
all.push(...(r.body?.list ?? []));
if (!r.body?.hasMore) break;
index += listSize;
}
return { count: all.length };
}

If the cap is reached before hasMore goes false, return what you have and continue in a fresh code_mode call — each one gets its own budget.

{placeholder} segments are filled from pathParams and URL-encoded for you.

async () => {
const r = await wifi.call({
method: 'GET',
path: '/rkszones/{zoneId}/wlans',
pathParams: { zoneId: 'd1f2a3b4-0000-0000-0000-000000000000' },
query: { listSize: 50, index: 0 },
});
return r.ok
? { count: r.body?.totalCount }
: { failed: r.status, statusText: r.statusText };
}

switches works identically, against SwitchM. Start from the tag list, which is the top of the discovery hierarchy on both surfaces.

async () => {
const { tags } = await switches.list_tags();
const switchTags = tags
.filter(t => t.operationCount > 5)
.sort((a, b) => b.operationCount - a.operationCount);
// Every Switch Health operation is a POST (and a read)
const health = await switches.list_endpoints_by_tag({
tag: 'Switch Health',
});
return {
biggestTags: switchTags.slice(0, 5),
healthEndpoints: health.results.map(e => `${e.method} ${e.path} (${e.access})`),
};
}

Nothing stops a single program touching both namespaces — they share the run budget and the detected API version. Note the different pagination: WSG lists take listSize and index in the query, while SwitchM lists are POSTs taking page (from 1) and limit in the body.

async () => {
const [zones, sw] = await Promise.all([
wifi.call({ method: 'GET', path: '/rkszones', query: { listSize: 100, index: 0 } }),
switches.call({ method: 'POST', path: '/switch', body: { page: 1, limit: 100 } }),
]);
return {
zones: zones.ok ? zones.body?.totalCount : { error: zones.status },
switches: sw.ok ? sw.body?.totalCount : { error: sw.status },
};
}

Every write sent through SZ-MCP is kept for 30 days with the state of its target just before it. history.undo without apply only plans the inverse; nothing is sent.

What did we change on the controller today, and how would I undo the last one?

async () => {
const { writes } = await history.writes({ sinceMinutes: 24 * 60, limit: 10 });
if (!writes.length) return { writes: 0 };
const plan = await history.undo({ writeId: writes[0].writeId });
return { writes: writes.map(w => `${w.method} ${w.path} ${w.status}`), plan };
}

Applying it is history.undo({ writeId, apply: true }), which goes through the write guard like any other write.

The linter reads the daily config snapshot, so it makes no controller calls. lint.to_mop turns fixable findings into a method of procedure without saving it unless you pass save: true.

Check our Wi-Fi config against best practice and draft a change for what can be fixed.

async () => {
const r = await lint.run({ minSeverity: 'warning' });
if (!r.findings) return r; // e.g. no config snapshot yet
const fixable = r.findings.filter(f => f.fix?.request).map(f => f.id).slice(0, 50);
const draft = fixable.length ? await lint.to_mop({ ids: fixable }) : null;
return { snapshotAt: r.snapshotAt, summary: r.summary, included: draft?.included, skipped: draft?.skipped };
}