Skip to main content
Glama
badchars

osint-mcp-server

by badchars

bgp_prefix

Retrieve BGP prefix details: announcing ASNs, name, country, and RIR for any IP prefix and CIDR mask.

Instructions

Look up details for a specific IP prefix/CIDR. Returns announcing ASNs, name, country, and RIR.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
prefixYesIP prefix (e.g. '1.1.1.0')
cidrYesCIDR mask (e.g. 24)

Implementation Reference

  • The bgpPrefix handler function that executes the tool logic. Fetches prefix/CIDR details from BGPView API, returns announcing ASNs, name, country, and RIR with caching (30 min TTL) and rate limiting (2s).
    // ─── Prefix Lookup ───
    
    export async function bgpPrefix(prefix: string, cidr: number): Promise<BgpPrefixResult> {
      const key = `prefix:${prefix}/${cidr}`;
      const cached = cache.get(key);
      if (cached) return cached;
    
      const data = await bgpFetch(`/prefix/${prefix}/${cidr}`);
    
      const result: BgpPrefixResult = {
        prefix: data.prefix,
        cidr: data.cidr,
        asns: (data.asns ?? []).map((a: any) => ({
          asn: a.asn, name: a.name, description: a.description, countryCode: a.country_code,
        })),
        name: data.name ?? "",
        description: data.description_short ?? "",
        countryCode: data.country_code ?? "",
        rir: data.rir_allocation?.rir_name ?? "",
      };
    
      cache.set(key, result);
      return result;
    }
  • The BgpPrefixResult interface defining the return type shape: prefix, cidr, asns array (asn/name/description/countryCode), name, description, countryCode, and rir.
    interface BgpPrefixResult {
      prefix: string;
      cidr: number;
      asns: { asn: number; name: string; description: string; countryCode: string }[];
      name: string;
      description: string;
      countryCode: string;
      rir: string;
    }
  • Tool registration as a ToolDef with name 'bgp_prefix', Zod schema for prefix (string) and cidr (number), description, and execute handler that delegates to bgpPrefix(). Included in allTools array at line 518.
    const bgpPrefixTool: ToolDef = {
      name: "bgp_prefix",
      description: "Look up details for a specific IP prefix/CIDR. Returns announcing ASNs, name, country, and RIR.",
      schema: {
        prefix: z.string().describe("IP prefix (e.g. '1.1.1.0')"),
        cidr: z.number().describe("CIDR mask (e.g. 24)"),
      },
      execute: async (args) => json(await bgpPrefix(args.prefix as string, args.cidr as number)),
    };
    
    // ═══════════════════════════════════════════════════════════════
    // Wayback Machine (2 tools) — CDX API free
    // ═══════════════════════════════════════════════════════════════
    
    const waybackUrlsTool: ToolDef = {
      name: "wayback_urls",
      description: "Search Wayback Machine for archived URLs of a domain. Returns unique URLs with timestamps, status codes, and MIME types. Useful for finding old endpoints, hidden paths, and removed content.",
      schema: {
        domain: z.string().describe("Domain to search archived URLs for"),
        match_type: z.string().optional().describe("CDX match type (exact, prefix, host, domain)"),
        filter: z.string().optional().describe("CDX filter (e.g. 'statuscode:200', 'mimetype:text/html')"),
        limit: z.number().optional().describe("Maximum URLs to return (default: 1000)"),
      },
      execute: async (args) =>
        json(await waybackUrls(
          args.domain as string,
          args.match_type as string | undefined,
          args.filter as string | undefined,
          args.limit as number | undefined,
        )),
    };
    
    const waybackSnapshotsTool: ToolDef = {
      name: "wayback_snapshots",
      description: "Get Wayback Machine snapshot history for a specific URL. Returns timestamps, status codes, and direct archive links. Shows first/last seen dates.",
      schema: {
        url: z.string().describe("URL to get snapshot history for"),
        limit: z.number().optional().describe("Maximum snapshots to return (default: 100)"),
      },
      execute: async (args) =>
        json(await waybackSnapshots(args.url as string, args.limit as number | undefined)),
    };
    
    // ═══════════════════════════════════════════════════════════════
    // HackerTarget (3 tools) — free tier (50/day)
    // ═══════════════════════════════════════════════════════════════
    
    const hackertargetHostsearchTool: ToolDef = {
      name: "hackertarget_hostsearch",
      description: "Find subdomains and their IPs for a domain via HackerTarget. Free tier: 50 queries/day.",
      schema: {
        domain: z.string().describe("Domain to search hosts for"),
      },
      execute: async (args) => json(await hackertargetHostsearch(args.domain as string)),
    };
    
    const hackertargetReverseIpTool: ToolDef = {
      name: "hackertarget_reverseip",
      description: "Reverse IP lookup via HackerTarget — find all domains hosted on an IP. Free tier: 50 queries/day.",
      schema: {
        ip: z.string().describe("IP address for reverse lookup"),
      },
      execute: async (args) => json(await hackertargetReverseIp(args.ip as string)),
    };
    
    const hackertargetAslookupTool: ToolDef = {
      name: "hackertarget_aslookup",
      description: "Look up ASN information for an IP or ASN via HackerTarget. Free tier: 50 queries/day.",
      schema: {
        query: z.string().describe("IP address or ASN to look up"),
      },
      execute: async (args) => json(await hackertargetAslookup(args.query as string)),
    };
    
    // ═══════════════════════════════════════════════════════════════
    // Microsoft 365 (2 tools) — free, no key
    // ═══════════════════════════════════════════════════════════════
    
    const m365TenantTool: ToolDef = {
      name: "m365_tenant",
      description: "Discover Microsoft 365 tenant information for a domain. Returns tenant ID, region, and OpenID configuration endpoints.",
      schema: {
        domain: z.string().describe("Domain to check for M365 tenant"),
      },
      execute: async (args) => json(await m365Tenant(args.domain as string)),
    };
    
    const m365UserRealmTool: ToolDef = {
      name: "m365_userrealm",
      description: "Detect authentication type for a domain's Microsoft 365 tenant. Returns namespace type (Managed/Federated), federation brand name, and auth endpoints.",
      schema: {
        domain: z.string().describe("Domain to check user realm for"),
      },
      execute: async (args) => json(await m365UserRealm(args.domain as string)),
    };
    
    // ═══════════════════════════════════════════════════════════════
    // Meta (2 tools)
    // ═══════════════════════════════════════════════════════════════
    
    const osintListSourcesTool: ToolDef = {
      name: "osint_list_sources",
      description: "List all OSINT data sources, their availability, API key requirements, and tool counts. Use this to check which sources are configured.",
      schema: {},
      execute: async (_args, ctx) => json(await checkSources(ctx)),
    };
    
    const osintDomainReconTool: ToolDef = {
      name: "osint_domain_recon",
      description: "Quick domain reconnaissance combining free sources: DNS (A/MX/NS/TXT), WHOIS, crt.sh subdomains, HackerTarget hosts, and email security analysis. No API keys required.",
      schema: {
        domain: z.string().describe("Domain to perform recon on"),
      },
      execute: async (args) => json(await domainRecon(args.domain as string)),
    };
    
    // ═══════════════════════════════════════════════════════════════
    // All Tools Export
    // ═══════════════════════════════════════════════════════════════
    
    export const allTools: ToolDef[] = [
      // DNS (6)
      dnsLookupTool,
      dnsReverseTool,
      dnsEmailSecurityTool,
      dnsSpfChainTool,
      dnsSrvDiscoverTool,
      dnsWildcardCheckTool,
      // WHOIS (2)
      whoisDomainTool,
      whoisIpTool,
      // crt.sh (1)
      crtshSearchTool,
      // Shodan (4)
      shodanHostTool,
      shodanSearchTool,
      shodanDnsResolveTool,
      shodanExploitsTool,
      // VirusTotal (4)
      vtDomainTool,
      vtIpTool,
      vtSubdomainsTool,
      vtUrlTool,
      // SecurityTrails (3)
      stSubdomainsTool,
      stDnsHistoryTool,
      stWhoisTool,
      // Censys (3)
      censysHostsTool,
      censysHostDetailsTool,
      censysCertificatesTool,
      // GeoIP (2)
      geoipLookupTool,
      geoipBatchTool,
      // BGP (3)
      bgpAsnTool,
      bgpIpTool,
      bgpPrefixTool,
  • src/index.ts:31-31 (registration)
    Listed as one of the available tools in the 'BGP / ASN' category (no API key required) for the --list menu.
    { label: "BGP / ASN", env: null, tools: ["bgp_asn", "bgp_ip", "bgp_prefix"] },
  • The bgpFetch helper utility used by bgpPrefix to make HTTP requests to the BGPView API with rate limiting and error handling.
    // ─── Helpers ───
    
    async function bgpFetch(path: string): Promise<any> {
      await limiter.acquire();
      const res = await fetch(`https://api.bgpview.io${path}`);
      if (!res.ok) throw new Error(`BGPView returned ${res.status}`);
      const json = await res.json();
      if (json.status !== "ok") throw new Error(`BGPView error: ${json.status_message ?? "unknown"}`);
      return json.data;
    }

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.2.0

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It implies a read-only lookup but does not explicitly confirm non-destructiveness or disclose any other behavioral traits. Adequate but not thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, 17 words, front-loaded with the action. Every word earns its place; no superfluous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple lookup tool with fully documented parameters and an explicitly stated output, the description is largely complete. It could optionally mention output format or additional details, but it suffices.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with both parameters described. The description adds context but no additional semantics beyond the schema. Baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool looks up details for a specific IP prefix/CIDR and lists the returned data (ASNs, name, country, RIR). It distinguishes itself from sibling tools like bgp_asn (ASN lookup) and bgp_ip (IP lookup) by focusing on prefix/CIDR.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not provide explicit when-to-use or when-not-to-use guidance. While the context of sibling tools implies differentiation, the description itself lacks such guidance, making it average.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.