Skip to main content
Glama
bgphorizon

bgphorizon-mcp

Official
by bgphorizon
README.md
# bgphorizon-mcp

An [MCP](https://modelcontextprotocol.io) server that exposes **BGPHorizon**
BGP routing data to any MCP-capable LLM client (Claude Code,
Claude Desktop, Cursor, Gemini CLI, OpenAI Agents, …).

It is not a thin wrapper over the REST API. The surface is **25 task-shaped
tools** built around the operations investigators and operators perform,
each returning aggregates plus `warnings[]` so a model cannot silently misread the
data (persistence, single-vantage-point concentration, censored `first_seen`, …).

```
LLM client ──stdio│http──► bgphorizon-mcp ──► BGPHorizon /api/v1 ──► ClickHouse
                            (key auth, metering, tier entitlements inherited)
```

## Install & run

The server needs a BGPHorizon API key (create one in your account's **API**
panel), passed as `BGPHORIZON_API_KEY`.

**From source, with [uv](https://docs.astral.sh/uv/):**

```bash
git clone https://github.com/bgphorizon/bgphorizon-mcp.git && cd bgphorizon-mcp
uv sync
export BGPHORIZON_API_KEY=bgps_xxx
uv run bgphorizon-mcp --selftest   # ✓ API reachable ✓ key valid ✓ 25 tools ✓ 9 resources ✓ 8 prompts
```

The selftest prints a line per check, so a wrong key or an unreachable API shows
up before you wire the server into a client.

**Not on PyPI yet.** Once it is released there, `uvx bgphorizon-mcp` will run it
with nothing to install, and `uv tool install bgphorizon-mcp` or
`pipx install bgphorizon-mcp` will install it. Until then use the source install
above, or the hosted endpoint, which needs no install at all.

## Connect it

You can either use the **hosted** endpoint (nothing to install) or **self-host**
(this repo). Both authenticate with the same `bgps_` API key and go through the
same metered `/api/v1`.

### Hosted endpoint, with sign-in (no install, no key)

Clients that support MCP sign-in (OAuth) only need the URL; they open a
BGPHorizon page where you sign in and click **Allow**.

- **Claude Desktop and claude.ai:** Settings → Connectors → Add custom
  connector → `https://bgphorizon.com/mcp`.
- **Claude Code:** `claude mcp add --transport http bgphorizon https://bgphorizon.com/mcp`,
  then `/mcp` → `bgphorizon` → **Authenticate**.
- **Cursor, VS Code and others:** `{ "mcpServers": { "bgphorizon": { "url": "https://bgphorizon.com/mcp" } } }`

Access lasts 90 days and shows up as a key in your API tab, where you can
revoke it.

### Hosted endpoint, with an API key

```bash
claude mcp add --transport http bgphorizon https://bgphorizon.com/mcp \
  --header "Authorization: Bearer bgps_xxx"
```

Cursor, and other clients whose config accepts a remote `url`:

```json
{
  "mcpServers": {
    "bgphorizon": {
      "url": "https://bgphorizon.com/mcp",
      "headers": { "Authorization": "Bearer bgps_xxx" }
    }
  }
}
```

Claude Desktop does not accept a `url` entry in its config file. Use the
connector above, or, to use a fixed key, bridge to the hosted endpoint with
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote), which needs
[Node.js](https://nodejs.org):

```json
{
  "mcpServers": {
    "bgphorizon": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://bgphorizon.com/mcp",
        "--header", "Authorization:${BGPHORIZON_AUTH}"
      ],
      "env": { "BGPHORIZON_AUTH": "Bearer bgps_xxx" }
    }
  }
}
```

Keep the key in `env` with no space after `Authorization:`; Claude Desktop on
Windows breaks arguments that contain spaces. See
[`docs/SETUP.md`](docs/SETUP.md#claude-desktop) for troubleshooting.

### Self-hosted with Claude Code

```bash
claude mcp add bgphorizon --env BGPHORIZON_API_KEY=bgps_xxx \\
  -- uv run --directory /path/to/bgphorizon-mcp bgphorizon-mcp
```

### Self-hosted with Claude Desktop / Cursor (`mcpServers` block)

```json
{
  "mcpServers": {
    "bgphorizon": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/bgphorizon-mcp", "bgphorizon-mcp"],
      "env": { "BGPHORIZON_API_KEY": "bgps_xxx" }
    }
  }
}
```

The package is not on PyPI yet, so `uvx bgphorizon-mcp` will not resolve. On
Windows, write the directory with doubled backslashes (`"C:\\Users\\you\\bgphorizon-mcp"`).

Point at a non-production API with `"BGPHORIZON_API_URL"` in the same `env` block.

### Hosted / HTTP transport

```bash
bgphorizon-mcp --transport http --port 8931 --require-auth
```

Put it behind TLS with `proxy_buffering off` for streaming. See
[`docs/SETUP.md`](docs/SETUP.md) for every client (Gemini CLI,
OpenAI Agents SDK, LangChain, n8n, VS Code) and reverse-proxy config.

## What's in the box

**Investigation tools (20):** `identify`, `inventory`, `timeline`,
`origin_history`, `reachability`, `global_reach`, `detections`, `paths`, `relationships`,
`path_diversity`, `translate_communities`, `compare_windows`, `locate`, `subprefixes`, `events_sample`,
`platform_baseline`, `notable_events`, `origin_episode`, `origin_reach`, `bulk_registry`.

**Operator tools (3):** `health_check`, `validate_announcement`, `visibility`.

**Alert tools (2):** `my_alerts`, `my_monitors`. Your own monitoring rather than the
global table. `my_alerts(window="today")` returns every alert your monitors fired over a
window, with totals by detection type, severity and monitor, ready to write up.
`my_monitors` lists your watchlist with each monitor's alert volume for the same window,
so coverage and noise come back in one call.

**Resources (9):** `bgphorizon://reference/{detection-types, collectors, glossary,
data-horizon, report-template, writing-guide, qa-checklist, methodology,
report-examples}`: reference the model can pull without a tool call.
`report-template` ships with the house CSS already inlined, and the full report
standards are here, so a hosted client that never clones the repo still writes
house-style reports. Only the local enforcement scripts (`style-lint.py`,
`build-report.sh`) need the repo, and they check work the standards already
describe.

**Prompts (8):** `investigate_entity`, `write_report`, `alert_report`,
`triage_incident`, `locate_infrastructure`, `audit_my_network`,
`preflight_change`, `explain_incident`. The methodology lives here. In Claude
Code they surface as `/bgphorizon:audit_my_network`, etc. `write_report` asks
first whether you want to review its findings before it writes them up.

Full tool contracts, with a worked example per tool: [`docs/TOOLS.md`](docs/TOOLS.md).

## Writing investigative reports

The server ships a complete **report kit** and a `write_report` prompt so you can
generate BGP routing reports from any client: Claude
Code, Claude Desktop, OpenAI (Codex / Agents / ChatGPT), Gemini CLI, Cursor, and more.

Connect the server, then ask for a report. The `write_report` prompt carries the
whole procedure: it reads the standards, runs the investigation, asks whether you
want to review the findings before it writes, and fills the template. Nothing has
to be cloned for that. Cloning adds `build-report.sh`, which validates the HTML,
fails on a style violation, and renders a PDF and PNG.

The per-client, copy-paste guide is in
**[`reporting/README.md`](reporting/README.md)**.

## Configuration

| Env var | Default | Purpose |
|---|---|---|
| `BGPHORIZON_API_KEY` | (none) | API key, forwarded as `Authorization: Bearer`. |
| `BGPHORIZON_API_URL` | `https://bgphorizon.com` | BGPHorizon base URL. |
| `BGPHORIZON_TIMEOUT` | `30` | Per-request timeout (seconds). |
| `BGPHORIZON_LOG_LEVEL` | `INFO` | DEBUG surfaces every upstream request. |

## Develop

```bash
uv sync --group dev
uv run pytest            # deterministic reshaping logic (transitions, direction, …)
uv run bgphorizon-mcp --selftest
npx @modelcontextprotocol/inspector uv run bgphorizon-mcp   # raw protocol inspection
```

Layout: `client.py` (one method per `/api/v1` endpoint) · `tools/` (analytical
operations + `_shape.py` pure helpers) · `resources.py` + `reference/` (bundled
docs) · `prompts.py` (methodology). Adding a tool = one function under `tools/`
with an `@mcp.tool()` decorator; the input schema comes from its type hints.

## License

MIT.

TDQS

A3.6/5.0

Scored across 18 tools

Disambiguation4/5

Most tools target clearly distinct aspects of BGP analysis, from identity lookup to path diversity to community translation. The only real risk is among the topology-related tools (paths, relationships, path_diversity), but their descriptions explicitly differentiate inferred hierarchy from observed propagation, so an agent reading carefully should select correctly.

Naming Consistency3/5

All names are lowercase and multi-word names use snake_case consistently, but the set mixes verb-led names (identify, locate, translate_communities, validate_announcement) with noun/resource names (inventory, timeline, detections, visibility). This is readable but does not follow a single verb_noun pattern.

Tool Count4/5

18 tools is slightly above the typical 3-15 well-scoped range, but each tool maps to a meaningful analytical function in the BGP domain. The count feels heavy at first glance, yet there is little redundancy.

Completeness5/5

The surface covers the BGP investigation workflow thoroughly: identification, inventory, historical origin, reachability, detections, topology, validation, health audit, and visibility. No obvious dead-end remains for the stated purpose, and even raw-event access exists as a last resort.

Maintenance

ActivityActive
ResponsivenessNo issues