/SKILL.md
Manage Cisco Meraki cloud networking - organizations, networks, devices, wireless, switches, firewall, and clients
npx skillsauth add leprachuan/pot-o-skills cisco-merakiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Complete REST API access to Cisco Meraki cloud networking platform for managing networks, devices, SSIDs, switches, and security policies.
Status: ✅ Fully Functional - All core APIs operational
# Get API key from Meraki Dashboard
# Meraki Dashboard → Organization → Administrators → My profile → API access
MERAKI_API_KEY=your_meraki_api_key_here
Python (Claude/Copilot):
pip install requests python-dotenv
Node.js (Gemini):
npm install axios dotenv
List Organizations (Python):
from copilot.cisco_meraki import MerakiClient
client = MerakiClient()
orgs = client.list_organizations()
for org in orgs:
print(f"{org['name']} (ID: {org['id']})")
List Networks (Python):
from copilot.cisco_meraki import MerakiClient
client = MerakiClient()
org_id = "your_org_id"
networks = client.list_networks(org_id)
for net in networks:
print(f"{net['name']} - Type: {net['type']}")
List Devices (Python):
from copilot.cisco_meraki import MerakiClient
client = MerakiClient()
network_id = "your_network_id"
devices = client.list_devices(network_id)
for device in devices:
print(f"{device['model']} ({device['serial']}) - {device['name']}")
JavaScript (Gemini):
const { MerakiClient } = require('./gemini/cisco_meraki');
const client = new MerakiClient();
// List organizations
const orgs = await client.listOrganizations();
orgs.forEach(org => {
console.log(`${org.name} (${org.id})`);
});
| Method | Description |
| --- | --- |
| list_organizations() | List all accessible organizations |
| get_organization(org_id) | Get organization details |
| Method | Description |
| --- | --- |
| list_networks(org_id) | List networks in organization |
| get_network(network_id) | Get network configuration |
| Method | Description |
| --- | --- |
| list_devices(network_id) | List all devices in network |
| get_device(network_id, serial) | Get device details |
| get_device_status(network_id, serial) | Get device status |
| Method | Description |
| --- | --- |
| list_ssids(network_id) | List SSIDs in network |
| get_ssid(network_id, number) | Get SSID configuration |
| Method | Description |
| --- | --- |
| list_switch_ports(network_id, serial) | List switch ports |
| get_switch_port(network_id, serial, port_id) | Get port details |
| Method | Description |
| --- | --- |
| list_firewall_rules(network_id) | List firewall rules |
| get_firewall_settings(network_id) | Get firewall configuration |
| Method | Description |
| --- | --- |
| list_network_clients(network_id, params) | List connected clients (paginated) |
| get_client(network_id, client_id) | Get client details |
The Meraki API uses cursor-based pagination for large result sets. Results are paginated by default with 10 items per page.
When querying endpoints that return many results (devices, clients, ports, rules), you must fetch all pages to get complete data.
Default (incomplete):
# ❌ Only gets first 10 clients
clients = client.list_network_clients(network_id)
Correct (complete):
# ✅ Gets ALL clients across all pages
import requests
api_key = "your_api_key"
headers = {'X-Cisco-Meraki-API-Key': api_key}
all_clients = []
url = f"https://api.meraki.com/api/v1/networks/{network_id}/clients"
while url:
resp = requests.get(url, headers=headers, params={'perPage': 100})
all_clients.extend(resp.json())
# Check Link header for next page
link_header = resp.headers.get('Link', '')
url = None
if 'rel=next' in link_header:
for part in link_header.split(', '):
if 'rel=next' in part:
url = part.split(';')[0].strip('<>')
break
perPage=100 to reduce pagination calls (default: 10)Link response headerThese endpoints return paginated results:
list_network_clients() - Often 50-100+ clientslist_devices() - May return multiple pages in large networkslist_switch_ports() - Depends on switch port countlist_firewall_rules() - May paginate in complex policiesAll APIs return JSON with consistent structure:
{
"id": "unique-identifier",
"name": "Resource Name",
"type": "ResourceType",
"status": "active|offline",
"url": "https://..."
}
| Code | Meaning | | --- | --- | | 401 | Unauthorized (invalid API key) | | 403 | Forbidden (insufficient permissions) | | 404 | Not found (resource doesn't exist) | | 429 | Rate limited (too many requests) | | 500 | Server error |
✅ API key stored in .env (git-ignored)
✅ HTTPS only
✅ OAuth 2.0 Bearer token
✅ No credentials in logs
✅ Per-organization isolation
data-ai
Interactive GitHub issues kanban board with agent assignments, due dates, and glassmorphism theming. Fully configurable for any GitHub repository.
data-ai
Interactive TODO board for Wee Canvas. Displays TODOs from both GitHub Issues (leprachuan/fosterbot-home) and flat files in two views: list and kanban. Features filtering, drag-and-drop status changes, quick-add, and auto-refresh every 30 seconds. Use when Foster asks to "show TODOs", "open TODO board", "view my tasks", or "TODO kanban".
tools
Web-based terminal tools for Wee Canvas: remote SSH terminal (WebSSH) and local bash terminal (ttyd). Embeds interactive terminal panels in Wee Canvas iframes. Use when the user asks for a 'web terminal', 'local terminal', 'browser SSH', 'webssh', or wants to interact with a host through the WebUI canvas. For browser windows, see the browser-window skill.
development
Use when you need to send WebEx notifications to flipkey-home-bot - supports markdown formatting, auto-retry with backoff, rate limiting, and message history tracking