Note: This project was co-authored with Cursor/Codex 5.3. Version note: This OSS repository is the current MCP server version and replaces the older
network_platforms_mcp_serversrepo. Legacydeclarative-*server entrypoints are deprecated.
This project is published for open-source use as is. It is not intended to be used in production.
Current OSS server suite (grouped by platform):
Meraki
meraki_core.py- FastMCP core app and tool registration for Merakimeraki_stdio.py- stdio transport wrapper for Merakimeraki_remote.py- streamable HTTP transport wrapper for MerakiResources/meraki_tools.yaml- Meraki declarative tool definitionsResources/meraki_organizations.yaml- Meraki organization mapping
Catalyst Center
catalyst_center_core.py- FastMCP core app and tool registration for Catalyst Centercatalyst_center_stdio.py- stdio transport wrapper for Catalyst Centercatalyst_center_remote.py- streamable HTTP transport wrapper for Catalyst CenterResources/catalyst_center_tools.yaml- Catalyst Center declarative tool definitionsResources/catalyst_center_clusters.yaml- Catalyst Center cluster mappingResources/catalyst_config_ai_flows.yaml- Catalyst Center AI flow definitions
Shared
download_embeddings_model.py- local embedding model/bootstrap helperenvironment.env.example- environment variable templateMakefile- helper commands for remote server startup/health checks
Training
training_mcp_servers/- optional training/demo server variants for learning and experimentation
Architecture model (grouped by platform):
Meraki architecture
meraki_core.pybuilds the Meraki FastMCP app and registers tools.meraki_stdio.pyruns Meraki withtransport="stdio".meraki_remote.pyruns Meraki withtransport="streamable-http"on/mcp(default port8001).
Catalyst Center architecture
catalyst_center_core.pybuilds the Catalyst Center FastMCP app and registers tools.catalyst_center_stdio.pyruns Catalyst Center withtransport="stdio".catalyst_center_remote.pyruns Catalyst Center withtransport="streamable-http"on/mcp(default port8000).
Shared transport behavior
- Run transport wrappers (
*_stdio.pyor*_remote.py) rather than executing*_core.pydirectly. - Remote wrappers bind to
MCP_HOST(default0.0.0.0); use a real server IP/FQDN in clients (0.0.0.0is bind-only). - Remote wrappers support optional TLS via
--ssl-certfileand--ssl-keyfile(orMCP_SSL_CERTFILE/MCP_SSL_KEYFILE). - Remote wrappers require API key auth on
/mcpusingMCP_API_KEYand client headerX-API-Key.
Use this checklist when integrating remote MCP clients:
-
Use streamable HTTP endpoint
- Catalyst Center:
https://<host>:8000/mcp(orhttp://<host>:8000/mcpfor local non-TLS testing). - Meraki:
https://<host>:8001/mcp(orhttp://<host>:8001/mcpfor local non-TLS testing).
- Catalyst Center:
-
Include API key header
- Remote wrappers require
MCP_API_KEYon startup, and clients must include: X-API-Key: <key>
- Remote wrappers require
-
Initialize first
- Send
POST /mcpwith JSON-RPCinitializebefore any other MCP calls.
- Send
-
Accept header must include both content types
Accept: application/json, text/event-stream- Sending only
text/event-streamcan return406 Not Acceptable.
-
Persist and reuse session ID
- Read
mcp-session-idfrom initialize response headers. - Send
mcp-session-idon all subsequent calls. - Missing this header can return
Bad Request: Missing session ID.
- Read
-
Keep transport assumptions correct
- Streamable HTTP may return JSON or SSE frames depending on request flow.
- SSE is part of streamable HTTP behavior, not a separate transport mode.
-
TLS/self-signed handling
- For self-signed certs in POC, either:
- trust the cert/CA in the client, or
- disable verification temporarily in the MCP client for testing only (for example Node-based clients may use
NODE_TLS_REJECT_UNAUTHORIZED=0).
- This repository does not implement a server-side
MCP_VERIFY_TLSvariable.
- For self-signed certs in POC, either:
- API Explorer execution is restricted to GET-only operations in this OSS repository.
- Non-GET explorer requests (POST/PUT/DELETE/PATCH) are intentionally blocked.
- Use the private/internal repository variant if you require full CRUD explorer behavior.
Use these explorer tools as a workflow: discover -> inspect -> execute -> review analytics.
Meraki Explorer Tools
explore_meraki_api_endpoints: Natural-language search over Meraki OpenAPI endpoints to find candidate APIs by intent.get_meraki_endpoint_info: Inspect one Meraki endpoint's expected parameters/usage before execution.execute_meraki_api_endpoint: Execute a selected Meraki endpoint dynamically (GET-only in OSS), optionally scoped by organization.get_meraki_explorer_analytics: Review Meraki explorer usage patterns and success/failure rates.
Catalyst Center Explorer Tools
explore_catalyst_api_endpoints: Natural-language search over Catalyst Center OpenAPI endpoints to find candidate APIs by intent.get_catalyst_endpoint_info: Inspect one Catalyst endpoint's expected parameters/usage before execution.execute_catalyst_api_endpoint: Execute a selected Catalyst endpoint dynamically (GET-only in OSS), optionally scoped by cluster.get_catalyst_explorer_analytics: Review Catalyst explorer usage patterns and success/failure rates.
Analytics intent:
- Use explorer analytics to identify frequently explored endpoints for promotion into curated YAML tools (
*_tools.yaml). - Use explorer analytics to identify tool usage patterns (high-frequency paths, repeated failures, parameter friction) and optimize tool definitions, defaults, and documentation.
*_stdio.pyservers do not expose HTTPS listeners, so local server certs are not required.*_remote.pyservers running without TLS (http://) do not require local certs (development/testing only).*_remote.pyservers running with TLS (https://) require local cert/key files on the MCP server host (--ssl-certfileand--ssl-keyfile, orMCP_SSL_CERTFILEandMCP_SSL_KEYFILE).- If those certs are self-signed, clients must trust the cert/CA or use a temporary client-side verification bypass only for testing.
- macOS or Linux shell environment
- Python
3.10+ pipand virtual environment support (python3 -m venv)makeopenssl(for self-signed cert generation in local TLS mode)- Optional for client testing examples: Node.js +
npx - API credentials for Meraki and/or Catalyst Center
-
Environment Setup
python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt -
Configure Credentials
Create
environment.envin the repository root from template:cp environment.env.example environment.env
Then update credentials and endpoints in
environment.env. -
Run Servers (choose one mode)
Use one of the following approaches:
A) Stdio mode (good for local MCP client testing)
# Meraki (run in its own terminal session) python meraki_stdio.py # Catalyst Center (run in its own terminal session) python catalyst_center_stdio.py
B) Remote mode (HTTP/HTTPS endpoints)
# Meraki (run in its own terminal session) python meraki_remote.py --host 0.0.0.0 --port 8001 # Catalyst Center (run in its own terminal session) python catalyst_center_remote.py --host 0.0.0.0 --port 8000
Optional HTTPS (self-signed cert) for remote mode
mkdir -p certs openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes \ -keyout certs/mcp-selfsigned.key \ -out certs/mcp-selfsigned.crt \ -subj "/CN=<host-or-fqdn>" # Meraki HTTPS remote python meraki_remote.py --host 0.0.0.0 --port 8001 \ --ssl-certfile certs/mcp-selfsigned.crt --ssl-keyfile certs/mcp-selfsigned.key # Catalyst Center HTTPS remote python catalyst_center_remote.py --host 0.0.0.0 --port 8000 \ --ssl-certfile certs/mcp-selfsigned.crt --ssl-keyfile certs/mcp-selfsigned.key
-
Alternative: Start MCP Remotes with Makefile
make upperforms a restart sequence for MCP remotes (stop existing listeners, then start fresh).Optional TLS path overrides:
MCP_ENABLE_TLS=true \ MCP_SSL_CERTFILE=certs/mcp-selfsigned.crt \ MCP_SSL_KEYFILE=certs/mcp-selfsigned.key \ make up
Required API key auth on
/mcp:MCP_API_KEY=replace-with-long-random-key make up
To disable TLS for local HTTP-only testing:
MCP_ENABLE_TLS=false make up
Auto-generated cert CN behavior:
make upauto-generates withCN=localhostwhen cert files are missing.- To avoid hostname/CN mismatches, pre-create certs for your host and pass them via
MCP_SSL_CERTFILEandMCP_SSL_KEYFILE.
Before first make up, create the log directory used by the Makefile:
mkdir -p logsAfter make up, verify MCP services (HTTPS default):
make status
# Catalyst Center
curl -k -i https://127.0.0.1:8000/health
# Meraki
curl -k -i https://127.0.0.1:8001/health
# Example MCP call (Catalyst Center)
curl -k -i -H "X-API-Key: $MCP_API_KEY" -H "Accept: application/json, text/event-stream" https://127.0.0.1:8000/mcpIf you disabled TLS (MCP_ENABLE_TLS=false), use HTTP checks:
MCP_ENABLE_TLS=false make status
# Catalyst Center
curl -i http://127.0.0.1:8000/health
# Meraki
curl -i http://127.0.0.1:8001/healthExpected:
- MCP remotes on
8000/8001return200health JSON.
- API Explorer coverage relies on local OpenAPI/Swagger files in
Resources/. - OpenAPI files are intentionally not committed in this OSS repo.
- For updates, download the latest specs from Cisco DevNet and place them as follows:
- Catalyst Center: https://developer.cisco.com/docs/catalyst-center/3-1-3/overview/ ->
Resources/catalyst_center_openapi.json - Meraki: https://developer.cisco.com/meraki/api-v1/overview/ ->
Resources/meraki_openapi.json
- Catalyst Center: https://developer.cisco.com/docs/catalyst-center/3-1-3/overview/ ->
After replacing OpenAPI files, regenerate embeddings with:
# Optional: refresh local sentence-transformer model cache
python download_embeddings_model.py
# Remove old embedding caches so they are rebuilt for new OpenAPI content
rm -f embeddings_assets/catalyst_embeddings_*.pkl
rm -f embeddings_assets/meraki_embeddings_*.pkl
# Start servers once; explorers auto-rebuild embeddings from Resources/*openapi*.json
make upMeraki
Resources/meraki_tools.yaml- Meraki API endpoints and parametersResources/meraki_openapi.json- Local, user-provided Meraki OpenAPI specification (not committed)
Catalyst Center
Resources/catalyst_center_tools.yaml- Catalyst Center API endpoints and parametersResources/catalyst_center_openapi.json- Local, user-provided Catalyst Center OpenAPI specification (not committed)Resources/catalyst_config_ai_flows.yaml- Example AI flow definitions; AI flows can be developed as reusable skills
Shared
requirements.txt- Python dependencies including MCP, API clients, ML libraries
- Add new API tools in the
_toolsfiles:Resources/meraki_tools.yamlandResources/catalyst_center_tools.yaml. - Start from the corresponding OpenAPI spec (
Resources/meraki_openapi.jsonorResources/catalyst_center_openapi.json) and map the operation into a tool entry. - Parameter locations should follow OpenAPI definitions:
in: path-> required path parameters in the endpoint template.in: query-> optional/required query string parameters.in: header-> explicit headers when required by the endpoint.requestBody-> JSON/body payload fields for non-GET operations (not executed by OSS API Explorer).
- Keep parameter names/types aligned with the OpenAPI
parametersandrequestBody.content.*.schemadefinitions so tool validation matches API expectations.
Example (_tools YAML entry):
- name: list_network_devices
description: "List devices for a specific network"
endpoint: "networks/{network_id}/devices"
method: GET
parameters:
organization:
type: string
description: "Organization scope for resolution"
required: true
location: special
network_id:
type: string
description: "Network identifier from a discovery call"
required: true
location: path
perPage:
type: integer
description: "Maximum results per page"
required: false
location: queryResources/meraki_organizations.yaml - Configure multiple Meraki organizations:
meraki_organizations:
- name: "Production"
api_key_env: "MERAKI_PROD_API_KEY"
description: "Production environment networks"
enabled: true
- name: "Lab"
api_key_env: "MERAKI_LAB_API_KEY"
description: "Development and testing networks"
enabled: trueUse enabled: true or enabled: false as a simple operational switch to include or exclude an organization from active service.
Resources/catalyst_center_clusters.yaml - Configure multiple Catalyst Center clusters:
catalyst_centers:
- name: "Portland"
host: "Portland-center.domain.com"
version: "2.3.7.10"
location: "Portland"
enabled: true
- name: "San Jose"
host: "SanJose-catalyst.domain.com"
version: "2.3.7.9"
location: "San Jose"
enabled: falseUse enabled: true or enabled: false as a simple operational switch to include or exclude a cluster from active service.
Note on Catalyst credentials: the current FastMCP Catalyst flow requires shared CC_USER and CC_PASS from environment variables.
catalyst_center_clusters.yaml provides cluster host inventory/selection (including cluster="all"); CC_URL is no longer required for startup.
If you want fully YAML-driven cluster auth in the future, prefer per-cluster env references (for example username_env / password_env) and keep secrets in environment or a secret manager rather than hardcoding credentials in YAML.
Create environment.env file:
# Remote listener defaults (all interfaces for local/server hosting)
# 0.0.0.0 is for server bind/listen only; clients must connect using a real server IP or FQDN.
MCP_HOST=0.0.0.0
MCP_CATALYST_PORT=8000
MCP_MERAKI_PORT=8001
# Meraki
MERAKI_PROD_API_KEY=your_production_api_key
MERAKI_LAB_API_KEY=your_lab_api_key
# Optional Meraki API base URL (default: https://api.meraki.com/api/v1)
MERAKI_BASE_URL=https://api.meraki.com/api/v1
# Catalyst Center
CC_USER=your_username
CC_PASS=your_password
# Shared transport/security
MCP_SSL_CERTFILE=certs/mcp-selfsigned.crt
MCP_SSL_KEYFILE=certs/mcp-selfsigned.key
# Optional MCP remote API key for /mcp endpoints
MCP_API_KEY=replace_with_a_long_random_key
# Shared logging
MCP_LOG_DIR=logs
MCP_LOG_LEVEL=INFO
MCP_LOG_MODE=a
MCP_LOG_FORMAT=%(asctime)s - PID:%(process)d - %(name)s - %(levelname)s - %(message)s
MERAKI_LOG_FILE=meraki_mcp.log
CATALYST_LOG_FILE=catalyst_center_mcp.logKey packages from requirements.txt (highlights):
mcp- Model Context Protocol server frameworkhttpx- Modern HTTP client for API callssentence-transformers- AI embeddings for API explorationcatalystcentersdk- Cisco Catalyst Center Python SDKscikit-learn,numpy- ML libraries for cosine similarity search
Add to your Claude Desktop claude_desktop_config.json:
Meraki (stdio)
{
"mcpServers": {
"meraki_stdio": {
"command": "/path/to/your/venv/bin/python3",
"args": ["/path/to/your/meraki_stdio.py"]
}
}
}Catalyst Center (stdio)
{
"mcpServers": {
"catalyst_center_stdio": {
"command": "/path/to/your/venv/bin/python3",
"args": ["/path/to/your/catalyst_center_stdio.py"]
}
}
}Note: Update paths to match your actual Python virtual environment and script locations.
These examples use external Node bridge packages (npx ...-remote) to connect Claude Desktop to this repo's HTTPS MCP endpoints.
Use https:// URLs when MCP server TLS is enabled.
Catalyst Center (remote HTTPS)
{
"mcpServers": {
"catalyst_remote": {
"command": "npx",
"args": [
"mcp-remote",
"https://<host-or-fqdn>:8000/mcp"
]
}
}
}Meraki (remote HTTPS)
{
"mcpServers": {
"meraki_remote": {
"command": "npx",
"args": [
"mcp-remote",
"https://<host-or-fqdn>:8001/mcp"
]
}
}
}Use this only for local/lab testing with self-signed certificates.
Catalyst Center (testing-only bypass)
{
"mcpServers": {
"catalyst_remote": {
"command": "npx",
"args": [
"mcp-remote",
"https://<host-or-fqdn>:8000/mcp"
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}Meraki (testing-only bypass)
{
"mcpServers": {
"meraki_remote": {
"command": "npx",
"args": [
"mcp-remote",
"https://<host-or-fqdn>:8001/mcp"
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}Warning: NODE_TLS_REJECT_UNAUTHORIZED=0 disables certificate verification and is insecure. Do not use it in production.
Recommended: use certificates signed by a trusted CA (or install your internal CA) and keep TLS verification enabled.
Each server provides YAML-defined tools plus OpenAPI-based API exploration for complete network automation capabilities.