recon-mcp
An MCP server providing 15 OSINT tools over free, public sources for AI agents, enabling domain reconnaissance, subdomain discovery, DNS lookups, host profiling, CVE search, and more without API keys.
README
recon-mcp
An MCP server that gives an AI agent 15 OSINT tools over free, public sources. No API keys, no accounts, no signup — every source here answers unauthenticated.
It is also a worked example of what changes when an MCP server has to survive real use rather than a demo: response shaping, context budgeting, per-endpoint retry policy, and composite tools that collapse a predictable ten-call sequence into one.
"Map the attack surface of github.com"
→ recon_domain("github.com") one call
→ 139 subdomains from Certificate Transparency
→ 6 of them still resolve, checked in parallel
→ 12 addresses profiled for open ports and known CVEs
That is a real run, not an illustration. It took ~2 minutes, nearly all of it waiting on crt.sh — certificate transparency is the slow leg on any busy domain. The win here is call count, not latency: the same picture assembled tool-by-tool costs twenty-plus round trips with the model deciding the obvious next step between each one.
Install
git clone https://github.com/<you>/recon-mcp && cd recon-mcp
python -m venv .venv && . .venv/bin/activate
pip install -e .
Register it with any MCP client. For Claude Desktop / Claude Code:
{
"mcpServers": {
"recon": {
"command": "/absolute/path/to/recon-mcp/.venv/bin/recon-mcp"
}
}
}
That is the whole setup. There is no configuration file and nothing to authenticate.
Tools
| Tool | Answers |
|---|---|
recon_domain |
Full first pass: CT → DNS → host exposure, one call |
crt_subdomains |
Subdomains from Certificate Transparency logs |
crt_certificates |
Raw CT entries — issuer, validity, SANs |
dns_records |
A/AAAA/CNAME/MX/NS/TXT/SOA in one parallel call |
dns_lookup |
One specific record type |
dns_reverse |
PTR for an IPv4 address |
host_profile |
Shodan InternetDB: ports, hostnames, tags, CVEs |
host_ports |
Just the open ports |
host_vulns |
Just the CVEs, with a false-positive warning |
cve_lookup |
One CVE: CVSS score, vector, description |
cve_search |
CVEs by keyword, newest first |
rdap_domain |
Registration data: dates, registrar, nameservers |
rdap_ip |
Netblock owner, range, country |
wayback_urls |
Historical URLs archived under a domain |
wayback_snapshots |
Snapshots of one URL over time, with digests |
Sources: crt.sh, Cloudflare & Google DNS-over-HTTPS, Shodan InternetDB, NVD, RDAP, Wayback Machine.
Design notes
The parts that took iteration, and why they ended up this way.
One envelope, including on failure
Every tool returns the same shape:
{
"ok": true,
"status": 200,
"data": {},
"pivots": {"hosts": [], "ips": [], "emails": [], "urls": []},
"truncated": false,
"hint": "..."
}
Tools that each invent their own result format make the model rediscover structure on every call. Errors keep the shape too — a tool that returns a bare string on failure forces the agent to branch on type before it can read anything.
hint carries what a status code cannot: that a 404 from Shodan means "never
crawled, probably nothing exposed" rather than "broken", or that CVE lists
from banner matching produce false positives when patches are backported.
Compaction is the default, full is opt-in
Recon endpoints answer big. A CT query on an active domain returns tens of
thousands of rows; handing that to a model ends the session. Lists are cut to
25 items and strings to 6000 characters, recursively, with truncated set so
nothing silently disappears. Any tool takes full: true when the caller
genuinely wants everything.
The budget is deliberately tight. An agent can always ask for more — it cannot un-blow its context window.
pivots — the next hop without a parse step
Every response harvests hostnames, IPs, emails and URLs out of the payload. The identifiers worth querying next live in unpredictable places: a hostname appears in a certificate subject, a redirect target and a PTR record, none of which share a key name. Harvesting them centrally means the agent chains lookups instead of parsing prose to find something to look up.
Retry budgets per endpoint
One retry policy for every source is wrong in both directions. crt.sh is slow and gateway-errors under load: long timeout, few retries, patience. NVD rate-limits unauthenticated callers to roughly five requests per 30 seconds: back off hard, cache for an hour. DNS is fast and cheap: short timeout, retry immediately against the spare resolver.
Retrying a known-broken endpoint four times turns one bad call into forty seconds of an agent sitting still — which the user experiences as the tool being broken.
Composite tools
An opening pass over a domain is always the same sequence, and the model's
"reasoning" between the steps adds nothing while the latency is real.
recon_domain runs it in-process with the fan-out parallelised: ~15 calls
become 1. The per-source tools stay available for drilling into whatever the
overview surfaces.
Its host_limit cap is the important part. Some domains have thousands of
subdomains; resolving all of them would mean thousands of DNS queries and a
result nobody can read. The tool takes the most promising ones, says how many
it skipped, and lets the caller go deeper deliberately.
Failures stay inside the tool
An unhandled exception in a handler propagates as a protocol error and, depending on the client, kills the connection or leaves the agent with no idea what happened. Everything is caught at the boundary and returned as a normal failure envelope: a broken tool costs one turn, not the session.
Logging goes to stderr, never stdout — stdout carries the MCP protocol, and a stray log line there corrupts the stream in a way that is unpleasant to debug from the client side.
Scope and use
This queries public databases about internet-facing infrastructure. It sends no traffic to the targets themselves: certificate logs, passive DNS, archived crawls and an existing scan index. That makes it safe for attack-surface mapping, asset inventory and pre-engagement research.
It is not a scanner and does not confirm anything. CVEs from Shodan are inferred from banners and go stale; archived URLs may be long gone. Everything here is a lead to verify, not a finding to report.
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.