Skip to main content
Glama
PeerGlass

PeerGlass

by duksh

πŸ” PeerGlass β€” Internet Resource Intelligence

PeerGlass Branding

Protocol note: PeerGlass uses RDAP (Registration Data Access Protocol β€” RFC 7480–7484). RDAP (RFC 7480–7484) is the IANA-mandated JSON successor to legacy plain-text WHOIS. Where you see "historical-whois" in source code or API responses, that is RIPE Stat's own name for their endpoint β€” it is not our protocol choice.

Query all 5 global Regional Internet Registries simultaneously using RDAP, validate routes via RPKI, inspect BGP routing visibility, trace full historical allocation timelines, discover IXP peering data via PeeringDB, and monitor network health β€” all from natural language in Claude or via REST API.


What Are the 5 RIRs?

Think of the internet's IP address space like a global land registry. IANA (the root) delegates large blocks to 5 regional bodies:

RIR

Region

Countries

🌍 AFRINIC

Africa

54

🌏 APNIC

Asia-Pacific

56 economies

🌎 ARIN

North America

USA, Canada, Caribbean

🌎 LACNIC

Latin America & Caribbean

33

🌍 RIPE NCC

Europe, Middle East, Central Asia

75+


Related MCP server: NetworksDB-MCP

Quick Start

Install

git clone https://github.com/duksh/peerglass
cd peerglass
pip install -e .

Configure MCP Clients (Claude and others)

PeerGlass runs as a standard MCP stdio server (mcp.run() in server.py), so any MCP-compatible AI client can use it β€” not just Claude Desktop.

For Claude Desktop, edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "peerglass": {
      "command": "peerglass",
      "args": []
    }
  }
}

If peerglass is not in your PATH, use:

{
  "mcpServers": {
    "peerglass": {
      "command": "python",
      "args": ["/full/path/to/peerglass/server.py"]
    }
  }
}

Restart Claude Desktop. All 42 tools become immediately available.

Start the REST API

uvicorn api:app --host 0.0.0.0 --port 8000 --reload

Interactive docs at: http://localhost:8000/docs

Start the Web UI

cd ui
npm install
npm run dev        # Dev server at http://localhost:5173

For production build:

cd ui
npm run build      # Output in ui/dist/

Set VITE_API_BASE_URL to point at your PeerGlass API deployment:

VITE_API_BASE_URL=https://api.peerglass.io npm run build

Example Queries (Natural Language in Claude)

Phase 1 β€” Registry lookups:

"Who owns the IP address 185.220.101.1?"
"What is the abuse contact for 8.8.8.8?"
"Who is AS13335 registered to?"
"Are all 5 RIR RDAP servers online right now?"

Phase 2 β€” Routing security:

"Is the route 1.1.1.0/24 via AS13335 RPKI valid?"
"Is 8.8.8.0/24 currently visible in the global BGP table?"
"What prefixes is AS15169 (Google) announcing right now?"
"Find all internet resources registered to Cloudflare globally."

Phase 3 β€” Historical intelligence:

"Show me the full registration history of 8.8.8.0/24."
"Has the prefix 192.0.2.0/24 ever been transferred between organizations?"
"Give me the global IPv4 exhaustion stats for all 5 RIRs."
"Show me the prefix hierarchy for 1.1.1.0/24 β€” parent blocks and sub-assignments."

Phase 4 β€” Peering, IXPs, health & monitoring:

"Who does AS13335 (Cloudflare) peer with at internet exchanges?"
"List all IXPs where Google has a presence."
"Is the network for 1.1.1.0/24 currently healthy β€” any ROA issues or BGP anomalies?"
"Monitor AS13335 for changes since last baseline."

Phase 5 β€” DNS intelligence:

"What DNS records does cloudflare.com have?"
"Is the DNSSEC chain valid for google.com?"
"Check if 1.2.3.4 is on any spam blocklist."
"Audit the email security posture of example.com."
"Has my DNS change for api.example.com propagated globally yet?"

Phase 6 β€” TLS, certificates & threat intel:

"When does the TLS certificate for cloudflare.com expire?"
"Show me all certificates ever issued for *.example.com."
"Is 198.51.100.1 flagged as malicious β€” what ports and CVEs does Shodan see?"
"What hostnames has the IP 1.2.3.4 served historically?"

All 42 MCP Tools

Phase 1 β€” Registry Queries

Tool

Description

Cache TTL

rir_query_ip

Query all 5 RIRs for an IP address (parallel)

1 hour

rir_query_asn

Query all 5 RIRs for an ASN (parallel)

1 hour

rir_get_abuse_contact

Find abuse contact for any IP globally

1 hour

rir_server_status

Health check all 5 RDAP servers

live

rir_cache_stats

View query cache state and TTLs

live

Phase 2 β€” Routing Intelligence

Tool

Description

Cache TTL

rir_check_rpki

Validate RPKI/ROA status for prefix + ASN

15 min

rir_check_bgp_status

Check BGP visibility for a prefix or ASN

5 min

rir_get_announced_prefixes

List all BGP-announced prefixes for an ASN

5 min

rir_audit_org

Audit all IP/ASN resources for an organization

6 hours

Phase 3 β€” Historical Intelligence

Tool

Description

Cache TTL

rir_prefix_history

Full ownership timeline for any prefix or ASN

12 hours

rir_detect_transfers

Detect cross-org / cross-RIR resource transfers

12 hours

rir_ipv4_stats

Global IPv4/IPv6/ASN dashboard + optional delegated IPv4 block listing (include_blocks, filters, pagination)

24 hours

rir_prefix_overview

Prefix hierarchy: parent, children, BGP status

1 hour

Phase 4 β€” Peering, IXPs, Health & Monitoring

Tool

Description

Cache TTL

rir_peering_info

PeeringDB peering data + BGP neighbours for an ASN

1 hour

rir_ixp_lookup

Search Internet Exchange Points globally

6 hours

rir_network_health

RPKI + BGP + RDAP health composite check

5 min

rir_change_monitor

Detect changes since last baseline (delta report)

live

Phase 5 β€” DNS Intelligence

Tool

Description

Cache TTL

peerglass_dns_resolve

DNS resolution with RDAP IP correlation (A/AAAA/PTR/MX/TXT/NS…)

5 min

peerglass_dns_enumerate

Full DNS record enumeration β€” all types in one call + SPF/DMARC extraction

5 min

peerglass_dns_dnssec

DNSSEC chain-of-trust validation (SECURE / INSECURE / BOGUS / INDETERMINATE)

5 min

peerglass_dns_dnsbl

DNS blocklist check against 30 RBLs in parallel (Spamhaus, Barracuda, SORBS…)

15 min

peerglass_dns_email_security

Email security audit: SPF, DMARC, DKIM, MX, BIMI + risk score

15 min

peerglass_dns_propagation

DNS propagation check across 10 global resolvers simultaneously

live

Phase 6 β€” TLS, Certificates & Threat Intelligence

Tool

Description

Cache TTL

peerglass_tls_inspect

TLS certificate inspection: subject, SANs, expiry, cipher suite, HSTS

1 hour

peerglass_ct_logs

Certificate Transparency log search via crt.sh β€” discover all certs ever issued

6 hours

peerglass_threat_intel

Threat intelligence: Shodan InternetDB (open ports, CVEs) + GreyNoise (classification, risk score)

15 min

peerglass_passive_dns

Passive DNS history via RIPE Stat β€” what IPs/hostnames were associated over time

12 hours

Phase 7 β€” BGP Depth

Tool

Description

Cache TTL

rir_check_irr

IRR route object validation via IRRExplorer β€” checks RIPE/RADB/ARIN/APNIC/LACNIC consistency

1 hour

rir_detect_route_leak

BGP route leak detection β€” identifies valley-free violations and multi-origin anomalies

5 min

rir_looking_glass

BGP looking glass via RIPE RIS β€” real AS paths from global vantage points

5 min

rir_route_stability

Route flap and stability analysis β€” state changes, uptime %, stability score

15 min

Phase 8 β€” Humanitarian & Crisis Intelligence

Tool

Description

Cache TTL

peerglass_shutdown_detect

Country BGP shutdown detection β€” compares current prefix counts vs baseline

5 min

peerglass_monitor_register

Register webhook alerts for shutdown/change events

live

peerglass_shutdown_timeline

Historical BGP shutdown timeline with SHA-256 integrity hash (for UN reports)

1 hour

peerglass_dns_censorship

DNS censorship fingerprinting β€” detects NXDOMAIN injection, IP poisoning, DPI blocking

10 min

peerglass_satellite_connectivity

Satellite internet tracking β€” Starlink, Viasat, OneWeb BGP presence

15 min

peerglass_country_chokepoints

Country internet chokepoint mapping β€” critical transit providers, resilience score

6 hours

peerglass_ooni_report

OONI censorship measurements β€” blocked domains, Tor accessibility, circumvention tools

30 min

peerglass_country_health

Composite country internet health dashboard β€” 0–100 score from BGP + DNS + OONI + satellite

5 min

Phase 9 β€” Advanced Platform

Tool

Description

Cache TTL

rir_as_relationships

AS relationship classification (provider/customer/peer) via CAIDA AS-Rank API

7 days

peerglass_geo_lookup

GeoIP enrichment via MaxMind GeoLite2-City (requires PEERGLASS_GEOIP_DB env var)

24 hours

peerglass_atlas_trace

RIPE Atlas distributed traceroute from global vantage points (requires PEERGLASS_RIPE_ATLAS_KEY)

5 min


REST API β€” 41 Endpoints

PeerGlass exposes every tool as a REST endpoint, allowing integration with dashboards, scripts, and CI/CD pipelines β€” no Claude required.

Registry & Routing

Method

Endpoint

Description

GET

/v1/ip/{ip}

RDAP lookup for an IP address

GET

/v1/asn/{asn}

RDAP lookup for an ASN

GET

/v1/abuse/{ip}

Abuse contact for any IP

GET

/v1/rpki?prefix=...&asn=...

RPKI validation

GET

/v1/bgp/{resource}

BGP visibility status

GET

/v1/announced/{asn}

Announced prefixes for an ASN

GET

/v1/org?name=...

Audit all resources for an org name

GET

/v1/history/{resource}

Prefix/ASN ownership history

GET

/v1/transfers/{resource}

Transfer detection

GET

/v1/stats/ipv4

Global IPv4/IPv6/ASN stats

GET

/v1/overview/{prefix}

Prefix hierarchy overview

GET

/v1/peering/{asn}

Peering info from PeeringDB

GET

/v1/ixp

IXP search and listing

GET

/v1/health/{resource}

Composite network health check

GET

/v1/monitor/{resource}

Change monitoring (delta)

DNS Intelligence

Method

Endpoint

Description

GET

/v1/dns/resolve/{target}

DNS resolution + RDAP IP correlation

GET

/v1/dns/enumerate/{domain}

Full DNS record enumeration (all types)

GET

/v1/dns/dnssec/{domain}

DNSSEC chain-of-trust validation

GET

/v1/dns/dnsbl/{ip}

DNS blocklist check (30 RBLs in parallel)

GET

/v1/dns/email/{domain}

Email security audit (SPF/DMARC/DKIM/BIMI)

GET

/v1/dns/propagation/{domain}

DNS propagation across 10 global resolvers

TLS, Certificates & Threat Intel

Method

Endpoint

Description

GET

/v1/tls/{hostname}

TLS certificate inspection

GET

/v1/ct/{domain}

Certificate Transparency log search

GET

/v1/threat/{ip}

Threat intelligence (Shodan + GreyNoise)

GET

/v1/pdns/{resource}

Passive DNS history (RIPE Stat)

BGP Depth

Method

Endpoint

Description

GET

/v1/irr?prefix=...&asn=...

IRR route object validation

GET

/v1/route-leak/{prefix}

BGP route leak detection

GET

/v1/looking-glass/{prefix}

BGP looking glass (RIPE RIS)

GET

/v1/stability/{prefix}

Route flap stability analysis

Humanitarian & Crisis

Method

Endpoint

Description

GET

/v1/shutdown/{country_code}

Country BGP shutdown detection

POST

/v1/shutdown/monitor

Register shutdown webhook alert

GET

/v1/shutdown/timeline/{resource}

Historical shutdown timeline

GET

/v1/censorship/{domain}

DNS censorship fingerprinting

GET

/v1/satellite/{country_code}

Satellite connectivity status

GET

/v1/chokepoints/{country_code}

Country internet chokepoints

GET

/v1/ooni/{country_code}

OONI censorship measurements

GET

/v1/health/country/{country_code}

Composite country internet health

Advanced Platform

Method

Endpoint

Description

GET

/v1/as-relationships/{asn}

AS relationship classification (CAIDA)

GET

/v1/geo/{ip}

GeoIP enrichment (MaxMind GeoLite2)

GET

/v1/atlas/{target}

RIPE Atlas distributed traceroute

POST

/v1/bulk

Bulk query up to 50 resources in one call

Quick example:

# Look up who owns 1.1.1.1
curl http://localhost:8000/v1/ip/1.1.1.1

# Validate RPKI for Cloudflare's prefix
curl "http://localhost:8000/v1/rpki?prefix=1.1.1.0/24&asn=AS13335"

# Get BGP peers for Google
curl http://localhost:8000/v1/peering/AS15169

# List AFRINIC delegated IPv4 blocks (allocated + Ghana), paginated
curl "http://localhost:8000/v1/stats/ipv4?rir=AFRINIC&include_blocks=true&status=allocated&country=GH&limit=5&offset=0&format=json"

# DNS β€” enumerate all record types for a domain
curl http://localhost:8000/v1/dns/enumerate/cloudflare.com

# DNS β€” check email security (SPF/DMARC/DKIM)
curl http://localhost:8000/v1/dns/email/cloudflare.com

# DNS β€” check if an IP is on any blocklist
curl http://localhost:8000/v1/dns/dnsbl/1.2.3.4

# DNS β€” check propagation across 10 global resolvers
curl "http://localhost:8000/v1/dns/propagation/cloudflare.com?record_type=A"

# TLS β€” inspect certificate for a hostname
curl http://localhost:8000/v1/tls/cloudflare.com

# Certificates β€” find all certs ever issued for a domain
curl http://localhost:8000/v1/ct/cloudflare.com

# Threat intel β€” open ports, CVEs, risk score for an IP
curl http://localhost:8000/v1/threat/1.2.3.4

# Passive DNS β€” what hostnames has this IP served?
curl http://localhost:8000/v1/pdns/1.1.1.1

Interactive docs (Swagger UI): http://localhost:8000/docs


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    PEERGLASS                            β”‚
β”‚                                                         β”‚
β”‚   Claude (LLM)              REST Clients                β”‚
β”‚       β”‚ MCP / stdio              β”‚ HTTP                 β”‚
β”‚       β–Ό                          β–Ό                      β”‚
β”‚   server.py (42 tools)      api.py (41 endpoints)       β”‚
β”‚       β”‚                          β”‚                      β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚
β”‚                  β–Ό                                       β”‚
β”‚           rir_client.py  ── All async HTTP calls         β”‚
β”‚                  β”‚                                       β”‚
β”‚       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚
β”‚       β–Ό          β–Ό                  β–Ό                   β”‚
β”‚  normalizer.py  formatters.py    cache.py               β”‚
β”‚  (unify RDAP)   (markdown/JSON)  (TTL tiers)            β”‚
β”‚       β”‚                                                  β”‚
β”‚       β–Ό                                                  β”‚
β”‚    models.py  (Pydantic v2 data models)                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

External APIs called at runtime:
  β”œβ”€β”€ RDAP:    rdap.afrinic.net / rdap.apnic.net / rdap.arin.net
  β”‚            rdap.lacnic.net  / rdap.db.ripe.net
  β”œβ”€β”€ RPKI:    rpki.cloudflare.com
  β”œβ”€β”€ BGP:     stat.ripe.net (bgp-state, announced-prefixes,
  β”‚            routing-status, asn-neighbours, historical-whois)
  β”œβ”€β”€ IXP:     peeringdb.com/api/net, /api/ix, /api/netixlan
  β”œβ”€β”€ Stats:   NRO Extended Delegation Stats (all 5 RIRs)
  └── Routing: data.iana.org/rdap/ (IANA bootstrap)

How Parallel Queries Work

asyncio.gather() fires all 5 RIR queries at exactly the same time:

  AFRINIC ──── responds in 1.1s ──── 404 Not Found
  APNIC   ──── responds in 0.9s ──── βœ… 200 OK  ← authoritative
  ARIN    ──── responds in 1.2s ──── 404 Not Found
  LACNIC  ──── responds in 1.4s ──── 404 Not Found
  RIPE    ──── responds in 0.8s ──── 404 Not Found

Total wall-clock time: ~1–2s (parallel) vs ~6–8s (sequential)

Web UI (Sprint 7)

PeerGlass includes a search-first, dark terminal-themed web frontend built with React 18 + Vite 5 + TypeScript + Tailwind CSS.

Features

  • Auto-detection: Paste any IP, ASN, prefix, domain, or 2-letter country code β€” the UI auto-detects the type and runs the right tool

  • 7 tool categories: Registry Β· Routing Β· DNS Β· TLS Β· Threat Β· Crisis Β· Peering

  • Dark terminal theme: Dark background, monospace font (JetBrains Mono), cyan/green accent palette

  • Markdown rendering: All API results rendered as formatted markdown with syntax highlighting

  • Crisis dashboard: One-click country health check for Syria, Myanmar, Ukraine, Belarus, Iran, Russia and more

  • 41 tools accessible: Every REST endpoint is exposed via the UI

Configuration

Variable

Default

Description

VITE_API_BASE_URL

http://localhost:8000

PeerGlass API base URL

Directory structure

ui/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ App.tsx                  # Main layout + tab state
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ SearchBar.tsx        # Search input with auto-type detection
β”‚   β”‚   β”œβ”€β”€ ResultPanel.tsx      # Markdown result renderer
β”‚   β”‚   β”œβ”€β”€ TabBar.tsx           # Category + tool tab navigation
β”‚   β”‚   β”œβ”€β”€ StatusBadge.tsx      # RPKI/BGP/shutdown status indicators
β”‚   β”‚   └── CountryDashboard.tsx # Crisis country quick-access grid
β”‚   β”œβ”€β”€ hooks/
β”‚   β”‚   └── usePeerGlass.ts      # Query state management hook
β”‚   └── api/
β”‚       └── client.ts            # Typed wrappers for all 41 endpoints
└── dist/                        # Production build output

Testing

PeerGlass has two separate test suites serving different purposes. You should run both β€” they catch different categories of problems.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   TESTING PYRAMID                           β”‚
β”‚                                                             β”‚
β”‚      πŸ”Ί INTEGRATION TESTS  (test_integration.py)            β”‚
β”‚      /\   Real internet. Real APIs. Real data.              β”‚
β”‚     /  \  Proves the product actually works end-to-end.     β”‚
β”‚    /────\  Run this on your machine or a GCP VM.            β”‚
β”‚                                                             β”‚
β”‚   πŸ”Ί UNIT / STATIC TESTS  (test_peerglass.py)              β”‚
β”‚   /\   In-memory. No network. Instant.                      β”‚
β”‚  /  \  Proves code structure, branding, and wiring.         β”‚
β”‚ /────\  Runs anywhere including CI/CD.                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Test 1 β€” Static / Unit Tests (test_peerglass.py)

What it checks:

#

Test

What It Verifies

1

Compile check

All 7 .py files parse without syntax errors

2

Branding audit

No stale legacy product/server identity strings

3

RDAP endpoints

All 5 RIR RDAP URLs are present and correct

4

Protocol header

Accept: application/rdap+json is set

5

User-Agent

Updated to peerglass/1.0.0

6

MCP server name

"peerglass"

7

Tool count

Exactly 42 @mcp.tool() decorators in server.py

8

REST endpoints

All 41 routes present in api.py

9

FastAPI runtime

TestClient hits 3 endpoints in-memory, validates responses

10

README

PeerGlass branding, 42 tools, RDAP note all present

How to run:

cd peerglass
python test_peerglass.py

Expected output:

============================================================
PEERGLASS β€” COMPLETE TEST SUITE
============================================================
1. COMPILE CHECK
   βœ… server.py  βœ… rir_client.py  βœ… formatters.py
   βœ… models.py  βœ… cache.py  βœ… normalizer.py  βœ… api.py

2. BRANDING AUDIT β€” no stale WHOIS identity strings
   βœ… server.py  βœ… rir_client.py  βœ… README.md  ...

...

βœ… ALL TESTS PASSED β€” 0 errors
  Python files: 7  |  MCP tools: 42  |  REST endpoints: 41
  Protocol: RDAP throughout (RFC 7480-7484)
  Branding: PeerGlass throughout
============================================================

When to run: Before every commit. Runs in under 3 seconds. No internet required.


Test 2 β€” Integration Tests (test_integration.py)

What it checks:

Real HTTP calls to external internet registries/data providers using well-known, stable test fixtures (Cloudflare AS13335, Google AS15169, 1.1.1.0/24). Every test asserts on actual response data β€” not just that the server responded.

#

Test

API Called

Fixture

Assertion

1

RDAP reachability

All 5 RIRs

1.1.1.1

HTTP 200 or 404 (both mean server is up)

2

RDAP IP lookup

APNIC

1.1.1.1

objectClassName=ip network, startAddress=1.1.1.0

3

RDAP ASN lookup

ARIN

AS13335

objectClassName=autnum, name contains CLOUDFLARE

4

RPKI validation

RIPE Stat

1.1.1.0/24 AS13335

status=ok, validation status is valid

5

BGP status

RIPE Stat

1.1.1.0/24

Prefix visible to RIS peers, origin ASN present

6

Announced prefixes

RIPE Stat

AS13335

>= 5 prefixes, mix of IPv4 + IPv6

7

Historical data

RIPE Stat

AS15169

status=ok, historical object versions returned

8

PeeringDB network

PeeringDB

AS13335

Network record found, peering policy present

9

IANA Bootstrap

IANA

AS13335

Mapped to correct RDAP service URL

10

AFRINIC RDAP

AFRINIC

102.176.0.0

objectClassName=ip network, African country code

11

ASN neighbours

RIPE Stat

AS13335

Upstream / peer ASN list returned

12

PeeringDB IXPs

PeeringDB

global

IXP list with name and country

13

IANA consistency

IANA/ICANN

IPv4 + IPv6 + ASN bootstrap files

All 5 RIR service URLs present

How to run:

# On your local machine or a GCP VM (requires internet access)
cd peerglass
python test_integration.py

Expected output (passing):

============================================================
  PEERGLASS β€” LIVE INTEGRATION TEST SUITE
  Real HTTP calls. No mocks. No fakes.
============================================================
  Time: 2026-02-20 14:00:00 UTC
  APIs: RIPE Β· ARIN Β· APNIC Β· LACNIC Β· AFRINIC Β· RIPE Stat Β· PeeringDB Β· IANA

────────────────────────────────────────────
  TEST 1 β€” RDAP Server Reachability (all 5 RIRs)
────────────────────────────────────────────
   βœ… PASS  RIPE RDAP reachable      HTTP 404
   βœ… PASS  ARIN RDAP reachable      HTTP 404
   βœ… PASS  APNIC RDAP reachable     HTTP 200
   βœ… PASS  LACNIC RDAP reachable    HTTP 404
   βœ… PASS  AFRINIC RDAP reachable   HTTP 404

...

============================================================
  SUMMARY
  Checks run   : 48
  βœ… Passed    : 47
  ❌ Failed    : 0
  ⚠️  Skipped  : 1
  Duration     : ~20-40s

  πŸŽ‰ ALL TESTS PASSED β€” PeerGlass live APIs confirmed working!
============================================================

When to run:

  • Before a release

  • After any change to rir_client.py (the HTTP layer)

  • After any change to the external API URLs or parameters

  • On a schedule (e.g. daily cron on a GCP VM) to detect API changes upstream

Why this cannot run in CI/CD without configuration: The integration tests require outbound internet access to external APIs (RIPE, ARIN, APNIC, LACNIC, AFRINIC, RIPE Stat, PeeringDB, IANA). Standard CI runners (GitHub Actions free tier) have internet access, so these tests can run there. Restricted sandboxes (Anthropic Claude environment, some corporate proxies) will block the outbound calls and every test will fail with 403 Forbidden β€” this is expected behaviour of the sandbox, not a bug in PeerGlass.


Understanding Test Results

Why does RDAP return 404 and still pass?

APNIC owns 1.1.1.0/24 (Cloudflare's block). If you ask RIPE for 1.1.1.1:

  You:  GET https://rdap.db.ripe.net/ip/1.1.1.1
  RIPE: HTTP 404

This 404 is RIPE saying "I know about this IP but it's not mine."
The server is alive and working correctly. 404 = server reachable.
200 = server reachable AND it's the authoritative RIR for that IP.
Both are valid success states for the reachability test.

Why does Test 7 sometimes SKIP?

RIPE Stat's historical-whois endpoint has variable coverage. For some ASNs it returns rich history; for others the objects array is empty. An empty array is a valid API response β€” the skip is logged to distinguish "no data" from "API broken".


Running Both Suites Together

cd peerglass

# Step 1: Always run static tests first (fast, catches code errors)
python test_peerglass.py
echo "Exit code: $?"

# Step 2: Only run integration tests if static tests pass
if [ $? -eq 0 ]; then
    python test_integration.py
fi

Verification β€” Source-Pinned Retrieval vs Model Recall

If you want to verify that PeerGlass is deterministic and source-pinned (real API retrieval) rather than model recall, run this quick check.

  1. Ask ChatGPT to fetch all 5 RIR RDAP endpoints for 1.1.1.1 and return raw JSON only.

  2. Repeat the exact same prompt multiple times.

  3. Compare ChatGPT output against direct endpoint results below.

Use this prompt in ChatGPT:

For IP 1.1.1.1, query these exact RDAP endpoints and return ONLY JSON:

- AFRINIC: https://rdap.afrinic.net/rdap/ip/1.1.1.1
- APNIC: https://rdap.apnic.net/ip/1.1.1.1
- ARIN: https://rdap.arin.net/registry/ip/1.1.1.1
- LACNIC: https://rdap.lacnic.net/rdap/ip/1.1.1.1
- RIPE: https://rdap.db.ripe.net/ip/1.1.1.1

Output schema per RIR:
{
  "rir": "...",
  "url": "...",
  "http_status": ...,
  "objectClassName": "... or null",
  "handle": "... or null",
  "error": "... or null"
}

Do not summarize. Do not infer.

Ground-truth script (direct endpoint calls):

python - <<'PY'
import asyncio
import json
import httpx

ENDPOINTS = {
    "AFRINIC": "https://rdap.afrinic.net/rdap/ip/1.1.1.1",
    "APNIC": "https://rdap.apnic.net/ip/1.1.1.1",
    "ARIN": "https://rdap.arin.net/registry/ip/1.1.1.1",
    "LACNIC": "https://rdap.lacnic.net/rdap/ip/1.1.1.1",
    "RIPE": "https://rdap.db.ripe.net/ip/1.1.1.1",
}

async def query_one(client, rir, url):
    try:
        r = await client.get(url, timeout=20)
        content_type = r.headers.get("content-type", "")
        data = r.json() if "json" in content_type else {}
        return {
            "rir": rir,
            "url": url,
            "http_status": r.status_code,
            "objectClassName": data.get("objectClassName"),
            "handle": data.get("handle"),
            "error": None,
        }
    except Exception as exc:
        return {
            "rir": rir,
            "url": url,
            "http_status": None,
            "objectClassName": None,
            "handle": None,
            "error": str(exc),
        }

async def main():
    headers = {
        "Accept": "application/rdap+json",
        "User-Agent": "peerglass/verification",
    }
    async with httpx.AsyncClient(headers=headers, follow_redirects=True) as client:
        results = await asyncio.gather(*[
            query_one(client, rir, url) for rir, url in ENDPOINTS.items()
        ])
    print(json.dumps(results, indent=2))

asyncio.run(main())
PY

If ChatGPT outputs are inconsistent or fail to fetch while direct calls are stable, that difference is exactly why PeerGlass uses deterministic source-pinned retrieval.


Adding Your Own Integration Tests

The test_integration.py script is designed to be extended. Each test follows this pattern:

async def test_your_thing():
    section("TEST N β€” Short description")
    print("  What API, what fixture, what you expect")

    url = "https://example-api.com/endpoint"
    params = {"resource": "your-fixture", "sourceapp": "peerglass-test"}
    headers = {"Accept": "application/json", "User-Agent": "peerglass/1.0.0 (integration-test)"}

    try:
        async with httpx.AsyncClient(timeout=25.0) as client:
            resp = await client.get(url, params=params, headers=headers)

        if resp.status_code != 200:
            fail("API returned 200", f"HTTP {resp.status_code}"); return

        data = resp.json()
        value = data.get("some", {}).get("field", "")

        ok("Field is what I expected", f"value='{value}'") if value == "expected" else fail("Field check", f"Got '{value}'")

    except Exception:
        fail("API call failed", traceback.format_exc()[-120:])

Then add it to the main() coroutine:

async def main():
    ...
    await test_your_thing()   # ← add here
    ...

External APIs Used

API

Purpose

Cache TTL

All 5 RIR RDAP endpoints

IP/ASN registration data (RDAP JSON)

1 hr

data.iana.org/rdap/

Bootstrap: which RIR owns which IP/ASN range

permanent

rpki.cloudflare.com

RPKI/ROA validation (Validated ROA Payloads)

15 min

stat.ripe.net/data/bgp-state

BGP routing table visibility

5 min

stat.ripe.net/data/announced-prefixes

Prefixes announced by an ASN

5 min

stat.ripe.net/data/asn-neighbours

BGP peer/upstream/downstream ASNs

1 hr

stat.ripe.net/data/historical-whois

RDAP object change history (RIPE's naming)

12 hr

stat.ripe.net/data/allocation-history

Allocation lifecycle events

12 hr

stat.ripe.net/data/prefix-overview

Prefix hierarchy metadata

1 hr

stat.ripe.net/data/routing-status

Routing status and visibility

5 min

peeringdb.com/api/net

Network peering policies

1 hr

peeringdb.com/api/ix

Internet Exchange Point directory

6 hr

peeringdb.com/api/netixlan

Network-to-IXP membership records

1 hr

NRO Extended Delegation Stats

Authoritative IPv4/IPv6/ASN allocation counts (all 5 RIRs)

24 hr


Phase 3 Data Sources Explained

RIPE Stat historical-whois

Records every change ever made to an RDAP object: when the org field changed, when the status changed, when a new maintainer was added. Used by rir_prefix_history and rir_detect_transfers. The name "historical-whois" is RIPE Stat's own endpoint naming β€” PeerGlass uses RDAP protocol throughout.

Coverage: Best for RIPE NCC resources. Partial for other RIRs.

RIPE Stat allocation-history

Logs the full allocation lifecycle: when a block was first allocated from the RIR pool, when it was sub-allocated to an ISP, when it was returned.

NRO Extended Delegation Stats

Published daily by each RIR as a pipe-delimited text file. Contains every single IP and ASN record ever created, with current status. Authoritative source for rir_ipv4_stats.

RIPE Stat prefix-overview / less-specifics / more-specifics

Three APIs queried in parallel to build the prefix hierarchy tree for rir_prefix_overview.


Use Case Workflows

BGP Hijack Investigation

1. rir_query_ip(suspicious_ip)         β†’ Who registered this IP?
2. rir_check_bgp_status(prefix)        β†’ Which ASN is announcing it right now?
3. rir_check_rpki(prefix, asn)         β†’ Is the announcement RPKI-valid?
4. rir_prefix_overview(prefix)         β†’ Any unexpected more-specifics?
5. rir_detect_transfers(prefix)        β†’ Did this block recently change hands?

M&A Due Diligence

1. rir_audit_org(company_name)         β†’ What IP blocks does this company own?
2. rir_prefix_history(each_prefix)     β†’ When were they acquired?
3. rir_detect_transfers(each_prefix)   β†’ Were any transferred recently?
4. rir_get_announced_prefixes(asn)     β†’ What are they actively routing?

Peering & IXP Analysis

1. rir_get_peering_info(asn)           β†’ Where does this network peer?
2. rir_lookup_ixps(city or ixp_name)  β†’ Find IXPs in a region
3. rir_network_health(asn)             β†’ Is the network healthy?
4. rir_change_monitor(asn)             β†’ Any changes since last check?

Policy Research / ISOC Report

1. rir_ipv4_stats()                    β†’ Full global IPv4/IPv6/ASN dashboard
2. rir_ipv4_stats(rir_filter="AFRINIC")β†’ Africa-specific detail
3. Compare ipv6_total_prefixes across  β†’ IPv6 adoption rates by region

IPv4 Exhaustion Context

RIR

IPv4 Free Pool Exhausted

APNIC

15 April 2011

RIPE NCC

14 September 2012

ARIN

24 September 2015

LACNIC

June 2020

AFRINIC

2020–2021

All RIRs now operate under transfer policies. IPv4 addresses trade on the secondary market. rir_ipv4_stats tracks remaining pools in real time.


License

MIT

Available Tools

42 tools
peerglass_atlas_traceA
Read-only

Launch a RIPE Atlas traceroute measurement to a target IP or hostname.

Uses the RIPE Atlas global probe network (thousands of vantage points). Requires PEERGLASS_RIPE_ATLAS_KEY environment variable with a valid Atlas API key (free from atlas.ripe.net).

Args: params (AtlasTraceInput): - target (str): IP address or hostname - probes (int): Number of probes to use (default 5, max 25) - response_format (str): 'markdown' (default) or 'json'

Returns: str: Traceroute hop tables per probe with RTT and IP at each hop.

Inputs: params (required). Returns: result

peerglass_country_chokepointsA
Read-onlyIdempotent

Map internet resilience for a country by identifying transit providers that many in-country ASNs depend on, and computing a resilience score.

Countries with 1–2 dominant upstream providers are catastrophically vulnerable β€” cutting those providers isolates the entire country.

Args: params (ChokePointInput): - country_code (str): ISO 3166-1 alpha-2 code e.g. 'SY', 'BY' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Resilience score (0–100), transit providers by dependency, single-upstream count.

Inputs: params (required). Returns: result

peerglass_country_healthA
Read-onlyIdempotent

Composite country internet health score combining: β€’ BGP shutdown detection (40%) β€” routing table withdrawal analysis β€’ DNS censorship probe (30%) β€” neutral vs ISP resolver comparison β€’ OONI app score (20%) β€” blocked domains and tool access β€’ Satellite availability (10%) β€” Starlink/Viasat/OneWeb BGP presence

Gives journalists, NGO directors, and crisis responders a single 0–100 score and plain-language summary of internet conditions.

Args: params (CountryHealthInput): - country_code (str): ISO 3166-1 alpha-2 code e.g. 'UA', 'SY', 'MM' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Overall score, severity level, component scores, and plain-language summary.

Inputs: params (required). Returns: result

peerglass_ct_logsA
Read-onlyIdempotent

Search crt.sh for all TLS certificates ever issued for a domain via Certificate Transparency logs. Returns deduplicated entries showing common name, issuer CA, validity period, and SAN name_value.

Useful for:

  • Discovering shadow IT / undocumented subdomains

  • Auditing which CAs have been used for a domain

  • Finding certificates issued before/after security incidents

  • Verifying certificate rotation

Args: params (CTLogInput): - domain (str): Domain name (e.g. 'cloudflare.com') - limit (int): Max entries to return (default 50, max 500) - response_format (str): 'markdown' (default) or 'json'

Returns: str: Certificate log table with CN, CA, validity dates, and unique CA summary.

Inputs: params (required). Returns: result

peerglass_dns_censorshipA
Read-onlyIdempotent

Probe for DNS censorship by querying a domain from multiple resolver vantage points β€” neutral global resolvers (Cloudflare, Google, Quad9) and optionally country-specific ISP resolvers.

Detects: β€’ NXDOMAIN injection β€” domain exists globally but ISP returns NXDOMAIN β€’ IP poisoning β€” ISP returns a different (block-page) IP β€’ DPI block β€” timeout / connection refused

Args: params (CensorshipProbeInput): - domain (str): Domain to probe e.g. 'twitter.com' - country_code (str, optional): ISO code for country-specific resolvers - response_format (str): 'markdown' (default) or 'json'

Returns: str: Censorship status, technique, and per-resolver response table.

Inputs: params (required). Returns: result

peerglass_dns_dnsblA
Read-onlyIdempotent

Check an IPv4 address against 30 DNS blocklists simultaneously, including Spamhaus ZEN, Barracuda, SORBS, URIBL, and more. All queries run in parallel for fast results.

Args: params (DNSBLInput): - ip (str): IPv4 address to check (e.g. '1.2.3.4') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Per-list listed/clean status with return codes and descriptions.

Inputs: params (required). Returns: result

peerglass_dns_dnssecA
Read-onlyIdempotent

Validate the DNSSEC chain-of-trust for a domain. Checks DNSKEY, DS, and RRSIG records and reports SECURE / INSECURE / BOGUS / INDETERMINATE.

BOGUS status means signatures exist but fail validation β€” a serious indicator of misconfiguration or potential tampering.

Args: params (DNSSECInput): - domain (str): Domain name (e.g. 'cloudflare.com') - response_format (str): 'markdown' (default) or 'json'

Returns: str: DNSSEC status, chain validity, record counts, and signing algorithms.

Inputs: params (required). Returns: result

peerglass_dns_email_securityA
Read-onlyIdempotent

Comprehensive email security posture check for a domain:

  • SPF: record presence, validity, and policy strength (-all / ~all / ?all)

  • DMARC: policy (none/quarantine/reject), pct coverage, rua/ruf reporting

  • DKIM: probes common selectors (google, selector1, default, k1, mail …)

  • MX: mail server records

  • BIMI: brand indicator for message identification

  • Risk score: LOW / MEDIUM / HIGH / CRITICAL with specific issues listed

Args: params (EmailSecurityInput): - domain (str): Domain name (e.g. 'example.com') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Full email security audit with risk level, score, and recommendations.

Inputs: params (required). Returns: result

peerglass_dns_enumerateA
Read-onlyIdempotent

Enumerate all common DNS record types for a domain in one call: A, AAAA, MX, NS, TXT, SOA, CNAME, CAA, SRV β€” plus extracts SPF and DMARC policies inline.

Args: params (DNSEnumerateInput): - domain (str): Domain name (e.g. 'cloudflare.com') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Per-type record tables with TTL values and extracted SPF/DMARC.

Inputs: params (required). Returns: result

peerglass_dns_propagationA
Read-onlyIdempotent

Check whether a recent DNS change has propagated globally by querying 10 geographically distributed resolvers simultaneously: Cloudflare (1.1.1.1), Google (8.8.8.8), Quad9, OpenDNS, Comodo, Verisign, Level3, FreeDNS, CleanBrowsing, and Alternate DNS.

Compares each resolver's answer to the majority answer and reports which resolvers are stale, diverging, or failing.

Args: params (DNSPropagationInput): - domain (str): Domain name (e.g. 'cloudflare.com') - record_type (str): DNS record type to check (default: A) - response_format (str): 'markdown' (default) or 'json'

Returns: str: Per-resolver answer table with propagation status and majority answer.

Inputs: params (required). Returns: result

peerglass_dns_resolveA
Read-onlyIdempotent

Resolve a hostname or reverse-lookup an IP address and correlate the result with RDAP registration data (holder, country, RIR, covering prefix).

Args: params (DNSResolveInput): - target (str): Hostname or IP address (e.g. '8.8.8.8', 'cloudflare.com') - record_type (str): DNS record type β€” A, AAAA, PTR, MX, TXT, NS, CNAME … - response_format (str): 'markdown' (default) or 'json'

Returns: str: DNS records table + RDAP owner details for each resolved IP.

Inputs: params (required). Returns: result

peerglass_geo_lookupA
Read-onlyIdempotent

Look up the geographic location of an IP address using MaxMind GeoLite2.

Returns city, region, country, coordinates, and timezone when available. Requires the PEERGLASS_GEOIP_DB environment variable pointing to a GeoLite2-City.mmdb file (free download from maxmind.com with account).

Args: params (GeoLookupInput): - ip (str): IPv4 or IPv6 address - response_format (str): 'markdown' (default) or 'json'

Returns: str: City, region, country, coordinates, timezone, EU membership.

Inputs: params (required). Returns: result

peerglass_monitor_registerA
Idempotent

Register a country code, ASN, or prefix for shutdown monitoring with a webhook URL. When the withdrawn% exceeds the threshold, PeerGlass will POST a JSON alert to the webhook.

Args: params (MonitorRegisterInput): - resource (str): Country code, ASN, or prefix to monitor - webhook_url (str): HTTPS URL to POST alerts to - threshold_pct (float): Alert threshold in % withdrawn (default 20%) - interval_minutes (int): Polling interval (default 5 min)

Returns: str: Registration confirmation and registration count.

Inputs: params (required). Returns: result

peerglass_ooni_reportA
Read-onlyIdempotent

Fetch OONI (Open Observatory of Network Interference) censorship measurements for a country over the last 30 days.

Shows confirmed blocked websites, Tor accessibility, and circumvention tool status (Psiphon, OpenVPN, Signal) as measured by OONI probes running inside the country.

Args: params (OONIReportInput): - country_code (str): ISO 3166-1 alpha-2 code e.g. 'IR', 'RU' - domain (str, optional): Filter to a specific domain - response_format (str): 'markdown' (default) or 'json'

Returns: str: Blocked domains, Tor accessibility, and circumvention tool status.

Inputs: params (required). Returns: result

peerglass_passive_dnsA
Read-onlyIdempotent

Query RIPE Stat Passive DNS for historical DNS records associated with an IP address or domain name. Shows what hostnames pointed to an IP (or what IPs a hostname resolved to) over time, with first/last seen timestamps and observation counts.

Useful for:

  • Tracing infrastructure changes over time

  • Finding previously-used domains for an IP

  • Investigating historical malware C2 infrastructure

  • Attribution and threat hunting

Data source: RIPE NCC's Passive DNS system, which aggregates DNS queries from recursive resolvers across the network.

Args: params (PassiveDNSInput): - resource (str): IP address or domain name - limit (int): Max records (default 100, max 500) - response_format (str): 'markdown' (default) or 'json'

Returns: str: Historical DNS records table with rrtype, value, and first/last seen dates.

Inputs: params (required). Returns: result

peerglass_satellite_connectivityA
Read-onlyIdempotent

Check whether satellite internet providers (Starlink, Viasat, OneWeb, SES, Inmarsat, HughesNet) are actively announcing BGP prefixes.

During ground-based internet shutdowns, satellite services often remain the only available connectivity option for journalists and aid workers.

Args: params (SatelliteConnectivityInput): - country_code (str): ISO 3166-1 alpha-2 code (used for context) - response_format (str): 'markdown' (default) or 'json'

Returns: str: Per-provider active status and announced prefix count.

Inputs: params (required). Returns: result

peerglass_shutdown_detectA
Read-onlyIdempotent

Detect internet shutdowns at the country level by comparing current BGP prefix counts against a stored baseline.

On the first call for a country the baseline is established. Subsequent calls measure how many prefixes have been withdrawn and classify severity: β€’ NORMAL < 5% withdrawn β€’ DEGRADED 5–20% withdrawn β€’ PARTIAL_SHUTDOWN 20–80% withdrawn β€’ FULL_SHUTDOWN > 80% withdrawn

Args: params (ShutdownDetectInput): - country_code (str): ISO 3166-1 alpha-2 code e.g. 'SY', 'IR', 'MM' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Severity level, withdrawn percentage, and sampled ASN prefix counts.

Inputs: params (required). Returns: result

peerglass_shutdown_timelineA
Read-onlyIdempotent

Retrieve a timestamped BGP withdrawal/restoration timeline for a country or ASN over a date range. Includes a SHA-256 content hash for evidence integrity verification (useful for UN reports, press, legal proceedings).

Args: params (ShutdownTimelineInput): - resource (str): Country code (e.g. 'SY') or ASN (e.g. 'AS29256') - start_date (str): ISO date e.g. '2023-10-07' - end_date (str): ISO date e.g. '2023-10-14' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Timeline of BGP events, total downtime hours, and SHA-256 integrity hash.

Inputs: params (required). Returns: result

peerglass_threat_intelA
Read-onlyIdempotent

Passive threat intelligence for an IP address from two sources:

  1. Shodan InternetDB (always available, no API key required):

    • Open ports detected via internet scanning

    • CVE identifiers for detected services

    • Reverse DNS hostnames

    • Shodan tags (cdn, vpn, tor-exit, etc.)

  2. GreyNoise Community (requires GREYNOISE_API_KEY env var):

    • Classification: malicious / benign / unknown

    • RIOT flag: trusted service (Google, Amazon, etc.)

    • Noise flag: benign internet background scanner

    • Named actor or service attribution

Produces an aggregated risk score (0–100) and level (LOW / MEDIUM / HIGH / CRITICAL).

Args: params (ThreatIntelInput): - ip (str): IPv4 address (e.g. '1.2.3.4') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Open ports, CVEs, GreyNoise classification, and risk assessment.

Inputs: params (required). Returns: result

peerglass_tls_inspectA
Read-onlyIdempotent

Connect to hostname:port over TLS and return full certificate details: subject, issuer, Subject Alternative Names (SANs), expiry date, days remaining, self-signed flag, TLS protocol version, cipher suite, chain length, and HSTS header presence.

Useful for:

  • Verifying certificate validity before expiry

  • Detecting self-signed or untrusted certificates

  • Checking TLS configuration (version, cipher suite)

  • Auditing HSTS deployment

Args: params (TLSInspectInput): - hostname (str): Target hostname (e.g. 'cloudflare.com') - port (int): TCP port β€” default 443 - response_format (str): 'markdown' (default) or 'json'

Returns: str: Certificate details, expiry countdown, issuer chain, and HSTS status.

Inputs: params (required). Returns: result

rir_as_relationshipsA
Read-onlyIdempotent

Fetch AS relationship data from CAIDA AS-Rank API.

Classifies neighbouring ASNs as: β€’ Providers (upstream transit) β€’ Customers (downstream networks) β€’ Peers (settlement-free peering)

Unlike RIPE Stat asn-neighbours (which only gives left/right/uncertain), CAIDA AS-Rank uses a BGP-path-based inference algorithm for higher accuracy.

Args: params (ASRelationshipInput): - asn (str): ASN e.g. 'AS13335' or '13335' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Classified providers, customers, and peers with relationship type.

Inputs: params (required). Returns: result

rir_audit_orgA
Read-onlyIdempotent

Find all IP blocks and ASNs registered to an organization across all RIRs.

Searches RDAP entity databases at AFRINIC, APNIC, ARIN, and RIPE (LACNIC does not support RDAP entity search β€” a limitation is noted). Aggregates results into a unified inventory.

Use cases:

  • M&A due diligence: What internet resources does Company X own globally?

  • Security research: What is the full IP footprint of an organization?

  • ICANN/RIR policy: Are resources distributed across multiple RIRs?

  • Incident response: Did this org transfer/sell IP space recently?

Tips:

  • Use org handles for precision (e.g. 'GOOGL-ARIN' not 'Google')

  • Partial name matching is supported (e.g. 'Cloudflare' finds 'Cloudflare Inc.')

  • Results are cached for 6 hours.

Args: params (OrgAuditInput): - org_name (str): Organization name or handle (e.g. 'Cloudflare', 'GOOGL-ARIN') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Summary of all IP blocks and ASNs by RIR, with handles, names, countries, and allocation dates. JSON schema: { "org_query": str, "total_resources": int, "ip_blocks": [{"rir": str, "handle": str, "prefix_or_asn": str, "name": str, "country": str}], "asns": [...], "rirs_found_in": [str], "errors": [str] }

Inputs: params (required). Returns: result

rir_cache_statsA
Read-onlyIdempotent

View the current state of the in-memory TTL cache.

The cache prevents repeated queries to RIRs within short windows, respecting rate limits and reducing latency for repeated lookups.

Returns: str: JSON with cache entry counts (total, alive, expired) and the configured TTL for each query type. Schema: { "cache_stats": {"total_entries": int, "alive": int, "expired": int}, "ttl_seconds": {"ip": int, "asn": int, "org": int, "abuse": int, "bgp": int, "rpki": int} }

Inputs: no named parameters. Returns: result

rir_change_monitorA
Read-only

Monitor a prefix or ASN for registration and BGP routing changes between calls.

How it works:

  • First call: captures a baseline snapshot of RDAP + BGP state. Stores it in memory for the server's lifetime.

  • Subsequent calls: fetches the current state and diffs it against the baseline. Reports exactly which fields changed and from what to what.

  • When changes are detected: automatically updates the baseline so the next call diffs from the new state (not the original).

  • reset_baseline=True: discards any stored baseline and captures fresh.

Tracked fields (8 total): RDAP: Holder, RIR, Country, Allocation Status, Abuse Email BGP: Announced (bool), Origin ASN(s), Visibility %

Severity of changes: πŸ”΄ BGP Origin ASN changed β†’ possible hijack, verify with rir_check_rpki πŸ”΄ RDAP Holder changed β†’ possible transfer, check rir_detect_transfers 🟑 BGP Announced changed β†’ prefix appeared/disappeared from routing 🟑 Country changed β†’ registration country updated 🟒 Visibility % changed β†’ normal BGP fluctuation

Baseline persists in server memory β€” not in a database. If the server restarts, baselines are lost and will be recreated on next call.

Args: params (ChangeMonitorInput): - resource (str): IP prefix (e.g. '8.8.8.0/24') or ASN (e.g. 'AS15169') - reset_baseline (bool): If True, discard baseline and start fresh

Returns: str: Baseline created confirmation (first call), or diff table (subsequent calls). JSON schema: { "resource": str, "status": str, (baseline_created|changes_detected|no_changes) "baseline_captured_at": str, "checked_at": str, "changes": [{"field": str, "old_value": str, "new_value": str}], "current_holder": str, "current_rir": str, "message": str }

Inputs: params (required). Returns: result

rir_check_bgp_statusA
Read-onlyIdempotent

Check whether a prefix or ASN is currently visible in the global BGP routing table.

Uses RIPE Stat (which aggregates data from RIPE RIS route collectors worldwide). BGP is the internet's routing protocol β€” the "GPS" that tells traffic how to navigate from one network to another.

For a prefix, returns:

  • Whether it is currently announced in BGP

  • Which ASN(s) are announcing it (multiple = potential hijack)

  • Percentage of global BGP peers that can see it (visibility)

For an ASN, returns:

  • Whether the ASN has any active BGP announcements

  • A list of all announced prefixes (use rir_get_announced_prefixes for details)

Combine with rir_check_rpki for complete routing security assessment. Results are cached for 5 minutes (BGP tables change frequently).

Args: params (BGPStatusInput): - resource (str): Prefix (e.g. '1.1.1.0/24') or ASN (e.g. 'AS15169') - response_format (str): 'markdown' (default) or 'json'

Returns: str: BGP visibility, announcing ASNs, and prefix list. JSON schema: { "resource": str, "resource_type": str, "is_announced": bool, "announcing_asns": [str], "visibility_percent": float, "announced_prefixes": [{"prefix": str, "peers_seeing": int}] }

Inputs: params (required). Returns: result

rir_check_irrA
Read-onlyIdempotent

Check IRRExplorer for route objects covering a prefix and verify they are consistent with the claimed origin ASN.

IRR (Internet Routing Registry) route objects tell ISPs which ASN is authorised to originate a prefix. Inconsistent or missing route objects can cause route filtering and reachability issues even when RPKI is valid.

Args: params (IRRCheckInput): - prefix (str): CIDR prefix e.g. '1.1.1.0/24' - asn (str): Expected origin ASN e.g. 'AS13335' or '13335' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Route objects per IRR source, consistency status, and missing IRR coverage.

Inputs: params (required). Returns: result

rir_check_rpkiA
Read-onlyIdempotent

Validate a prefix + ASN pair against the global RPKI using Cloudflare's validator.

RPKI (Resource Public Key Infrastructure) is the internet's route security framework. RIRs issue Route Origin Authorizations (ROAs) β€” digital certificates that cryptographically prove an ASN is authorized to announce a prefix.

Validity states: βœ… VALID β€” A matching ROA exists. Route is cryptographically authorized. 🚨 INVALID β€” A ROA exists but this ASN/prefix violates it. Possible hijack. ⚠️ NOT-FOUND β€” No ROA exists. Route is unverified (common, not inherently bad). ❓ UNKNOWN β€” Could not determine validity.

Combine with rir_check_bgp_status for full routing security assessment.

Results are cached for 15 minutes (ROAs can change, but not frequently).

Args: params (RPKICheckInput): - prefix (str): CIDR prefix e.g. '1.1.1.0/24' or '2400:cb00::/32' - asn (str): Originating ASN e.g. 'AS13335' or '13335'

Returns: str: RPKI validity state, description, and list of covering ROAs. JSON schema: { "prefix": str, "asn": str, "validity": "valid"|"invalid"|"not-found"|"unknown", "covering_roas": [{"asn": int, "prefix": str, "maxLength": int}], "description": str }

Inputs: params (required). Returns: result

rir_detect_route_leakA
Read-onlyIdempotent

Detect potential BGP route leaks or hijacks for a prefix using RIPE Stat BGP-state data.

Checks for:

  • Multiple distinct origin ASNs (possible hijack β€” two ASNs claiming the same prefix)

  • AS-path loops (valley-free violations β€” a transit ASN re-exporting a learned route)

Args: params (RouteLeakInput): - prefix (str): CIDR prefix e.g. '1.1.1.0/24' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Leak detection result with confidence, suspect ASNs, and anomalous AS paths.

Inputs: params (required). Returns: result

rir_detect_transfersA
Read-onlyIdempotent

Detect past ownership or cross-RIR transfers for an IP prefix or ASN.

An ownership transfer happens when a registered org (e.g. 'GOOGL-ARIN') changes to another org ('META-1-ARIN') in the registration record. A cross-RIR transfer is rarer β€” it means the resource physically moved between registries (e.g. from ARIN to RIPE NCC after an acquisition).

Transfer types detected: 🏒 Org Change β€” The registering organization changed πŸŒβ†’πŸŒŽ Cross-RIR β€” The resource moved to a different RIR πŸ”„ Intra-RIR β€” Maintainer changed within the same RIR

How it works: compares consecutive historical WHOIS object versions. If 'org' or 'mnt-by' changed between versions, a transfer is flagged. If RIR-specific suffixes in the handles differ, it's cross-RIR.

Results are cached for 12 hours.

Args: params (TransferDetectInput): - resource (str): IP prefix (e.g. '8.8.8.0/24') or ASN (e.g. 'AS15169') - response_format (str): 'markdown' (default) or 'json'

Returns: str: List of detected transfers with dates, types, from/to org, and evidence. JSON schema: { "resource": str, "resource_type": str, "transfers_detected": int, "transfers": [{"transfer_date": str, "transfer_type": str, "from_org": str, "to_org": str, "from_rir": str, "to_rir": str, "evidence": str}], "current_holder": str, "first_registered": str, "sources": [str], "notes": [str] }

Inputs: params (required). Returns: result

rir_get_abuse_contactA
Read-onlyIdempotent

Find the abuse contact for any IP address globally using IANA bootstrap routing.

Uses IANA RDAP Bootstrap to identify the authoritative RIR first (efficient), then queries only that RIR. Falls back to querying all 5 if bootstrap fails. Extracts abuse contacts from entity roles: 'abuse', 'technical', 'noc'.

Use this tool as the first step in any network abuse reporting workflow: spam, DDoS attacks, port scanning, credential stuffing, etc.

Results are cached for 1 hour.

Args: params (AbuseContactInput): - ip_address (str): IPv4 or IPv6 address (e.g. '185.220.101.1')

Returns: str: Markdown report with abuse email(s), phone(s), network name, organization, country, and authoritative RIR. JSON schema: { "ip_address": str, "authoritative_rir": str, "abuse_email": [str], "abuse_phone": [str], "network_name": str, "org_name": str, "country": str }

Inputs: params (required). Returns: result

rir_get_announced_prefixesA
Read-onlyIdempotent

Retrieve all IP prefixes currently being announced by an ASN in BGP.

This shows the ASN's complete routing footprint β€” every IP range it is actively advertising to the global internet via BGP. Uses RIPE Stat's announced-prefixes endpoint.

Useful for:

  • Understanding an organization's complete IP footprint

  • Detecting unexpected prefix announcements (possible hijacks)

  • M&A due diligence on network assets

  • Security research and threat intelligence

min_peers_seeing filters out unstable/flapping routes that only a small number of BGP peers can see. Higher = more stable routes only.

Results are cached for 5 minutes.

Args: params (AnnouncedPrefixesInput): - asn (str): ASN to query (e.g. 'AS13335' or '15169') - min_peers_seeing (int): Minimum peer count filter (default: 5)

Returns: str: Complete list of announced prefixes with peer visibility and first/last seen timestamps. JSON schema: { "resource": str, "is_announced": bool, "announced_prefixes": [ {"prefix": str, "peers_seeing": int, "first_seen": str, "last_seen": str} ] }

Inputs: params (required). Returns: result

rir_ipv4_statsA
Read-onlyIdempotent

Fetch global IPv4, IPv6, and ASN allocation statistics from all 5 RIRs.

Parses the NRO Extended Delegation Stats files β€” the authoritative daily publication of how each RIR has distributed address space:

  • How many IPv4 prefixes allocated (to ISPs) vs assigned (to end users)

  • Remaining free IPv4 pool (where published β€” most RIRs are exhausted)

  • IPv6 prefix count and growth

  • Total ASNs issued

Why this matters:

  • IPv4 was exhausted at IANA in 2011

  • APNIC exhausted in 2011, RIPE in 2012, ARIN in 2015

  • LACNIC near exhaustion 2020, AFRINIC followed

  • IPv6 transition is the only long-term solution

  • This tool lets you track adoption and exhaustion state in real time

Results are cached for 24 hours (stats files are published once daily).

Args: params (IPv4StatsInput): - rir_filter (str, optional): Filter to one RIR ('AFRINIC', 'APNIC', 'ARIN', 'LACNIC', 'RIPE'). Leave empty for all 5. - include_blocks (bool): Include raw delegated IPv4 blocks for the selected RIR. Requires rir_filter to be set. - status_filter (str, optional): allocated | assigned | available (free is normalized). - country_filter (str, optional): 2-letter country code filter (e.g. 'GH', 'ZA'). - limit (int): Max number of block rows when include_blocks=true. - offset (int): Pagination offset for block rows. - response_format (str): 'markdown' (default) or 'json'

Returns: str: Per-RIR table of IPv4/IPv6/ASN counts with totals and exhaustion context. JSON schema: { "queried_at": str, "rirs": [{"rir": str, "region": str, "ipv4_total_prefixes": int, "ipv4_allocated": int, "ipv4_assigned": int, "ipv4_available": int, "ipv6_total_prefixes": int, "asn_total": int, "stats_date": str}], "global_ipv4_prefixes": int, "global_ipv6_prefixes": int, "global_asns": int, "ipv4_blocks": [ {"rir": str, "country": str|null, "start_ip": str, "end_ip": str, "address_count": int, "date": str|null, "status": str} ], "blocks_total": int, "blocks_returned": int, "blocks_limit": int|null, "blocks_offset": int|null, "blocks_filters": {"rir_filter": str|null, "status_filter": str|null, "country_filter": str|null} }

Inputs: params (required). Returns: result

rir_ixp_lookupA
Read-onlyIdempotent

Search PeeringDB for Internet Exchange Points (IXPs) by country code or name.

An IXP is a physical location where ISPs and networks directly interconnect. Without IXPs, all traffic between two ISPs would travel via paid transit providers, costing more and adding latency. IXPs are the backbone of regional internet ecosystems.

Searching by country:

  • Use 2-letter ISO country code: 'MU' (Mauritius), 'ZA' (South Africa), 'DE' (Germany), 'US' (United States), 'SG' (Singapore)

Searching by name:

  • Partial name match: 'AMS-IX', 'LINX', 'Nairobi', 'Frankfurt'

Notable IXPs worldwide:

  • DE-CIX Frankfurt (Germany) β€” Europe's busiest, 13+ Tbps

  • AMS-IX (Netherlands) β€” 10+ Tbps

  • LINX (UK) β€” London Internet Exchange

  • JPNAP (Japan) β€” Asia-Pacific hub

  • Nap.Africa / JINX β€” African exchanges

  • MAURITIUS-IX β€” your local exchange!

Results are cached for 12 hours.

Args: params (IXPLookupInput): - query (str): 2-letter country code (e.g. 'MU') or IXP name fragment - response_format (str): 'markdown' (default) or 'json'

Returns: str: Table of matching IXPs with city, country, member count, and contact. JSON schema: { "query": str, "total_found": int, "ixps": [{"name": str, "city": str, "country": str, "member_count": int, "website": str, "tech_email": str}], "errors": [str] }

Inputs: params (required). Returns: result

rir_looking_glassA
Read-onlyIdempotent

Show BGP routing table entries for a prefix as seen from RIPE RIS (Route Information Service) collectors around the world.

Unlike BGP visibility (which answers whether a route exists), a looking glass shows how the route is announced β€” the actual AS paths from different geographic vantage points.

Args: params (LookingGlassInput): - prefix (str): CIDR prefix e.g. '1.1.1.0/24' - vantage_points (int): Max entries to return (default 10, max 50) - response_format (str): 'markdown' (default) or 'json'

Returns: str: AS paths per RIPE RIS collector with region and BGP community values.

Inputs: params (required). Returns: result

rir_network_healthA
Read-onlyIdempotent

Run a comprehensive parallel health check on any IP address, prefix, or ASN.

Fires all checks simultaneously (parallel asyncio): RDAP β†’ Who owns it? Which RIR? Country? Abuse contact? BGP β†’ Is it announced? Which ASNs? What global visibility %? RPKI β†’ Is the announcing ASN cryptographically authorized? (prefix only) PeeringDB β†’ Peering policy? NOC email? IXP count? (ASN only)

Synthesises a health signal dashboard: βœ… All good β€” registered, announced, RPKI valid ⚠️ Warning β€” not announced, unprotected route (no ROA), missing contacts 🚨 Critical β€” RPKI invalid (possible hijack!), multiple origin ASNs (MOAS)

This is your first-response tool for:

  • "Is this IP address legitimate?"

  • "Is this ASN healthy and reachable?"

  • "Is there anything suspicious about this prefix?"

  • NOC incident triage, security team first-response

Results are cached for 5 minutes (includes live BGP data).

Args: params (NetworkHealthInput): - resource (str): IP ('1.1.1.1'), prefix ('1.1.1.0/24'), or ASN ('AS13335') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Health signal dashboard + RDAP + BGP + RPKI + PeeringDB sections. JSON schema: { "resource": str, "resource_type": str, "queried_at": str, "rdap_holder": str, "rdap_rir": str, "rdap_country": str, "bgp_announced": bool, "bgp_announcing_asns": [str], "bgp_visibility_pct": float, "rpki_validity": str, "peering_policy": str, "peering_ixp_count": int, "health_signals": [str], "errors": [str] }

Inputs: params (required). Returns: result

rir_peering_infoA
Read-onlyIdempotent

Fetch peering policy, IXP presence, NOC contacts, and BGP neighbours for an ASN.

Data sources (queried in parallel):

  • PeeringDB (www.peeringdb.com) β€” the internet's peering registry

  • RIPE Stat asn-neighbours β€” live BGP upstream/downstream relationships

Information returned:

  • Peering policy: Open / Selective / Restrictive / No Peering

  • IRR AS-SET (used in route filters, e.g. AS-CLOUDFLARE)

  • NOC email, abuse email, peering contact email

  • IXP presence: which exchange points, peering IPs, link speed

  • BGP neighbours: up to 30 adjacent ASNs in the routing table

Use cases:

  • "Does Cloudflare have an Open peering policy?"

  • "Which IXPs is AS13335 present at?"

  • "What is the NOC email for AS1234 to report an incident?"

  • "Is this ASN a residential ISP or a CDN?"

Results are cached for 6 hours.

Args: params (PeeringInfoInput): - asn (str): ASN to look up (e.g. 'AS13335', '13335', 'AS-CLOUDFLARE') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Peering policy table, IXP presence table, contacts, BGP neighbours. JSON schema: { "asn": str, "network_name": str, "policy_general": str, "noc_email": str, "irr_as_set": str, "ixp_presence": [{"name": str, "city": str, "country": str, "ipaddr4": str, "ipaddr6": str, "speed": int}], "neighbour_asns": [str], "errors": [str] }

Inputs: params (required). Returns: result

rir_prefix_historyA
Read-onlyIdempotent

Fetch the complete registration history for an IP prefix or ASN.

Returns a chronological timeline of every change ever recorded:

  • Initial registration (who, when, under which RIR)

  • Org / maintainer changes (potential ownership transfers)

  • Status changes (allocated β†’ assigned β†’ available)

  • Last-changed updates

Uses RIPE Stat's historical-whois and allocation-history APIs. Coverage is best for RIPE NCC resources; partial for other RIRs.

Use cases:

  • "Has this IP block ever changed hands?"

  • "When was this ASN first registered?"

  • "What organization historically owned this prefix?"

  • Due diligence, incident response, fraud investigation

Results are cached for 12 hours (historical records are stable).

Args: params (PrefixHistoryInput): - resource (str): IP prefix (e.g. '8.8.8.0/24') or ASN (e.g. 'AS15169') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Chronological event timeline with dates, event types, and attribute changes. JSON schema: { "resource": str, "resource_type": str, "current_holder": str, "current_rir": str, "registration_date": str, "total_events": int, "events": [{"event_date": str, "event_type": str, "attribute": str, "old_value": str, "new_value": str}], "sources": [str], "errors": [str] }

Inputs: params (required). Returns: result

rir_prefix_overviewA
Read-onlyIdempotent

Fetch a rich hierarchical overview of an IP prefix.

IP address space is organized in a tree structure:

  • A /8 contains 256 /16s, each /16 contains 256 /24s, and so on.

  • 'Less-specific' = the parent block this prefix was carved from.

  • 'More-specific' = smaller blocks assigned within this prefix.

Think of it like a real estate map: Less-specific = the city block (containing your property) The prefix itself = your land parcel More-specific = subdivisions within your parcel

This tool fetches all three layers in parallel (3 RIPE Stat API calls simultaneously) and returns a unified view including:

  • Current holder and announcement status

  • Which ASN(s) are announcing it (multiple = potential hijack)

  • All less-specific (parent) prefixes up the tree

  • All more-specific (child) prefixes within the block

Combine with rir_check_rpki to validate the announcing ASN. Results are cached for 1 hour.

Args: params (PrefixOverviewInput): - prefix (str): IP prefix in CIDR notation (e.g. '1.1.1.0/24') - response_format (str): 'markdown' (default) or 'json'

Returns: str: Holder info, BGP status, and full prefix hierarchy table. JSON schema: { "prefix": str, "holder": str, "rir": str, "country": str, "announced": bool, "announcing_asns": [str], "allocation_status": str, "related_prefixes": [{"prefix": str, "relationship": str, "holder": str, "origin_asn": str}], "errors": [str] }

Inputs: params (required). Returns: result

rir_query_asnA
Read-onlyIdempotent

Query all 5 global RIRs simultaneously for an Autonomous System Number.

An ASN is a unique number assigned to a network operator (ISP, CDN, large enterprise) that participates in BGP routing. Examples: AS15169 = Google, AS13335 = Cloudflare, AS36864 = AFRINIC itself.

Accepts: 'AS15169', '15169', or named sets like 'AS-GOOGLE'. Results are cached for 1 hour.

Args: params (ASNQueryInput): - asn (str): ASN in any format (e.g. 'AS15169', '13335', 'AS-CLOUDFLARE') - response_format (str): 'markdown' (default) or 'json'

Returns: str: ASN registration details including owner, country, allocation date, abuse email, and responses from all 5 RIRs. JSON schema: { "asn": str, "results": [{"rir": str, "status": str}], "normalized": [{"rir": str, "asn": str, "name": str, "org_name": str, "country": str, "abuse_email": str}] }

Inputs: params (required). Returns: result

rir_query_ipA
Read-onlyIdempotent

Query all 5 global RIRs simultaneously for an IP address using RDAP.

Fires parallel RDAP requests to AFRINIC, APNIC, ARIN, LACNIC, and RIPE NCC. Exactly one RIR will be authoritative; the others return 'not found'. Normalizes all responses into a unified schema and returns a clear summary.

Results are cached for 1 hour to respect RIR rate limits.

Args: params (IPQueryInput): - ip_address (str): IPv4 or IPv6 address e.g. '1.1.1.1', '2001:4860:4860::8888' - response_format (str): 'markdown' (default) or 'json'

Returns: str: Registration details including prefix, owner, country, allocation date, abuse email, and responses from all 5 RIRs. JSON schema: { "ip": str, "results": [{"rir": str, "status": str, "error": str|null}], "normalized": [{"rir": str, "prefix": str, "name": str, "org_name": str, "country": str, "allocation_date": str, "abuse_email": str}] }

Inputs: params (required). Returns: result

rir_route_stabilityA
Read-onlyIdempotent

Analyse BGP route stability for a prefix over a configurable time window using RIPE Stat routing-history data.

A stable route has no state changes (no withdrawal/re-announcement cycles). Repeated flapping can indicate hardware failure, misconfiguration, or DDoS and causes router CPU load and convergence delays for peers.

Args: params (RouteStabilityInput): - prefix (str): CIDR prefix e.g. '1.1.1.0/24' - hours (int): Analysis window in hours (default 24, max 168 = 7 days) - response_format (str): 'markdown' (default) or 'json'

Returns: str: Stability score (0–100), state change count, uptime %, and event timeline.

Inputs: params (required). Returns: result

rir_server_statusA
Read-only

Check the real-time health of all 5 RIR RDAP servers simultaneously.

Queries the /help endpoint of each RIR (lightweight, no IP/ASN needed). Returns RDAP conformance levels and availability status.

Use this before bulk queries to verify connectivity, or to diagnose why a specific RIR's responses are failing.

Returns: str: Markdown table with RIR name, region, status (Online/Unreachable), and supported RDAP conformance extensions.

Inputs: no named parameters. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 42 tools

    Disambiguation4/5

    Most tools have distinct purposes, with clear separation between categories like DNS, RIR queries, and internet health monitoring. However, some overlap exists within categories, such as multiple DNS tools that could be confused (e.g., dns_resolve vs dns_enumerate vs dns_propagation), and RIR tools like query_ip and query_asn that might be ambiguous without careful reading of descriptions.

    Naming Consistency5/5

    All tool names follow a consistent snake_case pattern with a clear prefix structure: 'peerglass_' for internet health tools and 'rir_' for RIR-related tools. This predictable naming convention makes it easy to understand the tool's domain and purpose at a glance, with no deviations or mixed styles.

    Tool Count2/5

    With 42 tools, the count is excessive for a single server, making it overwhelming and difficult for an agent to navigate efficiently. While the domain (internet infrastructure and health monitoring) is broad, the tool set feels bloated and could benefit from consolidation or splitting into multiple focused servers to improve usability.

    Completeness5/5

    The tool set provides comprehensive coverage for internet infrastructure analysis, including DNS, BGP, RIR data, threat intelligence, and censorship detection. It supports full CRUD-like operations where applicable (e.g., monitoring registration and detection) and leaves no obvious gaps, enabling agents to perform end-to-end analyses without dead ends.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables network information lookup through WHOIS and RIPE Database queries. Supports domain/IP/ASN lookups, AS-SET expansion, route validation, and contact information retrieval across multiple Regional Internet Registries.
      14
      4
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI assistants to query global BGP routing intelligence, including network investigation, origin history, reachability, and health checks, with 15 tools plus resources and prompts for incident triage and reporting.
      18
      MIT