Skip to main content

CyberSPF MCP server

Lets an MCP client — Claude Desktop, an editor, an agent framework — ask CyberSPF about an IP, a domain or an ASN, list what an account monitors, and pull the graded report card.

What it is, and what it deliberately is not

It runs on the customer's machine, over stdio, calling /api/v1/ over HTTPS with their own API key.

That shape is the design, not a shortcut:

  • No new inbound surface. The droplet's only ingress stays the Cloudflare tunnel. A hosted MCP endpoint would add a second one.
  • No new authentication. ClientAPIKeyAuthentication and HasApiAccess already gate v1. This is another client of them, not a new path in.
  • No new metering. api_requests_per_day already counts these calls.
  • Nothing to operate. A process the client starts and stops.

A hosted HTTP server is worth building if customers ask for one. It is not worth building first.

Requires

A plan that includes API access, and for cyberspf_report_card, a plan that includes the report card. Those are two separate entitlements and the server reports them differently — a key that works for lookups and is refused for the card is a plan limit, not a bad key.

Install

Nothing to install — uvx fetches and runs it:

uvx cyberspf-mcp

Or into an environment you manage:

pip install cyberspf-mcp

From a checkout, for development:

cd mcp_server
python -m venv .venv
. .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Configure

Create a key in CyberSPF under Settings → Webhooks and API, then point your client at the server. For Claude Desktop, in claude_desktop_config.json:

{
  "mcpServers": {
    "cyberspf": {
      "command": "uvx",
      "args": ["cyberspf-mcp"],
      "env": {
        "CYBERSPF_API_KEY": "your key here"
      }
    }
  }
}

That form exists because the alternative was two absolute paths. A client started from a desktop launcher inherits no PATH and no working directory, and a relative path there is the commonest reason a server appears in the client list and never answers. If uvx itself is not on the launcher's PATH, give its full path.

From a checkout instead, point command at the venv's python and args at server.py — both absolute, for the same reason.

Listing

server.json is the manifest for the official MCP Registry (registry.modelcontextprotocol.io), published as com.cyberspf/mcp. The registry namespaces by reverse DNS and verifies the domain, which is why the name is the one domain we can prove.

A stdio server is listed there through a packages entry naming a package registry and an identifier — so the PyPI package is a prerequisite for the listing, not merely a convenience.

CYBERSPF_BASE_URL overrides the endpoint; it defaults to https://cyberspf.com/api/v1. Useful for pointing at a staging host and for nothing else.

The tools

Tool Answers
cyberspf_investigate start here — looks one thing up and follows what it points at, in a single call
cyberspf_lookup one IP, domain, CIDR or ASN — ordered sections of findings with severities
cyberspf_list_monitors what this account watches, and when each was last checked
cyberspf_report_card the graded assessment per monitored domain, with recommendations
cyberspf_alerts what changed, newest first — page with before, poll with since
cyberspf_threat_lists the account's threat lists, their tags and sizes
cyberspf_tag_suggestions tags already in use, so a new one is not a near-miss of an old one
cyberspf_bulk_lookup submit many terms at once; returns a job id
cyberspf_bulk_result collect a bulk job — polling is free

cyberspf_investigate and cyberspf_lookup both take detail: summary returns only findings rated bad or warn plus a count of every severity seen, which is far less to read. Investigate defaults to summary because it returns several subjects at once; lookup defaults to full.

And these change the account:

Tool Does
cyberspf_start_monitoring begin watching a domain, IP or ASN
cyberspf_stop_monitoring stop watching one
cyberspf_create_threat_list create an empty list, named, tagged and graded
cyberspf_add_to_threat_list add hosts, IPs or CIDR blocks — up to 100 a call
cyberspf_remove_from_threat_list take entries back out

Each of those says CHANGES THE ACCOUNT in its own description, and the two that remove protection — stopping a monitor, and un-flagging a threat — tell the model to confirm with the person first. A monitor that was quietly stopped does not announce itself: the next real change simply goes unreported.

It started as three, not the eight the design sketch proposed: two of those eight (zone_search and anything over new-domain data) have no data behind them — zone_domain holds zero rows since collection was paused — and the rest wrapped endpoints v1 did not expose. Three that work beat eight where five return errors.

Fourteen now, because v1 grew alerts, threat lists, monitor writes and investigate on 2026-10-03. The rule did not change, only what satisfies it: a tool ships when there is a working endpoint behind it. zone_search still has none.

Following a result instead of stopping at it

cyberspf_lookup returns the API's own sections unflattened, on purpose. Values that can themselves be looked up carry a type (ip, domain, asn, cidr), so an agent can feed one back in:

look up example.com → take the addresses it resolves to → look each up → take the ASN announcing them → look that up

That chain is the point. Flattening the response into prose for the model would read more smoothly and would throw away the one field that makes the chain possible.

Failure messages

Every failure is phrased as something a person can act on, because an agent cannot read a stack trace and cannot retry its way out of a plan limit:

Condition What the tool says
no CYBERSPF_API_KEY exits at startup, naming the setting — rather than appearing healthy and failing on first use
401 the key was rejected; check it has not been revoked
403 the key is valid, the plan does not include what was asked for
429 daily allowance used up, resets midnight UTC
timeout 45s, and says a first lookup of a cold domain can be slow before concluding it is down

A blank term is refused locally rather than sent, so it does not spend one of the account's daily calls to be told it was blank.

Nothing here probes anything

Every tool reads what CyberSPF already stored. None of them causes a connection to the subject of the lookup, from the customer's machine or from ours — the report card in particular is built from stored data, which is what makes it safe for an agent to call in a loop. Outbound probing happens elsewhere in the product, from the dedicated prober, on its own schedule.

Metadata

Release files for cyberspf-mcp 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cyberspf-mcp 0.2.0
File Size Uploaded
cyberspf_mcp-0.2.0.tar.gz 17.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cyberspf-mcp 0.2.0
File Interpreter ABI Platform
cyberspf_mcp-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.4 kB

Release files / cyberspf_mcp-0.2.0.tar.gz

Download URL cyberspf_mcp-0.2.0.tar.gz
Size 17.6 kB
Tags Source
SHA-256 checksum
How to use checksums
367ddad21d3691bd7665224d63ff1ca7873098e66640c82c22d381a0d3bdbf1b
BLAKE2b-256 checksum
How to use checksums
f2ecce09ddc07c33da5273b661571a6ee87813979410a766d372ed4861612919
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / cyberspf_mcp-0.2.0-py3-none-any.whl

Download URL cyberspf_mcp-0.2.0-py3-none-any.whl
Size 14.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
254c73dde43981cd72d8bf707da00a4b0e22204f1427d600c070d3fbff41e9b3
BLAKE2b-256 checksum
How to use checksums
b59e25de62c1bf81e295a57919f597aca787236eeaf7e7b6b35edf96e9f1ba4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page