Technical writing

The Voidly MCP Server: 83 Censorship Query Tools for Claude and GPT

· 7 min read· AI Analytics
CensorshipVoidlyMCPInfrastructure

The Voidly dataset is queryable via REST and downloadable from HuggingFace. Both require a developer who knows what they're looking for and how to structure a query or filter. The MCP server is the third access surface — it's designed for AI agent workflows where the agent doesn't know in advance what it needs to look up. Claude or GPT can call query_incidents with a natural-language description of what it wants, and the MCP tool resolves that into structured dataset queries without the agent needing to know the schema.

The server at github.com/voidly-ai/mcp-server exposes 83 tools over JSON-RPC / Streamable HTTP, compatible with Claude's tool use API and OpenAI's function calling. No authentication is required. The dataset is CC BY 4.0.

Connecting from Claude Code or Claude Desktop

# Claude Code — add to .claude/mcp.json in your project root,
# or to ~/.claude/mcp.json for global availability
{
  "mcpServers": {
    "voidly": {
      "command": "npx",
      "args": ["mcp-remote", "https://api.voidly.ai/mcp"]
    }
  }
}

# Claude Desktop — add to claude_desktop_config.json
{
  "mcpServers": {
    "voidly": {
      "command": "npx",
      "args": ["mcp-remote", "https://api.voidly.ai/mcp"]
    }
  }
}

After adding the server, restart Claude Code or Desktop. The 83 Voidly tools become available in any conversation. Claude will automatically invoke them when a question involves internet censorship, shutdown events, or network interference data.

Tool categories

Incident lookup tools (12 tools)

These tools return verified incidents — events that have reached theverified_incident tier with external corroboration from at least one of OONI, CensoredPlanet, or IODA.

  • get_incident — fetch a specific incident by ID
  • list_incidents_by_country — all incidents for a country, paginated
  • list_recent_incidents — most recent N incidents globally
  • search_incidents — free-text search across incident descriptions
  • get_incidents_by_domain — all incidents involving a specific domain
  • get_shutdown_events — country-level full outages only (BGP + IODA)
  • get_active_incidents — incidents currently open (no end date)
  • get_incidents_by_type — filter by interference type
  • get_incidents_by_category — filter by OONI URL category code
  • get_election_adjacent_incidents — incidents within 14 days of an election
  • get_protest_adjacent_incidents — incidents correlated with protest events
  • compare_country_incidents — side-by-side for two countries

Measurement query tools (18 tools)

Raw measurement access — one row per probe test. These are noisier than the incident tools (they include anomaly and corroboratedtier rows, not just verified_incident) but provide finer time resolution.

  • query_measurements — structured query with country, domain, date, tier filters
  • get_measurements_for_domain — all measurements for a domain across all countries
  • get_asn_measurements — measurements by autonomous system number
  • get_blocking_rate — 7-day and 30-day blocking rate for domain × country
  • get_dns_tampering_measurements, get_tls_interference_measurements,get_http_blocking_measurements, get_bgp_withdrawal_measurements,get_throttling_measurements — one tool per interference class
  • get_control_failure_rate — what fraction of measurements had control failures (data quality check)
  • aggregate_by_asn — blocking rates grouped by ISP
  • get_time_series — daily measurement counts and blocking rates over time

Country and coverage tools (15 tools)

  • get_country_summary — censorship overview for a country: probe count, recent incidents, top blocked domains, trend
  • get_country_asn_coverage — which ISPs have Voidly probes
  • get_country_shutdown_history — all shutdown events for a country
  • get_shutdown_forecast — 7-day shutdown probability for a country
  • list_high_risk_countries — countries with active incidents or elevated forecast
  • compare_regional_censorship — aggregated stats for a UN region
  • get_election_calendar — upcoming elections with censorship risk scores

Domain and test list tools (10 tools)

  • get_domain_status — current blocking status for a domain across all countries
  • get_most_blocked_domains — top N domains by blocking rate globally or per country
  • get_test_list — the current URL test list with category codes
  • search_test_list — find domains in the test list by category or keyword

BGP and network infrastructure tools (9 tools)

  • get_bgp_events — BGP prefix withdrawal events for a country
  • get_asn_routing_history — 90-day prefix advertisement history for an ASN
  • get_ioda_signals — IODA BGP, DNS, and telescope signals for a country and time range
  • detect_routing_anomaly — returns whether current BGP state is anomalous vs. baseline

Dataset and metadata tools (19 tools)

  • get_dataset_stats — total measurements, incidents, and coverage counts
  • get_probe_count — current probe count by country and ASN type
  • get_schema — the full measurement dataset schema (returns the field definitions)
  • export_csv — stream a CSV export for a filtered query
  • get_citation_format — APA and BibTeX citation strings for the dataset

Example agent conversations

Journalist: checking current censorship before filing a story

User: What is Voidly seeing in Russia right now?

Claude calls:
  get_country_summary({ country_code: "RU" })
  list_recent_incidents({ country_code: "RU", limit: 10 })
  get_shutdown_forecast({ country_code: "RU" })

Returns: summary of current probe coverage, the 10 most recent verified
incidents (domains blocked, interference type, when detected, which
sources corroborated), and the 7-day shutdown probability.

Researcher: tracking how a specific domain is blocked globally

User: How is signal.org blocked across different countries?

Claude calls:
  get_domain_status({ domain: "signal.org" })
  get_measurements_for_domain({ domain: "signal.org", tier: "verified_incident" })

Returns: a country-by-country breakdown of blocking status, interference
type, and the number of verified incidents, ordered by blocking rate.

Human rights organization: election-period monitoring

User: Are there any censorship events correlated with elections in 2025?

Claude calls:
  get_election_calendar({ year: 2025 })
  get_election_adjacent_incidents({ year: 2025 })

Returns: a list of elections alongside any censorship incidents detected
within 14 days of each election, with interference type and domain category
(NEWS, POLR, COMM, HUMR are the most relevant categories for election monitoring).

Implementation: JSON-RPC over Streamable HTTP

The MCP server implements JSON-RPC 2.0 over Streamable HTTP, as specified in the MCP protocol. Tool calls are POST requests to the base URL; streaming results use Server-Sent Events for tools that return large result sets.

# Direct JSON-RPC call (without MCP client)
curl -X POST https://api.voidly.ai/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_country_summary",
      "arguments": { "country_code": "IR" }
    }
  }'

The server is deployed as a Cloudflare Worker co-located with the Voidly data backend. Most tool responses are served in under 100ms. Tools that aggregate across large date ranges or multiple countries may take 300–800ms.

Rate limits and attribution

No authentication is required. Rate limits are applied per IP: 300 requests per minute for single-entity lookup tools, 60 requests per minute for aggregate and time-series tools. The CC BY 4.0 license applies to all data returned. Attribution format: “Source: Voidly / AI Analytics — voidly.ai (CC BY 4.0)”.


For the full schema of the fields returned by measurement query tools: The Voidly measurement dataset: field-by-field schema reference →

For how the probe architecture that generates the data in these tools works: The Voidly Probe: Tauri + boringtun network measurement at the operator's edge →

For the confidence tier system that determines what data the incident tools return: From anomaly to verified incident: the Voidly confidence tier system →

For the REST API alternative — HTTP endpoints, cursor pagination, streaming NDJSON export, and code samples in curl, Python, and TypeScript: The Voidly REST API: querying the global censorship index in real time →

For the TimescaleDB infrastructure that the MCP tools query — 2.2B rows, continuous aggregates, and the query performance that makes MCP tool responses feel instant: Voidly's measurement database: 2.2B probe results in TimescaleDB →

For the nightly export job that publishes the dataset the MCP tools query — PyArrow schema, Zstandard compression, country+year_month Parquet partitioning, and atomic HuggingFace commit: Voidly's nightly Parquet export: from TimescaleDB to HuggingFace →

For the corroboration engine that determines which incidents the MCP incident tools return — tokio::join! parallel fetches across OONI, CensoredPlanet, and IODA with adaptive polling and independence-weighted scoring: Voidly's real-time corroboration engine: fetching, aligning, and merging OONI, CensoredPlanet, and IODA data →