The DomainTools MCP Server enables Large Language Models (LLMs) to access domain threat information through the Model Context Protocol (MCP).
MCP is an open standard that allows LLM applications to securely connect to external data sources and tools. This integration brings DomainTools domain intelligence directly into your AI-powered workflows, enabling natural language investigation of suspicious domains, infrastructure mapping, and threat analysis.
Connect using your own MCP-compatible AI client.
The server provides specialized tools spanning Iris Investigate, Farsight DNSDB passive DNS, and domain history data for domain lookups, pivot searches, passive DNS analysis, and historical investigation.
## How it works
DomainTools hosts and operates the MCP Server — there's nothing to install or run on your end. Your MCP-compatible AI client connects to the server over HTTPS at https://api.domaintools.com/v1/mcp using your DomainTools API key. The client handles the conversation with the LLM; the MCP Server handles the data. All communication between your client and the server is encrypted using TLS 1.3.
## Quick start
Already have an MCP-compatible client and a DomainTools API key? This quick start shows you how to connect Claude Code CLI to the DomainTools MCP Server and run your first query. Full configuration instructions are in the Get started guide. For credential details and how MCP auth compares to the Python SDK and direct API, see Authentication.
Set your API key and add the MCP Server to Claude Code CLI:
```bash
export DOMAINTOOLS_API_KEY="your-api-key"
claude mcp add --transport http domaintools-mcp \
https://api.domaintools.com/v1/mcp \
--header "X-Api-Key: ${DOMAINTOOLS_API_KEY}"
```
Restart your client and test the connection by asking Claude to investigate a domain:
```text
Tell me everything you can about the domain domaintools.com
```
## What you get with the MCP Server
The MCP Server exposes tools from three DomainTools platforms:
### Iris Investigate
Iris Investigate is DomainTools' deep analysis platform for mapping adversary infrastructure. It provides domain intelligence from DNS, passive DNS, domain registration data (WHOIS/RDAP), TLS certificates, website content, screenshots, and predictive risk scoring. The MCP Server exposes 7 Iris tools for domain lookups, pivot searches, and infrastructure analysis.
### DNSDB
Farsight DNSDB is a passive DNS database containing historical and real-time DNS records observed across global sensor networks. The MCP Server exposes 4 DNSDB tools for forward lookups, inverse lookups, and pattern-based searches across billions of DNS records.
### Domain History
Domain History APIs provide timestamped change records for domain registration, infrastructure, and website data. The MCP Server exposes 4 history tools for tracking how domains evolve over time, including deep WHOIS history for records predating 2022.
### MCP-optimized responses
MCP tool responses are optimized for LLM consumption. They return a relevant subset of each product's data with empty fields removed and structures flattened to reduce token usage.
The REST APIs return the full dataset for programmatic parsing — the right choice when you need every field or are building a traditional integration. The MCP Server returns LLM-sized subsets with context logic that helps models correctly interpret risk signals and DNS relationships. Use the REST APIs when you need the raw data; use the MCP Server when you want an LLM to reason over it.
## Key use cases
Security analysts and threat researchers can use the MCP Server to:
- Investigate suspicious domains with threat intelligence
- Discover related infrastructure through pivot searches
- Query historical and real-time passive DNS records
- Build timelines of domain registration, infrastructure, and website changes
- Assess domain risk at scale with bulk lookups
## Prerequisites
Before you connect to the DomainTools MCP Server, you need the following:
### Your own MCP-compatible client
DomainTools provides the MCP Server, but you must bring your own MCP-compatible LLM client. The client must support:
- Streamable HTTP transport for MCP connections (STDIO (Standard Input/Output) transport requires the server to run as a local process on the same machine; it can't connect to a remotely hosted service)
- Custom HTTP headers (specifically X-Api-Key) for API key authentication, or OAuth 2.0 with pre-registered credentials
- MCP tools
The server also exposes two MCP Resources (docs://usage-guide and docs://field-reference) that provide your AI client with built-in guidance on tool usage and response interpretation. Clients that support MCP Resources will load these automatically.
The following clients are supported for the DomainTools MCP Server. Each supports API key authentication, OAuth, or both — follow the linked setup steps for your client.
| Client | API key | OAuth |
|---|---|---|
| ChatGPT app | Setup | — |
| Claude Code CLI | Setup | Setup |
| Claude Desktop | Setup | Setup |
| Cline | Setup | — |
| Codex (CLI and Desktop) | Setup | — |
| Cursor | Setup | Setup |
| Gemini CLI | Setup | Setup |
| VS Code with GitHub Copilot (1.99+) | Setup | Setup |
Any MCP-compatible client that meets the requirements above should work, even if not listed. See the MCP clients directory for a community-maintained list. If you encounter issues with a specific client, contact your DomainTools representative.
### DomainTools API credentials
You must be provisioned for the DomainTools MCP Server, plus the DomainTools products you want to use. The available tools depend on your account entitlements:
- Iris Investigate: required for domain lookup, pivot, evaluate, and history tools
- Farsight DNSDB: required for passive DNS tools
To get provisioned, contact your DomainTools representative or email enterprisesupport@domaintools.com.
After provisioning, an organization admin must delegate MCP access to each user before they can connect:
1. The admin signs in and goes to the Group Admin page.
2. In the user list, select the Enabled checkbox next to the user's DomainTools username.
3. After the admin enables access, retrieve your API key at the account dashboard.
### Network access
Your client must be able to connect to the hosted MCP Server endpoint at https://api.domaintools.com/v1/mcp.
The MCP Server is fully hosted, so there are no server-side components to install or manage. You only need a compatible MCP client on your local machine.
## Understand authentication
The DomainTools MCP Server supports two authentication modes:
- API key authentication: pass your DomainTools API key in an X-Api-Key HTTP header. It's the fastest path to a working connection and is available for most clients. See the client table for per-client support.
- OAuth authentication: your MCP client redirects you to sign in with your DomainTools account, using pre-registered credentials. Requires a registration step with DomainTools. See the client table for which clients support it.
During the MCP initialize handshake, the server validates your credentials by making a request to the DomainTools /v1/account endpoint. For how MCP credentials compare to the Python SDK and direct API authentication, see Authentication.
## Verify that the connection works
After adding the server, verify that the tools are available:
1. Start a new conversation in your MCP client
2. Ask: "What tools are available?"
3. Confirm you see tools listed, including lookup_single, lookup_bulk, evaluate, pdns_lookup_rrset, and registration_history
Try a domain lookup:
```text
Look up threat intelligence for example.com using the lookup_single tool
```
The response includes domain data such as risk score, registration details, DNS records, and more.
## Troubleshooting
If you have trouble connecting to the MCP Server or using its tools, check these common issues.
### 401 Unauthorized
An HTTP 401 response indicates your API key or OAuth credentials are missing or invalid. Verify your key at your account dashboard and confirm you're passing it correctly in the X-Api-Key header, or that your OAuth registration is active.
### 403 Forbidden
An HTTP 403 response indicates your API account is not authorized for the requested product. Each tool category requires its own product entitlement (see API credentials). Contact your DomainTools representative to verify your account entitlements.
### Tools not appearing in your client
- Confirm your client supports Streamable HTTP transport. Clients that only support the legacy SSE or STDIO transports cannot connect.
- Check that the server URL is exactly https://api.domaintools.com/v1/mcp with no trailing slash.
- Restart your client or start a new session after adding the server configuration.
### Connection timeouts
If requests time out, verify that your network allows HTTPS connections to api.domaintools.com. Corporate proxies, VPNs, and firewalls may block the connection.
### Rate limiting
The MCP Server enforces a rate limit of 10 requests per second per API key, with a burst capacity of 20. If you exceed this limit, the server throttles requests.
Individual DomainTools products (Iris Investigate, DNSDB, etc.) also enforce their own rate limits and query quotas. If a tool call fails due to a product-level limit, the error message will indicate the source. Check your account dashboard for your current quota usage.
## Next steps
- API key authentication: per-client setup with X-Api-Key header
- OAuth authentication: pre-registered OAuth credentials
- MCP tools reference: browse all available tools and usage examples
- MCP Server FAQ: security, data handling, and common questions
The DomainTools MCP Server authenticates requests using an X-Api-Key HTTP header. This page shows you how to configure supported MCP clients with your API key.
For OAuth pre-registration instead, see OAuth authentication.
For how MCP credentials compare to the Python SDK and direct API authentication, see Authentication.
## Before you begin
- An MCP-compatible client (prerequisites)
- A DomainTools API key (retrieve at your account dashboard)
Before you can retrieve a key for MCP access, your organization admin must enable your account on the Group Admin page. See DomainTools API credentials for the full delegation steps.
Store your API key in an environment variable rather than hardcoding it in configuration files. This keeps secrets out of version control and makes rotation easier. For storage trade-offs and rotation guidance, see Storing credentials securely.
```bash
export DOMAINTOOLS_API_KEY="your-api-key"
```
## Environment variable syntax by client
Each example below references the DOMAINTOOLS_API_KEY environment variable, but the syntax varies by client:
| Client | Syntax in config | Resolved by |
|---|---|---|
| ChatGPT app | Env var name (Headers from env) | The app |
| Claude Code CLI | ${DOMAINTOOLS_API_KEY} | Your shell |
| Claude Desktop | env block (via mcp-remote) | mcp-remote |
| Cline | ${env:DOMAINTOOLS_API_KEY} | The client |
| Codex CLI | env_http_headers field | The client |
| Cursor | ${env:DOMAINTOOLS_API_KEY} | The client |
| Gemini CLI | $DOMAINTOOLS_API_KEY | The client |
| VS Code | ${env:DOMAINTOOLS_API_KEY} | The client |
The Cline, Cursor, VS Code, Gemini CLI, Codex CLI, and ChatGPT app examples resolve the variable at runtime, so your API key stays out of configuration files. The Claude Code CLI example uses shell expansion, so the resolved key is stored in the config, but it's still read from the environment variable you set earlier. The Claude Desktop mcp-remote bridge stores the key as a literal string; see that section for hardening guidance.
## Configure your client
Note:
MCP client interfaces and configuration formats are evolving rapidly. The steps on this page are accurate as of publication and we do our best to keep them updated. If you need help, contact your DomainTools representative.
### ChatGPT app
The ChatGPT desktop app has a Codex tab and a ChatGPT tab at the top; both share the same MCP configuration, so a server you add here is available across both surfaces. The app connects to a remote MCP server directly over Streamable HTTP with header-based authentication, so you can use your DomainTools API key without OAuth registration.
1. Open Settings > Plugins, then select the MCPs tab.
2. Click + Add server to open Connect to a custom MCP.
3. Enter a Name (for example, domaintools).
4. Set Type to Streamable HTTP.
5. In the URL field, enter https://api.domaintools.com/v1/mcp.
6. Under Headers, add a header with the Key X-Api-Key and the Value set to your DomainTools API key.
7. Click Save, then enable the server's toggle in the MCPs list.
Leave the Bearer token env var field blank: the DomainTools MCP Server authenticates with the X-Api-Key header, not a bearer token.
Entering the key under Headers stores it in the app's configuration. To keep the key out of that config, use the Headers from environment variables section instead, with the Key X-Api-Key and the Value DOMAINTOOLS_API_KEY (the name of the environment variable that holds your key). The app resolves the variable at connection time. Because apps launched from the macOS Dock or Finder don't inherit your shell environment, the variable must be visible to the app; launch it from a terminal where DOMAINTOOLS_API_KEY is exported.
### Claude Code CLI
Run the following command in your terminal:
```bash
claude mcp add --transport http domaintools-mcp \
https://api.domaintools.com/v1/mcp \
--header "X-Api-Key: ${DOMAINTOOLS_API_KEY}"
```
The shell expands ${DOMAINTOOLS_API_KEY} when you run the command. This adds the server to your user-level configuration. To scope the server to a specific project instead, add --scope project.
### Claude Desktop
Claude Desktop's Custom Connectors UI only accepts OAuth Client ID/Secret: there's no field for a plain header value, so API key authentication needs a bridge. (For the OAuth path, see Claude Desktop on the OAuth page.) Editing claude_desktop_config.json directly with a url/headers shape doesn't work either: its mcpServers block only runs local STDIO servers (command/args/env), and Claude Desktop rejects any entry shaped otherwise.
To use API key authentication with Claude Desktop, bridge through mcp-remote, a community-maintained stdio-to-HTTP proxy that Claude Desktop can run as a local process. Add the following to claude_desktop_config.json (Settings > Developer > Edit Config):
```json
{
"mcpServers": {
"domaintools": {
"command": "npx",
"args": [
"mcp-remote",
"https://api.domaintools.com/v1/mcp",
"--header",
"X-Api-Key: ${DOMAINTOOLS_API_KEY}"
],
"env": {
"DOMAINTOOLS_API_KEY": "YOUR_API_KEY"
}
}
}
}
```
Replace YOUR_API_KEY with the API key from your account dashboard. Restart Claude Desktop after saving the file.
mcp-remote is a third-party tool, not built or supported by DomainTools. Treat it as a workaround rather than an officially supported path; a Claude Desktop or mcp-remote update could change this behavior. The mcp-remote bridge is the only way to reach API key authentication from Claude Desktop, and it's unsupported by both DomainTools and Anthropic.
### Cline
In the Cline VS Code extension or CLI settings, add the following MCP Server configuration:
```json
{
"mcpServers": {
"domaintools": {
"disabled": false,
"timeout": 15,
"type": "streamableHttp",
"url": "https://api.domaintools.com/v1/mcp",
"headers": {
"X-Api-Key": "${env:DOMAINTOOLS_API_KEY}"
}
}
}
}
```
Cline resolves ${env:DOMAINTOOLS_API_KEY} from your environment when the server connects.
### Codex CLI
Codex MCP documentation
Codex CLI supports environment variable indirection for header values via the env_http_headers field. This keeps the API key out of your config file.
Add the following to your ~/.codex/config.toml file:
```toml
[mcp_servers.SERVER_ALIAS]
url = "https://api.domaintools.com/v1/mcp"
env_http_headers = { "X-Api-Key" = "DOMAINTOOLS_API_KEY" }
```
Replace SERVER_ALIAS with any name of your choice. The value DOMAINTOOLS_API_KEY is the name of the environment variable Codex reads at runtime; make sure it's set in your shell. See Codex MCP headers for the distinction between http_headers (static values) and env_http_headers (environment variable names).
### Cursor
Add the following to your .cursor/mcp.json file:
```json
{
"mcpServers": {
"domaintools": {
"url": "https://api.domaintools.com/v1/mcp",
"headers": {
"X-Api-Key": "${env:DOMAINTOOLS_API_KEY}"
}
}
}
}
```
Cursor resolves ${env:DOMAINTOOLS_API_KEY} from your environment when the server connects. Cursor also supports OAuth pre-registration; see Cursor on the OAuth page.
### Gemini CLI
Add the following to your ~/.gemini/settings.json file:
```json
{
"mcpServers": {
"domaintools": {
"httpUrl": "https://api.domaintools.com/v1/mcp",
"headers": {
"X-Api-Key": "$DOMAINTOOLS_API_KEY"
}
}
}
}
```
Gemini CLI expands $DOMAINTOOLS_API_KEY from your environment when settings are loaded. The ${DOMAINTOOLS_API_KEY} syntax also works.
### VS Code with GitHub Copilot
VS Code 1.99 and later supports MCP servers through GitHub Copilot's agent mode. Add the following to your workspace's .vscode/mcp.json file:
```json
{
"servers": {
"domaintools": {
"type": "http",
"url": "https://api.domaintools.com/v1/mcp",
"headers": {
"X-Api-Key": "${env:DOMAINTOOLS_API_KEY}"
}
}
}
}
```
VS Code resolves ${env:DOMAINTOOLS_API_KEY} from your environment when the server connects.
### Other clients
Most MCP clients use a JSON configuration with the same core fields. If your client isn't listed above, adapt this general pattern and replace YOUR_API_KEY with the API key value from your account dashboard:
```json
{
"mcpServers": {
"domaintools": {
"url": "https://api.domaintools.com/v1/mcp",
"headers": {
"X-Api-Key": "YOUR_API_KEY"
}
}
}
}
```
Common variations between clients include the top-level key name (mcpServers vs servers), the transport type field (type, transport), and the URL field (url vs httpUrl). Check your client's documentation for the exact format and whether it supports environment variable interpolation.
## Verify the connection
See Verify that the connection works on the Get Started page.
## Related pages
- Get started with the MCP Server: prerequisites and verification
- OAuth authentication: pre-registered OAuth credentials for Claude Code, Claude Desktop, Cursor, Gemini CLI, VS Code
- MCP Server tools reference
- MCP Server FAQ
The DomainTools MCP Server supports OAuth 2.0 authentication with pre-registered client credentials. Your MCP client redirects you to sign in with your DomainTools account.
For clients that don't support OAuth pre-registration (Cline, Codex, ChatGPT app), see API key authentication. Claude Desktop supports both: use OAuth here, or the API key bridge on that page.
DomainTools does not support Dynamic Client Registration. Every MCP client must be pre-registered by DomainTools before it can complete the OAuth flow.
## OAuth vs API key
Both authentication modes have equal access to MCP Server tools. Choose OAuth when you want per-user sign-in tied to a DomainTools account, or when your security policy prefers token-based flows over a static header. Choose API key authentication when you want the fastest path to a working connection, or when your client isn't in the pre-registration clients list.
## Before you begin
Contact your DomainTools representative or email enterprisesupport@domaintools.com to request OAuth credentials. Before you contact DomainTools:
1. Choose one or more clients from the pre-registration clients list below.
2. Identify the redirect URI for each client. See the client-specific sections for details.
3. (Optional) Propose a client name for each registration. If you don't, DomainTools generates one. The name is a human-readable label in DomainTools' registry: it identifies your entry in support requests but is not sent during the OAuth flow, so you can use the same label on both sides or diverge if needed.
4. Include the redirect URIs and any proposed client names in your request.
### Email template
Copy, fill in, and send the following to enterprisesupport@domaintools.com:
```text
Subject: MCP Server OAuth registration request
Company / account:
Primary contact:
MCP client(s):
For each client, provide:
- Redirect URI(s) — see the client-specific sections in
https://docs.domaintools.com/mcp/oauth/
- Proposed client name (optional)
Notes:
```
DomainTools will provide you with:
- The confirmed client name for your registration
- A client ID and client secret for OAuth authentication
Store the client secret like any other credential. Don't commit it to source control. See the per-client sections for guidance on keeping it out of config files where the client supports environment-variable interpolation.
## Pre-registration clients
Note:
MCP client interfaces and configuration formats are evolving rapidly. The steps on this page are accurate as of publication and we do our best to keep them updated. If you need help, contact your DomainTools representative.
The following MCP clients support pre-registered credentials. Each has its own redirect URI format and configuration method.
The CLIENT_NAME placeholder in the examples below is a local label only: it identifies the server entry inside your client's config. The authorization server validates connections by client ID, client secret, and registered redirect URI, not by this name. Use any label you like, though matching the name DomainTools confirmed in your registration response makes support requests easier to trace.
### Claude Code
Claude Code documentation
By default, Claude Code uses a random port for its redirect URI. To use OAuth with DomainTools, configure a fixed callback port so the redirect URI is consistent.
Pick a fixed port (for example, 61264) and provide the following redirect URI during registration:
```text
http://localhost:61264/callback
```
Add the MCP Server with the --callback-port option:
```shell
claude mcp add CLIENT_NAME https://api.domaintools.com/v1/mcp \
--transport http \
--callback-port 61264 \
--client-id CLIENT_ID \
--client-secret CLIENT_SECRET
```
Replace CLIENT_NAME with the registered client name.
### Claude Desktop
Claude Desktop Custom Connectors documentation
Claude Desktop uses a static redirect URI. Provide the following during registration:
```text
https://claude.ai/api/mcp/auth_callback
```
Claude Desktop's Custom Connectors support pre-registered credentials via the Advanced settings section.
To configure a custom connector:
1. Open Claude > Settings > Connectors > Add custom connector.
2. Enter the registered client name in the Name field, and fill out the Remote MCP server URL field.
3. Click Advanced settings, then fill out the OAuth Client ID (optional) and OAuth Client Secret (optional) fields with the values provided by DomainTools.
4. Click Add.
To trigger the OAuth flow, click the overflow menu (⋯) next to the MCP server's name in the Connectors list and select Connect.
### Cursor
Cursor documentation
Cursor uses a static redirect URI. Provide the following during registration:
```text
cursor://anysphere.cursor-mcp/oauth/callback
```
Add the following to your .cursor/mcp.json file:
```json
{
"mcpServers": {
"CLIENT_NAME": {
"type": "http",
"url": "https://api.domaintools.com/v1/mcp",
"auth": {
"CLIENT_ID": "YOUR_CLIENT_ID",
"CLIENT_SECRET": "YOUR_CLIENT_SECRET"
}
}
}
}
```
Replace CLIENT_NAME with the registered client name. Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the credentials provided by DomainTools.
Tip: Keep secrets out of version control
Cursor supports ${env:VAR} interpolation in the auth block. Export your credentials as env vars and reference them instead of pasting the secret into .cursor/mcp.json:
```json
{
"mcpServers": {
"CLIENT_NAME": {
"type": "http",
"url": "https://api.domaintools.com/v1/mcp",
"auth": {
"CLIENT_ID": "${env:MCP_CLIENT_ID}",
"CLIENT_SECRET": "${env:MCP_CLIENT_SECRET}"
}
}
}
}
```
### Gemini CLI
Gemini CLI documentation
By default, Gemini CLI uses a random port for its redirect URI. To set a static redirect URI, configure the mcpServers.SERVER_NAME.oauth.redirectUri setting.
Pick a fixed port (for example, 7777) and provide the following redirect URI during registration:
```text
http://localhost:7777/oauth/callback
```
Add the following to your ~/.gemini/settings.json file:
```json
{
"mcpServers": {
"CLIENT_NAME": {
"httpUrl": "https://api.domaintools.com/v1/mcp",
"oauth": {
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_CLIENT_SECRET",
"redirectUri": "http://localhost:7777/oauth/callback"
}
}
}
}
```
Replace CLIENT_NAME with the registered client name. Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the credentials provided by DomainTools.
### VS Code
VS Code MCP documentation
MCP in VS Code is accessed through GitHub Copilot's agent mode.
Add a remote MCP server using the Command Palette's MCP Add command. VS Code prompts you for the resource URL, then generates two redirect URIs, for example:
- http://127.0.0.1:33418
- https://vscode.dev/redirect
VS Code then prompts for a client ID and client secret. Provide the generated redirect URIs during registration, then enter the credentials provided by DomainTools.
VS Code prompts for a Server ID that becomes the key in mcp.json. Because VS Code doesn't transmit this identifier during OAuth or the MCP connection, it doesn't need to match the registered client name.
## Troubleshooting OAuth
In addition to the general errors documented in Get started > Troubleshooting, OAuth registrations have a few specific failure modes.
### Redirect URI mismatch
The authorization server rejects the flow with an invalid_request or redirect_uri_mismatch error when the redirect URI your client sends doesn't exactly match a URI registered for your client ID. Causes:
- Host, port, path, or scheme differs by even one character (for example, http://localhost:61264/callback registered but client sends http://localhost:61265/callback).
- Claude Code or Gemini CLI fell back to a random port because the fixed-port option wasn't configured. Re-check --callback-port (Claude Code) or mcpServers..oauth.redirectUri (Gemini CLI).
- VS Code's local redirect URI was regenerated on a new machine. Send the new URI to DomainTools for registration.
### Invalid client ID or secret
An invalid_client error during the token exchange means the client ID or client secret is wrong, or the secret has been rotated. To rotate or reissue credentials, contact your DomainTools representative or email enterprisesupport@domaintools.com.
### Rotating or revoking a registration
There is no self-serve endpoint for rotating a client secret or decommissioning a registration. Contact enterprisesupport@domaintools.com.
### Corporate proxies and SSO
If your corporate network forces HTTPS through a proxy, the OAuth redirect back to your local client may fail. Work with your network team to allow outbound HTTPS to api.domaintools.com (MCP Server) and account.domaintools.com (OAuth authorization server). Both must be reachable from the MCP client host. If your DomainTools account uses SSO, the sign-in page redirects to your identity provider before returning to the MCP client; confirm that users have active SSO sessions.
## Related pages
- API key authentication: per-client setup for clients that use the X-Api-Key header
- Get started with the MCP Server: prerequisites and verification
- MCP Server tools reference: available tools and usage
- MCP Server FAQ
## Available tools
MCP clients interact with the server through tool calls. In a conversational workflow, a prompt like "investigate example.com" or "find domains on this IP address" triggers the right tool automatically. Agents and automated pipelines can also call tools directly with structured parameters.
The server provides specialized tools organized into four categories. Each tool is optimized for specific use cases and returns a different subset of data.
How to read this reference: Each tool description below includes:
- Usage examples (in text blocks) — natural language prompts that trigger the tool in conversational clients. Naming a specific tool (like "Use lookup_single to...") is optional but can help direct tool selection.
- Input format (in json blocks) — the structured parameters the client sends to the tool. Conversational clients construct these automatically; agents and integrations can build them directly.
- Returns — fields included in the tool response.
### Tool summary
Domain intelligence tools — domain lookups, risk scoring, and pivot searches:
| Tool | Input | Returns | Best for |
|------|-------|---------|----------|
| lookup_single | Single domain | Full domain profile (risk, WHOIS, DNS, SSL, web, history, tags) | Deep investigation of one domain |
| lookup_bulk | Multiple domains (comma-separated) | Essential fields (risk, dates, tags, popularity) | Quick triage of domain lists |
| import_hash | Iris search hash | Same as lookup_bulk | Continuing Iris Investigate web searches |
| evaluate | Pivot parameters | Same as lookup_bulk | General connected-domain discovery |
| infrastructure | Pivot parameters | Infrastructure fields (IP, NS, MX, SOA, registrar) | Mapping hosting and DNS infrastructure |
| registration | Pivot parameters | Registration fields (WHOIS contacts, dates, status) | Identifying registrant patterns |
| website | Pivot parameters | Website fields (tracking codes, SSL, redirects, server) | Finding sites with shared web properties |
| irisql | IrisQL query text | Same fields as lookup_bulk, plus pagination metadata | Complex searches with OR logic, nested conditions, or field presence checks |
Passive DNS tools — historical DNS lookups and pattern searches:
| Tool | Input | Returns | Best for |
|------|-------|---------|----------|
| pdns_lookup_rrset | Owner name (domain) | RRsets with rdata, bailiwick, timestamps | Historical DNS records for a domain |
| pdns_lookup_rdata_name | Hostname/domain in rdata | Records pointing to that name | Finding domains sharing DNS infrastructure |
| pdns_lookup_rdata_ip | IP address or CIDR range | Domains that resolved to that IP | IP-based infrastructure mapping |
| pdns_flex_search | Regex or glob pattern | Matching rrnames or rdata values | Large-scale threat hunting with patterns |
Domain history tools — tracking changes over time:
| Tool | Input | Returns | Best for |
|------|-------|---------|----------|
| registration_history | Single domain | Registration change events with before/after states | Ownership and registrar changes |
| infrastructure_history | Single domain | Historical IP, nameserver, and mail server records | Tracking hosting migrations |
| website_history | Single domain | Historical SSL, redirects, server, and tracking codes | Website evolution over time |
| registration_history_deep | Single domain | Full historical WHOIS records | Deep WHOIS history (pre-2022 records) |
Understanding pivot tool parameters:
Pivot tools (evaluate, infrastructure, registration, website) accept a search_criteria object containing a primary search (a search_type and value pair) and optional secondary filters like tld, active, or create_date. Conversational clients build this structure automatically from your prompt. Agents and integrations can construct it directly.
For example, asking "find all .com domains hosted on IP 192.0.2.1" produces:
```json
{
"search_criteria": {
"primary": {"search_type": "ip", "value": "192.0.2.1"},
"tld": "com"
}
}
```
You can combine multiple filters: "find domains on IP 192.0.2.1 created after January 2026 with a risk score above 70." The client maps these to the appropriate secondary filters.
### lookup_single - Full domain profile
Usage example:
```text
Use lookup_single to investigate example.com
```
Purpose: Retrieve a comprehensive threat intelligence profile for a single domain.
Example use case: Investigating a suspicious domain reported in a phishing incident
Input format:
```json
{
"domain": "example.com"
}
```
Returns: Full domain profile including:
- Domain risk score and components
- Registration data (WHOIS/RDAP)
- DNS records (A, MX, NS)
- TLS/SSL certificate information
- Website metadata and tracking codes
- Historical data points
- Tags and classifications
Key fields in response:
- domain_risk.risk_score: Overall risk assessment (0-100)
- active: Whether the domain is currently registered and resolving
- create_date: Domain registration date
- registrant_contact: Registrant contact details (organization, country, email)
- registrant_org: Registrant organization
- registrar: Domain registrar name
- ip: Current IP addresses with ASN, country, and ISP
- name_server: Authoritative nameservers
- mx: Mail server records
- ssl_info: TLS/SSL certificate details
- website_title: Website title tag content
- ga4, gtm_codes: Google Analytics 4 and Tag Manager codes
- tags: Classification tags
- data_updated_timestamp: When the domain data was last refreshed
Note: The server removes fields like ga4, gtm_codes, and tags entirely from the response when no data is available for the queried domain. See Empty and null fields.
### lookup_bulk - Quick domain assessment
Usage example:
```text
Use lookup_bulk to check these domains: example.com,example.net,example.org
```
Purpose: Rapid risk assessment for multiple domains with essential threat indicators.
Example use case: Checking a batch of domains extracted from email headers
List the domains in any format: "check example.com, example.net, and example.org." The client converts your list into the comma-separated format the tool expects.
Input format:
```json
{
"domains": "example.com,example.net,example.org"
}
```
Returns: Essential risk fields for each domain:
- domain: Domain name
- active: Registration and DNS status
- create_date: Registration date
- first_seen: First observed by DomainTools
- popularity_rank: Domain popularity rank from DomainTools (lower = higher traffic; updated daily; top 500,000 domains only)
- domain_risk: Risk score and components
- tags: Classification tags (omitted from response when unavailable — see Empty and null fields)
Performance notes:
- Optimized for speed with reduced dataset
- Accepts up to 100 domains per request
- Returns only the most actionable fields
### import_hash - Resume saved searches
Usage example:
```text
Import the domains from this Iris search hash: [paste hash]
```
Purpose: Import domain lists from searches saved in the Iris Investigate web interface.
Example use case: Continuing an investigation started in the Iris Investigate web interface
How to get a search hash:
Search hashes are generated by the Iris Investigate web interface:
1. Perform a search in Iris Investigate
2. Click Search in the top menu
3. Select Export
4. Copy the search hash value
Input format:
```json
{
"search_hash": "U2FsdGVkX1/0ltGMb0qZqYOdhIF..."
}
```
Returns: Same fields as lookup_bulk (domain, active, create_date, first_seen, popularity_rank, domain_risk, tags)
Note: Only the Iris Investigate web interface generates search hashes. The MCP Server consumes them but doesn't generate them.
Error: An HTTP 400 response with the message "The search_hash parameter appears to be invalid" indicates the hash is malformed or expired. Generate a new hash from the Iris Investigate web interface.
### evaluate - Find connected domains (general)
Usage example:
```text
Use evaluate to find all .com domains hosted on IP 192.0.2.1
```
Purpose: Discover related domains through shared infrastructure, registration, or web characteristics. For deep investigation of a single domain without pivot parameters, use lookup_single instead.
Example use case: Finding domains on the same IP address
Supported search_type values:
- Domain/IP: domains, ip, redirect_domain
- DNS: nameserver_host, nameserver_domain, nameserver_ip, mailserver_host, mailserver_domain, mailserver_ip
- Registration: registrant, registrant_org, registrar, email, email_domain, email_dns_soa, contact_name, contact_phone, contact_street, iana_id, whois
- Historical: historical_email, historical_registrant, historical_free_text
- SSL/TLS: ssl_common_name, ssl_issuer_common_name, ssl_org, ssl_subject, ssl_email, ssl_hash, ssl_alt_names, ssl_duration (integer: validity in days)
- Web/Tracking: website_title, server_type, adsense, google_analytics, ga4, google_tag_manager, facebook, hotjar, matomo, yandex_metrica, baidu_analytics, statcounter_project, statcounter_security
- Tags: tagged_with_any, tagged_with_all
- Other: search_hash
Optional secondary filters: tld, active, create_date, expiration_date, first_seen_since, first_seen_within, ip_country_code, risk_score, rank, ssl_not_before, ssl_not_after, not_tagged_with_any, not_tagged_with_all
Input format:
```json
{
"search_criteria": {
"primary": {"search_type": "ip", "value": "192.0.2.1"},
"tld": "com"
}
}
```
Returns: Same fields as lookup_bulk (domain, active, create_date, first_seen, popularity_rank, domain_risk, tags)
Additional examples:
```text
Use evaluate to find domains using Google Analytics 4 code G-XXXXXXXXXX
```
```text
Use evaluate to find domains registered to "Example Corp"
```
### infrastructure - Infrastructure-focused pivoting
Usage example:
```text
Use infrastructure to find domains using nameserver ns1.example.com
```
Purpose: Find domains sharing infrastructure components with detailed DNS and hosting information.
Example use case: Mapping nameserver usage patterns
Supported search_type values and secondary filters: Same as evaluate tool
Input format:
```json
{
"search_criteria": {
"primary": {"search_type": "nameserver_domain", "value": "ns.example.com"}
}
}
```
Returns: Infrastructure-specific fields:
- domain: Domain name
- active: Registration and DNS status
- first_seen: First observed by DomainTools
- ip: Current IP addresses, each with nested asn, country_code, and isp
- name_server: Nameserver hostnames
- mx: Mail server records
- soa_email: DNS SOA email address
- registrar: Domain registrar
Difference from evaluate: Returns more detailed infrastructure fields (IP, ASN, ISP, NS, MX records) but omits general metadata like popularity rank and risk scores.
### registration - Registration-focused pivoting
Usage example:
```text
Use registration to find domains registered to email domain example.com
```
Purpose: Find domains with shared registration characteristics and WHOIS data.
Example use case: Finding domains registered by the same entity
Supported search_type values and secondary filters: Same as evaluate tool
Input format:
```json
{
"search_criteria": {
"primary": {"search_type": "registrant_org", "value": "Example Corporation"}
}
}
```
Returns: Registration-specific fields:
- domain: Domain name
- active: Registration and DNS status
- first_seen: First observed by DomainTools
- create_date: Domain registration date
- expiration_date: Domain expiration date
- email_domain: Email domain from WHOIS
- soa_email: DNS SOA email
- additional_whois_email: Other emails in WHOIS
- admin_contact: Administrative contact
- billing_contact: Billing contact
- registrant_org: Registrant organization
- technical_contact: Technical contact
- registrar: Domain registrar
- registrar_status: Domain status codes
Privacy note: WHOIS data respects GDPR and other privacy regulations. Some fields may be redacted based on registry policies.
### website - Website-focused pivoting
Usage example:
```text
Use website to find all domains using Google Analytics 4 code G-XXXXXXXXXX
```
Purpose: Find domains sharing web technologies, tracking codes, and website characteristics.
Example use case: Finding domains with the same Google Analytics code
Typical workflow: Use lookup_single on a domain to discover its tracking codes, then pivot with this tool using those codes to find related domains.
Additional example:
```text
Use website to find all domains with the same AdSense code as example.com
```
Supported search_type values and secondary filters: Same as evaluate tool
Input format:
```json
{
"search_criteria": {
"primary": {"search_type": "ga4", "value": "G-XXXXXXXXXX"}
}
}
```
Returns: Website-specific fields:
- domain: Domain name
- active: Registration and DNS status
- first_seen: First observed by DomainTools
- website_response: HTTP response code
- redirect: Redirect URL
- redirect_domain: Redirect target domain
- website_title: Website title tag
- server_type: Web server software
- ssl_info: SSL certificate details
- ssl_email: Email from SSL certificate
- adsense: Google AdSense code
- google_analytics: Google Analytics (UA) code
- ga4: Google Analytics 4 codes
- gtm_codes: Google Tag Manager codes
- fb_codes: Facebook/Meta tracking codes
- hotjar_codes: Hotjar tracking codes
- baidu_codes: Baidu Analytics codes
- yandex_codes: Yandex Metrica codes
- matomo_codes: Matomo tracking codes
- statcounter_project_codes: StatCounter project codes
- statcounter_security_codes: StatCounter security codes
Tracking code types supported:
- Google Analytics (UA and GA4)
- Google Tag Manager
- Google AdSense
- Facebook/Meta Pixel
- Hotjar
- Baidu Analytics
- Yandex Metrica
- Matomo
- StatCounter
### irisql - Advanced query language
Caution: Read the IrisQL syntax reference before using this tool
The MCP server exposes the IrisQL reference as a resource at docs://irisql-reference. Conversational clients and agents should read it before constructing queries. Humans can read the authoritative IrisQL syntax reference.
Usage example:
```text
Use irisql to find domains containing "bank" or "finance", created in the last 30 days, with a risk score above 75
```
Purpose: Run Iris Investigate searches written as IrisQL, a text-based query language. Use this tool when a search needs capabilities the structured pivot tools (evaluate, infrastructure, registration, website) don't support — OR logic across values of the same field, nested AND/OR combinations, field presence checks, or relative date ranges.
Example use cases:
- Finding domains matching one of several name patterns
- Combining registration, risk, and tracking-code filters in a single search
- Paginating through a large result set
When to prefer a different tool:
- Single-domain investigation: use lookup_single
- Quick triage of a known domain list: use lookup_bulk
- Simple single-field pivots: use evaluate, infrastructure, registration, or website
Input format:
```json
{
"query": "# IrisQL-1.0\nDOMAIN CONTAINS \"bank\"\nDOMAIN CONTAINS \"finance\"\nAND\nCREATE_DATE WITHIN \"The last 30 days\"\nAND\nRISK_SCORE GREATER_THAN 75",
"position": null
}
```
Input parameters:
- query (required): The full IrisQL query text. The first line must be the version comment # IrisQL-1.0.
- position (optional): Pagination cursor returned by a previous call. Omit on the first request.
Syntax: For query structure, supported fields, operators, data types, and examples, see the IrisQL syntax reference. That page is the source of truth for query language details.
Returns: An object containing:
- results: Array of matching domains. Each entry includes the same fields as lookup_bulk (domain, active, create_date, first_seen, popularity_rank, domain_risk, tags).
- has_more_results: Boolean indicating whether additional pages are available. Present when the server returns pagination metadata.
- total_count: Total matching records, when available.
- results_count: Count of records in the current page, when available.
- position: Opaque cursor string to pass to the next call. Present when has_more_results is true.
Pagination:
To page through results, pass the position value from a previous response as the position parameter on the next call. Stop when has_more_results is false or position is absent.
```json
{
"query": "# IrisQL-1.0\nDOMAIN CONTAINS \"example\"",
"position": "eyJza2lwIjo1MH0="
}
```
Note: A query that's too broad to return any results on the first page can come back with has_more_results: true, an empty results array, and no position cursor. Narrow the query with additional conditions (for example, TLD, CREATE_DATE, or RISK_SCORE) to get a paginable result set.
Note: The server removes empty and null fields from each result. See Empty and null fields.
### pdns_lookup_rrset - Forward DNS lookup
Usage example:
```text
Look up all DNS records for example.com using passive DNS
```
Purpose: Forward lookup of DNS resource record sets (RRsets) by owner name. Returns complete record sets with all rdata values, bailiwick metadata, and observation timestamps.
Example use case: Discovering historical DNS records and subdomains for a domain under investigation
Input format:
```json
{
"owner_name": "example.com",
"rrtype": "A"
}
```
Returns:
- rrname: DNS owner name
- rrtype: Record type (A, AAAA, CNAME, MX, NS, etc.)
- rdata[]: Record data values
- bailiwick: DNS bailiwick (zone of authority)
- count: Number of times observed
- time_first, time_last: First and last observation timestamps
- zone_time_first, zone_time_last: Zone file observation timestamps
Optional parameters: rrtype, bailiwick, time_first_before, time_first_after, time_last_before, time_last_after, limit, offset, aggr
Wildcards: Use *.example.com for left-hand wildcards (slower) or www.example.* for right-hand wildcards (faster).
### pdns_lookup_rdata_name - Inverse name lookup
Usage example:
```text
Find all domains whose DNS records point to ns1.example.com
```
Purpose: Inverse lookup that finds domains whose rdata contains a specific hostname or domain name. Returns individual records rather than full RRsets.
Example use case: Finding domains sharing a nameserver or mail server
Input format:
```json
{
"name": "ns1.example.com"
}
```
Returns:
- rrname: DNS owner name
- rrtype: Record type
- rdata: Record data value
- count: Number of times observed
- time_first, time_last: First and last observation timestamps
- zone_time_first, zone_time_last: Zone file observation timestamps (when available)
Wildcards: Use .example.com (dot-prefix) for left-hand wildcards or www.example. (dot-suffix) for right-hand wildcards. Note: this differs from pdns_lookup_rrset, which uses * wildcards.
Optional parameters: rrtype, time_first_before, time_first_after, time_last_before, time_last_after, limit, offset, aggr
### pdns_lookup_rdata_ip - Inverse IP lookup
Usage example:
```text
Find all domains that have ever resolved to IP 192.0.2.1
```
Purpose: Inverse lookup that finds all domains that have pointed to specific IP addresses or CIDR ranges.
Example use case: Mapping all domains hosted on a suspicious IP address
Input format:
```json
{
"ip": "192.0.2.1"
}
```
Returns: Same fields as pdns_lookup_rdata_name
IP formats supported: Single IP (192.0.2.1), CIDR prefix (192.0.2.0/24), or IP range (192.0.2.1-192.0.2.10). Also supports IPv6 addresses.
Optional parameters: time_first_before, time_first_after, time_last_before, time_last_after, limit, offset, aggr
### pdns_flex_search - Pattern search
Usage example:
```text
Search passive DNS for all domains matching the pattern *malware*.com
```
Purpose: Pattern-based passive DNS search using regex or glob expressions.
Example use case: Large-scale threat hunting for domains matching a suspicious pattern
Input format:
```json
{
"search_params": {
"search_type": "rrnames_glob",
"value": "*malware*.com"
}
}
```
Search types: rrnames_regex, rrnames_glob, rdata_regex, rdata_glob
Returns (rrnames search): rrname, rrtype
Returns (rdata search): rdata, rrtype, raw_rdata
Flex search returns minimal metadata for pattern discovery. Use pdns_lookup_rrset or pdns_lookup_rdata_name on individual results to get full temporal data (count, time_first, time_last).
Optional parameters: rrtype, exclude (filter out matches), time_first_before, time_first_after, time_last_before, time_last_after, limit, offset
### registration_history - Registration changes
Usage example:
```text
Show me the registration history for example.com
```
Purpose: Retrieve a timestamped record of changes to a domain's registration data, including ownership transfers and registrar changes.
Example use case: Tracking when a domain changed hands or switched registrars
Input format:
```json
{
"domain": "example.com"
}
```
Returns: The response includes domain, count (total number of changes), and a changes array. Each change event contains:
- timestamp: When the change was detected
- field: Which field changed
- before / after: The field's state before and after the change
Tracked fields: create_date, expiration_date, registrant, registrar, registrar_status, active, admin_contact, billing_contact, registrant_contact, technical_contact.
Data coverage: This tool tracks changes beginning January 1, 2022. For older registration records, use registration_history_deep.
Pagination: Results are paginated with page_size (default 50, max 100) and offset (0-indexed).
### infrastructure_history - Infrastructure changes
Usage example:
```text
Show the historical IP addresses and nameservers for example.com
```
Purpose: Retrieve a timestamped record of changes to a domain's infrastructure, including IP addresses, nameservers, and mail servers.
Example use case: Tracking hosting migrations and nameserver changes over time
Input format:
```json
{
"domain": "example.com"
}
```
Returns: The response includes domain, count (total number of changes), and a changes array. Each change event contains:
- timestamp: When the change was detected
- field: Which field changed (for example, ip, mx, name_server)
- before / after: The field's state before and after the change
Change events use these field values: ip (each entry contains address, asn, country_code, isp), name_server (each entry contains host, ip), mx (each entry contains host, ip, priority).
Data coverage: This tool tracks infrastructure changes from January 1, 2022 onward. Earlier infrastructure data isn't available through the MCP Server.
Pagination: Results are paginated with page_size (default 50, max 100) and offset (0-indexed).
### website_history - Website changes
Usage example:
```text
Show the website history for example.com including past SSL certificates
```
Purpose: Retrieve a timestamped record of changes to a domain's web presence, including SSL certificates, redirects, server software, and tracking codes.
Example use case: Investigating how a compromised website changed over time
Input format:
```json
{
"domain": "example.com"
}
```
Returns: The response includes domain, count (total number of changes), and a changes array. Each change event contains:
- timestamp: When the change was detected
- field: Which field changed (for example, ssl_info, website_title, server_type)
- before / after: The field's state before and after the change
Change events use these field values:
- ssl_info: Each entry contains hash, common_name, alt_names, subject, issuer_common_name, not_before, not_after, duration, email
- Content: redirect, redirect_domain, screenshot_collected_timestamp, server_type, website_response, website_title
- Tracking codes: google_analytics, ga4, google_tag_manager, facebook, hotjar, matomo, yandex_metrica, baidu_analytics, statcounter_project, statcounter_security, adsense
Data coverage: This tool tracks website changes from January 1, 2022 onward. Earlier website data isn't available through the MCP Server.
Pagination: Results are paginated with page_size (default 50, max 100) and offset (0-indexed).
### registration_history_deep - Deep WHOIS history
Usage example:
```text
Show the full WHOIS history for example.com going back to its original registration
```
Purpose: Retrieve historical WHOIS registration records, including records older than those available from registration_history (which begins at January 2022).
Example use case: Investigating the original registrant of a domain or changes predating 2022
Input format:
```json
{
"domain": "example.com"
}
```
Returns: The response includes record_count (total historical records) and a history array. Each record contains:
- date: Record timestamp
- is_private: Whether WHOIS privacy was active (0 = public, 1 = redacted)
- whois: Parsed WHOIS data containing:
- registrant: Registrant name
- registration: Object with created, expires, updated, registrar, statuses
- name_servers: Nameservers at time of record
- record: Raw WHOIS text
Optional parameters:
- sort: date_asc or date_desc (default) — controls record ordering
- limit: Maximum records per request (1-100, default 100)
- offset: Number of records to skip for pagination (0-indexed)
- mode: list (default) returns records, count returns only the record count, check_existence returns whether the domain exists in the database
- format: Response format — json (default), xml, or html
## Example workflows
These examples show how to chain tools for multi-step investigations. In a conversational workflow, describe each step and the client selects the tools and carries context forward. Agents can chain these tools programmatically.
### Investigate a domain and find related infrastructure
Start with a suspicious domain, discover its tracking codes, and pivot to find other domains using the same codes.
```text
Step 1: Use lookup_single to investigate example.com
```
The response includes tracking codes (ga4, gtm_codes, adsense), SSL certificates, and nameservers. Pivot on a shared identifier:
```text
Step 2: Use website to find all other domains using that same Google Tag Manager code
```
```text
Step 3: Use lookup_bulk to check the risk scores for those related domains
```
Tools used: lookup_single → website → lookup_bulk
### Map infrastructure from an IP address
Identify all domains associated with a suspicious IP address using both domain lookup and passive DNS tools, then triage by risk.
```text
Step 1: Use lookup_single to get the current IP and hosting details for example.com
```
```text
Step 2: Use pdns_lookup_rdata_ip to find all domains that have ever resolved to that IP address
```
```text
Step 3: Use infrastructure to find active domains currently hosted on that IP, and show their nameservers and registrar
```
```text
Step 4: Use lookup_bulk to assess risk scores for the domains you found — focus on any with a risk score above 70
```
Prioritize high-risk domains. Domains sharing an IP with low risk scores and high popularity ranks are likely co-tenants on shared hosting and can usually be deprioritized.
Tools used: lookup_single → pdns_lookup_rdata_ip + infrastructure → lookup_bulk
### Hunt for typosquatting or DGA domains
Proactively search for suspicious domains matching a pattern, then triage the results with lookup_bulk.
```text
Step 1: Use pdns_flex_search to find all domains matching the glob pattern *paypa1*.com
```
Filter the matches for suspicious names, then get full DNS details for the strongest candidates:
```text
Step 2: Use pdns_lookup_rrset to look up the A records for the top suspicious matches
```
```text
Step 3: Use lookup_bulk to check risk scores and registration dates for those domains
```
Newly created domains with high risk scores and shared infrastructure are the strongest candidates for typosquatting campaigns.
Tools used: pdns_flex_search → pdns_lookup_rrset → lookup_bulk
## Understand results
The server returns structured JSON data. In conversational clients, the model interprets these results and presents them in a readable format. This section explains the underlying data structures.
### Risk score interpretation
See the Domain Risk Score user guide for more information.
Domain risk scores range from 0 (lowest risk) to 100 (highest risk):
| Score | Description |
|-------|-------------|
| 100 | Blocklisted — known-bad, includes sinkholed domains |
| 90-99 | Strong confidence in near-term weaponization |
| 70-89 | Default investigation significance threshold |
| 50-69 | May require attention depending on security posture |
| 1-49 | Very little evidence of malicious intent |
| 0 | Zero-listed — no evidence of malicious registration |
Risk scores include components that explain the assessment:
- proximity: Observed closeness to known-malicious infrastructure
- threat_profile_phishing: Phishing-specific ML classifier
- threat_profile_malware: Malware-specific ML classifier
- threat_profile_spam: Spam-specific ML classifier
### Pivot counts in lookup_single
lookup_single returns fields in {value, count} format, where count indicates how many other domains share that exact value (excludes the queried domain):
```json
{
"value": "192.0.2.1",
"count": 42
}
```
Use pivot counts to guide your next investigation step:
- Low count (1-50): Strong signal — a rare, high-confidence connection worth pivoting on
- High count (500+): Common value (shared hosting, popular provider) — usually not worth pivoting on
- Count of 1: Unique to the queried domain
All other domain intelligence tools (lookup_bulk, import_hash, evaluate, infrastructure, registration, website) return flattened values with pivot counts removed to keep responses compact.
### Empty and null fields
The server removes fields entirely from a response when they are empty or null at query time. This reduces token usage and keeps responses focused on available data.
If a field documented in this reference doesn't appear in a response, it means no data was available for that field — not that the tool doesn't support it. For example:
- A domain without Google Analytics won't include ga4 in the response.
- A domain without classification data won't include tags.
- Privacy-protected WHOIS may omit registrant contact fields.
- Inactive domains may lack current DNS records.
## What is the DomainTools MCP Server?
The DomainTools MCP Server integrates DomainTools domain intelligence directly into AI-powered workflows through the Model Context Protocol (MCP). This hosted service works with MCP-compatible AI clients to accelerate domain triage and infrastructure investigation.
## Does DomainTools provide the AI model?
No. DomainTools doesn't provide or operate the Large Language Models (LLMs). The MCP Server works with your existing AI models and agents. You control which LLM you use and how you use it.
## Does DomainTools use generative AI within the product?
No. DomainTools doesn't use generative AI to produce outputs. All tool responses are constructed programmatically from DomainTools' proprietary databases.
## Does the MCP Server comply with an open standard?
Yes. The DomainTools MCP Server implements MCP 1.2, the specification stabilized by the Linux Foundation's Agentic AI Foundation. Using an open standard means the server isn't tied to any single AI vendor's proprietary protocols or security model, and any MCP-compatible client can connect to it.
## How is the MCP Server delivered?
DomainTools hosts the MCP Server as a service. You connect to it over HTTPS using your MCP-compatible client — there's nothing to install or manage on your side.
## What data does the MCP Server handle?
- Input: You provide domain names and IP addresses.
- Output: DomainTools returns threat intelligence about those indicators, combining publicly available data with DomainTools' proprietary intelligence.
## Does DomainTools log or store my queries?
Yes. DomainTools logs customer queries only to investigate and resolve customer-reported support issues.
## Do you use my queries to train DomainTools' models?
No. DomainTools doesn't train its internal predictive risk models on customer data.
## How does the MCP Server protect against prompt injection?
Prompt injection — including indirect injection, where malicious instructions are embedded in external content an LLM reads — is a known risk in AI-integrated workflows. The DomainTools MCP Server addresses this in two ways:
- Input validation: The server validates all tool inputs against strict JSON schemas before execution. If a parameter doesn't match the declared specification, the server rejects the call and returns an error. An LLM can't be tricked into passing arbitrary commands to the server through malformed tool inputs.
- Deterministic outputs: DomainTools constructs all tool responses programmatically from its own databases — no generative AI is involved. Responses follow the tool specifications exactly and can't be manipulated to inject instructions back into the LLM context.
Your security team controls the prompts that invoke MCP Server tools, which is the primary control point for indirect injection risk at the application layer.
## Can the MCP Server hallucinate data?
No. DomainTools constructs every tool response programmatically from its own databases, so the data retrieval layer is deterministic — hallucination isn't possible there. However, the LLM your client uses interprets the analyst's intent and summarizes results, and LLMs can hallucinate in that layer. This is true for any LLM interacting with any MCP server — it's a property of the model, not the data source. The DomainTools data itself is always retrieved, not generated.
## What authentication methods does the MCP Server support?
The MCP Server supports two authentication modes:
- API key — pass your DomainTools API key in an X-Api-Key HTTP header. Works with every supported client. See API key authentication.
- OAuth 2.0 — pre-registered client credentials for Claude Code, Claude Desktop, Cursor, Gemini CLI, and VS Code. Your MCP client redirects you to sign in with your DomainTools account. See OAuth authentication.
During the MCP initialize handshake, the server validates your credentials against the DomainTools /v1/account endpoint.
## Should I use API key or OAuth?
Use API key authentication when you want the fastest path to a working connection, or when your client isn't in the OAuth pre-registration list (for example, Codex). Use OAuth when you want per-user sign-in tied to DomainTools accounts, or when your security policy prefers token-based flows over static headers. Both modes have equal access to MCP Server tools.
## Does the MCP Server support dynamic client registration?
No. OAuth clients must be pre-registered with DomainTools. Contact your DomainTools representative or email enterprisesupport@domaintools.com to request credentials. See OAuth authentication for the registration workflow.
## How does the MCP Server handle encryption?
- Data in transit: All client connections to the MCP Server use TLS 1.3-encrypted HTTPS. The server doesn't support STDIO (Standard Input/Output) transport — STDIO is a local transport that requires the server process to run on the same machine as the client, which isn't suitable for a remotely hosted service.
- Data at rest: You're responsible for encrypting data at rest on your own systems, if required.