Skip to main content
Glama
Antobh36

Threat Intel MCP Server

by Antobh36

Threat Intel MCP Server

This MCP server is designed so an agent can use various threat intelligence platforms like VirusTotal, Shodan, and more. It is still a work in progress. So far I have made 27 tools across VirusTotal, AbuseIPDB, Shodan, GreyNoise, urlscan.io, and DNS. GreyNoise has 2 functions: one for the community API, and one for the enterprise API if you have a trial. Only the community one is registered as a tool. There are also 4 "enrich" tools that ask every provider at once and merge the answers, for an IP, a domain, a URL, or a file.

Email security tools

Five of the tools check DNS instead of a threat feed: dns_lookup_mx, dns_lookup_spf, dns_lookup_dmarc, dns_lookup_dkim, and email_security_audit. The audit runs all four checks at once and grades the domain out of 100 (SPF 30, DMARC 40, DKIM 20, MX 10), returning findings with a severity and a suggested fix for each one. DKIM is the awkward one: selectors cannot be listed from DNS, so the audit probes common selector names, and when none of them answer it drops DKIM from the score entirely and scores the domain out of 80 rather than failing it unfairly. These run over DNS-over-HTTPS, so they need no API key at all.

Running it

Copy .env.example to .env and fill in whichever keys you have: VT_API_KEY, ABUSEIPDB_API_KEY, URLSCAN_API_KEY, SHODAN_API_KEY. None of them are mandatory, you just get fewer tools. GREYNOISE_KEY is optional too because the community API works without one.

Real environment variables take priority over .env, so an MCP client can pass the keys in its own config instead.

Locally, over stdio, which is what Claude Desktop and the IDE extensions use:

pip install -r requirements.txt
python threat_intel_server.py

With Docker, over HTTP on port 8000:

docker build -t threat-intel-mcp .
docker run --rm --env-file .env -p 8000:8000 threat-intel-mcp

Add -i -e MCP_TRANSPORT=stdio if you want the container to speak stdio instead.

NOTES:

  • This project is mostly for learning purposes.

  • The project is a work in progress, so some functions may not work as intended.

  • Each platform has a class in providers.py that holds its base URL, its authentication, and its rate limit.

  • Keys are optional one at a time. If a key is missing, that platform's tools are simply not registered and the rest of the server still runs, so you can start with one key and add the others later. The server prints to stderr which tools it skipped.

  • With no keys at all you still get 8 tools, because the DNS lookups and the GreyNoise community API work without one.

  • Every tool is marked read-only and validates its input before spending an API call, so a malformed IP or domain is rejected locally instead of burning quota.

  • All the providers report failures the same way, as an MCP error carrying a code like invalid_argument, rate_limited, forbidden or unauthorized.

  • Never commit your .env. It is in .gitignore and .dockerignore, so the keys stay out of the repo and out of the image.

  • There is a Dockerfile now, but I haven't published the image anywhere until I am satisfied with the project.