packetfabric-mcp
MCP server for the PacketFabric API, built from its OpenAPI spec
(346 operations, bundled in src/packetfabric_mcp/data/openapi.yaml).
Instead of one tool per endpoint (which overwhelms the model), it exposes 16 tools:
| Tool | What it does |
|---|---|
pf_get_account |
Current customer account — good credential check |
pf_list_ports, pf_get_port |
Ports / LAGs / cloud ports |
pf_list_services |
Virtual circuits (backbone, cloud, IX, marketplace) |
pf_list_point_to_point |
PTP services |
pf_list_cloud_routers, pf_list_cloud_router_connections |
Cloud Routers and their connections |
pf_list_cloud_connections |
L2 hosted / dedicated cloud connections |
pf_find_locations |
POPs / data centers |
pf_get_pricing |
List pricing (MRC/NRC) between locations |
pf_get_traffic |
bps/pps time series for a port or a VC on a port |
pf_get_maintenances |
Current/upcoming maintenance by POP or market |
pf_list_api_areas → pf_search_endpoints → pf_describe_endpoint → pf_call_endpoint |
Reach any other endpoint in the spec |
Safety
- Read-only by default. Any POST/PUT/PATCH/DELETE is refused unless the server runs with
PF_ALLOW_WRITES=true. - With writes enabled, a write call returns a dry-run preview first; it only executes when re-called with
confirm=true. - Auth/session, MFA, signup and API-key-management endpoints are never exposed.
- List responses are capped (
max_items, default 100) and can be trimmed to specificfields.
Setup
Requires uv (brew install uv).
cd ~/Documents/src/packetfabric/mcp
uv sync
uv run pytest # offline tests
Get an API key in the PacketFabric portal (Settings → API Keys). API keys work with MFA-enabled accounts; login/password does not.
Claude Code
claude mcp add packetfabric -s user -e PF_TOKEN=your-key -- \
uv run --directory ~/Documents/src/packetfabric/mcp packetfabric-mcp
Claude Desktop / Cowork
Settings → Developer → Edit Config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"packetfabric": {
"command": "/opt/homebrew/bin/uv",
"args": ["run", "--directory", "/Users/chad/Documents/src/packetfabric/mcp", "packetfabric-mcp"],
"env": { "PF_TOKEN": "your-key" }
}
}
}
(Use which uv for the command path. Restart Claude after editing.)
To allow provisioning, add "PF_ALLOW_WRITES": "true" to env. Consider a separate server entry
(e.g. packetfabric-rw) so read-only stays the default.
Configuration
| Env var | Purpose |
|---|---|
PF_TOKEN |
API key (sent as Bearer). Preferred. |
PF_LOGIN / PF_PASSWORD |
Alternative to PF_TOKEN; auto re-login on 401 |
PF_ALLOW_WRITES |
true to allow create/modify/delete (each still needs confirm=true) |
PF_ON_BEHALF |
Resellers: customer UUID sent as On-Behalf header |
PF_API_URL |
Override base URL (default https://api.packetfabric.com) |
PF_SPEC_PATH |
Use a different OpenAPI file |
PF_TIMEOUT, PF_MAX_RESPONSE_CHARS |
HTTP timeout (s, default 60) and response size cap (default 60000) |
Hosted mode (MCP over HTTP + A2A + discovery)
uv sync --extra a2a
PF_PUBLIC_URL=https://mcp.example.com uv run packetfabric-mcp --http --host 0.0.0.0 --port 8765
# or: docker build -t packetfabric-mcp . && docker run -p 8765:8765 -e PF_PUBLIC_URL=... packetfabric-mcp
| Path | What |
|---|---|
POST /mcp |
MCP streamable HTTP (stateless, so it scales horizontally) |
GET /mcp/server-card |
MCP Server Card (SEP-2127) |
GET /.well-known/agent-card.json |
A2A v1.0 Agent Card |
POST /a2a |
A2A JSON-RPC endpoint |
GET /.well-known/ai-catalog.json |
AI Catalog listing both cards |
GET /healthz |
Liveness |
Every caller uses their own PacketFabric API key, sent as Authorization: Bearer <key> (plus
On-Behalf: <customer uuid> for resellers). The operator's PF_TOKEN/PF_LOGIN are ignored in HTTP mode
unless PF_HTTP_USE_SERVER_CREDENTIALS=true, which is only safe for a private single-user deployment.
Put it behind TLS; the discovery documents are public by design and contain no secrets.
The A2A agent is deterministic, not an LLM: send a DataPart {"skill": "list_ports", "arguments": {"pop": "LAX1"}}
and get the API result back as a JSON data artifact. Skills mirror the MCP tools (see the agent card).
A2A access is always read-only.
curl -s https://mcp.example.com/a2a -H 'A2A-Version: 1.0' -H 'Content-Type: application/json' \
-H "Authorization: Bearer $PF_TOKEN" -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":
{"messageId":"1","role":"ROLE_USER","parts":[{"data":{"skill":"find_locations","arguments":{"market":"NYC"}}}]}}}'
| Env var (HTTP mode) | Purpose |
|---|---|
PF_PUBLIC_URL |
Public https base URL advertised in the cards (otherwise derived from the request) |
PF_HTTP_USE_SERVER_CREDENTIALS |
true = fall back to the operator's own credentials (private use only) |
PF_DISABLE_A2A |
true = serve MCP only |
PF_ICON_URL |
Icon advertised in the cards |
Domain-level discovery: if the server runs on its own host (e.g. mcp.packetfabric.com), the
/.well-known/ documents are already in the right place. To advertise it from the main domain, serve a copy of
/.well-known/ai-catalog.json from https://packetfabric.com/.well-known/ai-catalog.json (the entries hold
absolute URLs, so a static copy works).
Publishing
Listed on the MCP Registry as
io.github.PacketFabric/packetfabric-mcp (see server.json), installed from PyPI as packetfabric-mcp.
- Bump the version in
pyproject.toml,src/packetfabric_mcp/__init__.pyandserver.json(tests fail if they disagree). - Push a tag
vX.Y.Z..github/workflows/publish.ymlruns the tests, publishes to PyPI (Trusted Publishing), then publishesserver.jsonto the MCP Registry using GitHub OIDC. - Once the hosted server is live, set the repo variable
MCP_PUBLIC_URLand the registry entry will also list it as a remote.
One-time: add a PyPI Trusted Publisher for packetfabric-mcp (repo PacketFabric/public-mcp, workflow
publish.yml, environment pypi). The mcp-name: comment at the top of this README is how the registry verifies
that the PyPI package belongs to this server; keep it.
To publish under com.packetfabric/... instead of io.github.PacketFabric/..., change REGISTRY_NAME in
metadata.py and server.json, add the DNS TXT record from mcp-publisher login dns, and switch the
workflow's login step.
Other
- Refresh the bundled spec:
uv run packetfabric-mcp --update-spec - To add a curated tool, copy one of the
pf_list_*functions inserver.pyand point_run()at anoperation_id(find one withpf_search_endpoints). Add a matching entry toSKILLSina2a_agent.py.
Metadata
Release files for packetfabric-mcp 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| packetfabric_mcp-0.2.1.tar.gz | 222.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| packetfabric_mcp-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 357.6 kB
Release files / packetfabric_mcp-0.2.1.tar.gz
| Download URL | packetfabric_mcp-0.2.1.tar.gz |
|---|---|
| Size | 222.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ef4fc9160679d3523a8b15fce8adcf57e768e83bb51dccf69d4077f21963ccc9
|
|
BLAKE2b-256 checksum How to use checksums |
4678541c81df64481a2fb1c703bf88ef47398cacbd4d68058692fdd8e0cfb10b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logRelease files / packetfabric_mcp-0.2.1-py3-none-any.whl
| Download URL | packetfabric_mcp-0.2.1-py3-none-any.whl |
|---|---|
| Size | 135.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e98aa65373001a0ad035cccd09e6b5789c4f034a86182f3b1e0c3ce260f0a332
|
|
BLAKE2b-256 checksum How to use checksums |
df15beb56e37efcc20fb59df46743f8eda825ff78830bb22489df4b6a1082fe4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency log