Metadata-Version: 2.4
Name: mcp-server-abuseipdb
Version: 0.1.1
Summary: Official AbuseIPDB MCP server — check IP reputation from MCP clients
Keywords: mcp,abuseipdb,security,threat-intelligence,ip-reputation
Author: AbuseIPDB
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Security
Classifier: Typing :: Typed
Requires-Dist: httpx>=0.28.1
Requires-Dist: mcp>=1.27.1,<2
Requires-Dist: pydantic>=2.13.4,<3
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/AbuseIPDB/abuseipdb-mcp
Project-URL: Documentation, https://github.com/AbuseIPDB/abuseipdb-mcp#readme
Project-URL: Repository, https://github.com/AbuseIPDB/abuseipdb-mcp
Project-URL: Issues, https://github.com/AbuseIPDB/abuseipdb-mcp/issues
Description-Content-Type: text/markdown

# AbuseIPDB MCP

<!-- mcp-name: io.github.abuseipdb/abuseipdb-mcp -->

AbuseIPDB MCP is a small Model Context Protocol server for checking IP
reputation from MCP clients such as Claude, Cursor, VS Code, Codex, and others.
It talks to the AbuseIPDB API v2 over HTTPS and exposes the results as MCP
tools over stdio.

Current server status: beta, stdio, read-only. Published on PyPI as
[`mcp-server-abuseipdb`](https://pypi.org/project/mcp-server-abuseipdb/) and in
the [MCP Registry](https://registry.modelcontextprotocol.io) as
`io.github.abuseipdb/abuseipdb-mcp`. A published Docker image is planned; see
[Coming next](#coming-next).

## What it does

- Checks one public IPv4 or IPv6 address with `check_ip`.
- Checks a batch of public IPs with `bulk_check` (cap configurable, default 100).
- Returns AbuseIPDB confidence score, report count, country, ISP, usage type,
  domain, last report time, risk tier, and a short plain-English summary.
- Rejects hostnames, URLs, CIDR ranges, and private/reserved addresses by
  default.
- Returns structured errors for bad input, auth failures, timeouts, rate limits,
  and AbuseIPDB API errors.
- Publishes MCP tool annotations for read-only, idempotent, open-world calls.

It does not submit reports or fetch blacklists yet.

## Requirements

- Python 3.11+
- [uv](https://docs.astral.sh/uv/)
- An AbuseIPDB API key

## Install

The distribution on PyPI is `mcp-server-abuseipdb`. It installs two equivalent
commands, `mcp-server-abuseipdb` and `abuseipdb-mcp` — use either. Most users do
not need to install anything ahead of time: `uvx` fetches and runs it on demand,
which is the form every client example below uses.

Run it once by hand to confirm your key works:

```bash
ABUSEIPDB_API_KEY=your_key_here uvx mcp-server-abuseipdb
```

To keep a persistent install on `PATH` instead:

```bash
uv tool install mcp-server-abuseipdb
```

The server uses MCP stdio. It waits for JSON-RPC on stdin and looks idle when
started from a terminal; that is expected. Stdout is reserved for JSON-RPC
messages, so logs go to stderr.

## MCP client setup

The MCP client starts this server and passes its environment variables. Put
`ABUSEIPDB_API_KEY` in the client configuration shown below, then restart or
reload the server from that client. Do not put the key in `args` or commit a
real key to source control.

### Generic `mcpServers` clients

Use this shape for clients that accept a top-level `mcpServers` object:

```json
{
  "mcpServers": {
    "abuseipdb": {
      "command": "uvx",
      "args": ["mcp-server-abuseipdb"],
      "env": {
        "ABUSEIPDB_API_KEY": "your_key_here"
      }
    }
  }
}
```

Copy: [`examples/mcp/mcpServers.json`](examples/mcp/mcpServers.json)

### Claude Desktop

Open **Settings → Developer → Edit Config**, or edit the platform file:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "abuseipdb": {
      "command": "uvx",
      "args": ["mcp-server-abuseipdb"],
      "env": {
        "ABUSEIPDB_API_KEY": "your_key_here"
      }
    }
  }
}
```

Copy: [`examples/mcp/claude-desktop.json`](examples/mcp/claude-desktop.json).
Restart Claude Desktop after saving.

### Claude Code

For a shared project setup, copy this to `.mcp.json` in the project root:

```json
{
  "mcpServers": {
    "abuseipdb": {
      "command": "uvx",
      "args": ["mcp-server-abuseipdb"],
      "env": {
        "ABUSEIPDB_API_KEY": "${ABUSEIPDB_API_KEY}"
      }
    }
  }
}
```

Copy: [`examples/mcp/claude-code-project.mcp.json`](examples/mcp/claude-code-project.mcp.json).
Export `ABUSEIPDB_API_KEY` before starting Claude Code. For private user-level
setup instead, use `claude mcp add-json --scope user`; run `claude mcp list` to
verify installation.

### Cursor

Save this as `.cursor/mcp.json` for one project or `~/.cursor/mcp.json` for all
projects:

```json
{
  "mcpServers": {
    "abuseipdb": {
      "command": "uvx",
      "args": ["mcp-server-abuseipdb"],
      "env": {
        "ABUSEIPDB_API_KEY": "your_key_here"
      }
    }
  }
}
```

Copy: [`examples/mcp/cursor-mcp.json`](examples/mcp/cursor-mcp.json). Reload
Cursor after saving.

### VS Code with GitHub Copilot

Save this as `.vscode/mcp.json` for one workspace. For user-level setup, run
**MCP: Open User Configuration** from the Command Palette. VS Code prompts for
the key instead of placing it directly in the file:

```json
{
  "inputs": [
    {
      "id": "abuseipdb-api-key",
      "type": "promptString",
      "description": "AbuseIPDB API key",
      "password": true
    }
  ],
  "servers": {
    "abuseipdb": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mcp-server-abuseipdb"],
      "env": {
        "ABUSEIPDB_API_KEY": "${input:abuseipdb-api-key}"
      }
    }
  }
}
```

Copy: [`examples/mcp/vscode-copilot-mcp.json`](examples/mcp/vscode-copilot-mcp.json).
Run **MCP: List Servers** to start, restart, or inspect the server.

### Codex

Add this to `~/.codex/config.toml` for all projects or `.codex/config.toml`
inside a trusted project:

```toml
[mcp_servers.abuseipdb]
command = "uvx"
args = ["mcp-server-abuseipdb"]

[mcp_servers.abuseipdb.env]
ABUSEIPDB_API_KEY = "your_key_here"
```

Copy: [`examples/mcp/codex-config.toml`](examples/mcp/codex-config.toml).
Restart Codex after saving.

If `uvx` is not on the client application's `PATH`, replace `"uvx"` with its
absolute path. On macOS or Linux, find it with `which uvx`; on Windows, use
`where uvx`.

## Tools

### `check_ip`

Checks one public IP address.

| Parameter | Default | Notes |
|---|---:|---|
| `ip` | required | Public IPv4 or IPv6 address |
| `max_age_in_days` | `30` | AbuseIPDB report window, 1-365 |
| `verbose` | `true` | Include AbuseIPDB report details when available |

Returns a normalized dict with `abuseConfidenceScore`, `riskTier`, report
metadata, source fields, and `message`.

### `bulk_check`

Checks a list of public IP addresses.

| Parameter | Default | Notes |
|---|---:|---|
| `ips` | required | IPv4/IPv6 addresses; cap set by `ABUSEIPDB_MAX_BULK_IPS` (default 100) |
| `max_age_in_days` | `30` | AbuseIPDB report window, 1-365 |

Duplicate inputs are deduplicated. Invalid IPs are returned as per-item errors.
If AbuseIPDB rate-limits an item, the remaining items in that same call are
marked skipped rather than burned against an exhausted quota.

## Rate limits

AbuseIPDB is the sole authority on your quota. This server does not cache or
predict limit state across requests:

- An `HTTP 429` is returned to the caller as a structured `RATE_LIMITED` error.
- The short-circuit is scoped to a single `bulk_check` call. A later tool
  invocation contacts AbuseIPDB again, so a retry works as soon as your quota
  allows.
- When a response shows the remaining quota at or below 10% of your plan
  limit, the result carries a `notice` field.

## Environment

| Variable | Default | Purpose |
|---|---|---|
| `ABUSEIPDB_API_KEY` | required | AbuseIPDB API key |
| `ABUSEIPDB_ALLOW_PRIVATE` | `false` | Allow private/reserved IPs for lab use |
| `ABUSEIPDB_REQUEST_TIMEOUT` | `30` | API timeout in seconds |
| `ABUSEIPDB_MAX_BULK_IPS` | `100` | Max IPs accepted per `bulk_check` call |
| `ABUSEIPDB_ENABLE_WRITE_TOOLS` | `false` | Reserved gate for future write tools |

## Docker

No image is published yet. Only available if using git repo right now. Build and run it locally:

```bash
docker build -t abuseipdb-mcp:local .
docker run --rm -i -e ABUSEIPDB_API_KEY=your_key_here abuseipdb-mcp:local
```

`-i` is required — the server communicates over stdio. When an official image
ships, [`examples/mcp/docker.json`](examples/mcp/docker.json) has the client
entry to use.

## Development

```bash
git clone https://github.com/AbuseIPDB/abuseipdb-mcp.git
cd abuseipdb-mcp
uv sync
cp .env.example .env   # then set ABUSEIPDB_API_KEY
```

Run the server from the checkout (`--env-file` loads `.env`; `uv run` alone
does not):

```bash
uv run --env-file .env abuseipdb-mcp
```

Tests and lint:

```bash
uv run pytest -q
uv run ruff check .
```

`tests/test_stdio_protocol.py` drives a real subprocess over JSON-RPC, so the
handshake and advertised tool schema are covered by `pytest`. For interactive
inspection, MCP Inspector is available through the development npm package:

```bash
npm install
npm run mcp:inspector
```

## Coming next

- `check_block` for CIDR lookups through AbuseIPDB `/check-block`.
- `report_ip`, hidden unless `ABUSEIPDB_ENABLE_WRITE_TOOLS=true`.
- Bounded concurrency and compact flagged-only output for `bulk_check`.
- Published Docker image at `abuseipdb/abuseipdb-mcp`.
- Optional hosted Streamable HTTP transport for team or remote use.

Release process for maintainers: see [`RELEASING.md`](RELEASING.md).

## Safety notes

- This server is read-only today.
- An abuse score of `0` means no reports in the selected window, not proof that
  an IP is safe.
- AbuseIPDB quotas depend on your account. `bulk_check` consumes one lookup per
  checked IP.
- Secrets are read from the environment and are not returned in tool output.

## License

MIT. See `LICENSE`.
