fcc-broadband-mcp-server
Provides tools for accessing FCC broadband availability, coverage analysis, and digital divide data for US geographies and census blocks.
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
Public Hosted Server: https://fcc-broadband.caseyjhand.com/mcp
Overview
FCC broadband data from Form 477 (June 2015 – June 2021) and the Broadband Data Collection (June 2022 onward). Geocode coordinates to census blocks, look up the ISPs and advertised speeds at a block, and summarize, compare, or rank geographies by unserved population for BEAD and equity research.
Tools
Tool | Description |
| Convert a lat/lon coordinate to a 2010-vintage census block FIPS code, with county and state identifiers |
| List the providers and advertised speeds at a census block, filtered by technology and speed |
| Find state, county, congressional district, place, CBSA, and tribal GEOIDs by name |
| Population by provider count for one geography, split by urban/rural and tribal/non-tribal |
| Rank coverage across several geographies of the same type, worst first |
| Rank the most underserved areas in a state or nationwide by unserved population |
| Search holding companies by name, state, and technology; returns |
| National coverage profile for one holding company: technologies and population per speed tier |
| List data vintages: Form 477 filing periods and BDC as-of dates |
| List BDC bulk data files for one as-of date |
Resources
Resource | Description |
| Coverage summary for one geography at 25 Mbps |
| One page of the Form 477 holding-company directory, 25 entries per page |
Resource data is also reachable through tools: fcc_get_coverage_summary for geographies, fcc_search_providers for holding companies.
Prompts
Prompt | Description |
| Structure a digital divide analysis that chains FCC coverage with Census and BLS data |
Skill
fcc-broadband-guide covers geography and holding-company identifier chains, comparable population scopes, and sampling limits. It ships with plugin installs, npm, Docker, and the desktop bundle, and is available over MCP at skill://fcc-broadband-guide/SKILL.md.
Related MCP server: OpenUSPublicDataMCP
Capability reference
fcc_geocode_block tool
latitudeandlongitudein decimal degrees, resolved against 2010 census boundaries through the FCC Geo APIReturns
blockFips(15 digits, ready forfcc_search_availability),censusVintage,countyFips,countyName,stateFips,stateCode, andstateName; coordinates over water or outside US coverage fail asblock_not_found. Structured FCC backend faults fail asgeo_backend_unavailablewith guidance to retry the same coordinates later
fcc_search_availability tool
block_fips(15 digits, 2010 vintage) is required;tech_filter(Form 477 technology codes),min_speed_down(Mbps), andconsumer(trueconsumer,falsebusiness) narrow the rowsOne row per offering with
hoconum,techCode/techLabel,maxDownloadMbps,maxUploadMbps,consumer, andbusiness, plustotalProviderscounting distinct holding companies; an unfiltered block with no providers fails asblock_not_found, while a filtered query that matches nothing returns an empty list with anotice
fcc_search_geographies tool
Required nonblank
namematches a case-insensitive literal substring; optionalgeography_typeisstate,county,cd,place,cbsa, ortribal,limitdefaults to 20 (max 100), andoffsetstarts at 0Returns distinct
{ geography_type, geography_id, name }matches in stable name/type/GEOID order, pluscount,offset, andnextOffsetonly when more matches remain. Empty and past-end pages carry guidance; no total count is computedUses the live FCC lookup with
year='2021'even when the mirror is enabled. Include a location qualifier innameto narrow matches; CBSA codes do not establish state membership. Pass the selected type and GEOID tofcc_get_coverage_summary
fcc_get_coverage_summary tool
geography_typeis one ofnation,state,county,cd,place,cbsa,tribal;geography_idis required for every type butnation;urban_rural_filter(all/R/U) andtribal_filter(all/T/N) narrow the populationReturns
populationby provider count (noCoverage,oneProvider,twoProviders,threeOrMore,total),coveragePct,unservedPct,competitivePct, and a per-segmentbreakdown. An empty demographic selection returns zero totals and a notice after confirming geography rows exist; a missing geography still fails asgeography_not_foundRequired reads share a 48-second deadline (
coverage_timeout); invalid geography inputs fail asinvalid_geography_comboorinvalid_geography_id_shapeNational coverage is named
United Stateslocally and retainsgeography.id: "0"; it needs no geography-name lookup
fcc_compare_areas tool
geography_idsof onegeography_type(every type butnation), orcompare_all_states: truefor the 50 states plus DC; the first 300 distinct IDs are compared, with duplicates and excluded IDs disclosed.sort_byisunserved_pct(default),unserved_pop,coverage_pct, orcompetitive_pctEvery sort ranks worst first, so
rank1 is the area most in need; rows carryid,namewhen resolved, the provider-count populations, and all three percentages. Fails asmissing_geography_ids,invalid_all_states_combo,invalid_geography_id_shape, orno_data_foundunmatchedIdsidentifies queried IDs without coverage rows, separately from IDs excluded by the comparison cap. Reads run in batches of at most 50; ranking happens once across all returned statistics
fcc_find_underserved tool
state(USPS state or territory code) scopes the search, otherwise it runs nationwide;geography_typeiscounty(default),cd,place, orcbsa;urban_rural_filterdefaults toR,min_unserved_popto 1, andlimitto 20 (max 100). Startoffsetat 0 and follownextOffsetAreas are ranked globally by
noCoverage, with GEOID tie-breaking, before paging; rows carryrank,id,name,oneProvider,total,unservedPct, andcoveragePct.totalFoundcounts matches before paging. An unrecognizedstatefails asunknown_state; notices distinguish no matching areas from an exhausted page
fcc_search_providers tool
name_search(case-insensitive partial name),state, andtech_filterare all optional and must hold on the same filing;limitdefaults to 50 (max 200). Startoffsetat 0 and follownextOffset; unknown USPS state or territory codes fail asunknown_statebefore queryingDeduplicated holding companies with
hoconum,holdingCompanyName, and nationalstatesServed/techCodesthat the filters never narrow. No match returns an empty list with anotice; a live search over its 30-second budget fails aslive_search_timeoutA full-corpus mirror (
FCC_MIRROR_ENABLED=true) pages the complete matching company set inhoconumorder and reportstotalCount. Against the live API,scanTruncated: truemarks a sample and withholdstotalCount; continuation covers only the sampled set, which can change between calls
fcc_get_provider tool
hoconum(digits only) fromfcc_search_providersor the providers directory resourceReturns
techCodes/techLabelsandspeedTierPopulation, which counts each person once and omits empty tiers; business-only carriers come back with both lists empty. Fails asprovider_not_found, orlive_provider_timeoutpast the 30-second budget
fcc_list_filing_periods tool
Always returns the Form 477 periods;
include_bdc: trueadds BDC as-of dates when credentials are configuredperiodsnewest first, each withasOfDateandsource(form477orbdc), plusform477Count,bdcCount, andhasBdcCredentials; missing credentials leavebdcCountat 0 rather than raising an error
fcc_list_downloads tool
as_of_date(YYYY-MM-DD) is required; filter bydata_type(availabilitydefault, orchallenge),category(Summary,State,Provider),technology_type(Fixed Broadband,Mobile Broadband,Mobile Voice),state, andprovider_name;limitdefaults to 50 (max 200), paged withoffsetReturns file metadata and a
downloadUrlper file, not file contents;totalFilescounts every match andnextOffsetis omitted on the last page. Fails asinvalid_as_of_datefor an unsupported dateAvailable to MCP clients only when both BDC credentials are configured at startup. Otherwise the HTTP landing page retains its disabled card and setup guidance
fcc-broadband://geography/{type}/{id}/summary resource
typetakes the sevenfcc_get_coverage_summarygeography types;idis a FIPS GEOID checked for digit count,0fornationFixed at 25/3 Mbps and satellite-inclusive
acfosw; returnspopulation, the three percentages, andsegmentsasapplication/json. Usefcc_get_coverage_summaryfor the terrestrial default or other thresholds and filters
fcc-broadband://providers/list/{offset} resource
offsetpages the directory 25 entries at a time inhoconumorder; start at0and follownextOffsetEntries carry
hoconumand, when resolved,holdingCompanyName; each page reportstotalandcount. To find one company by name, usefcc_search_providers
broadband_equity_analysis prompt
Arguments:
region(free text) andfocus(underserved,rural,tribal, orall), both requiredReturns one user message laying out a five-step analysis: baseline coverage, focus area, demographic cross-reference, provider landscape, and historical screening context
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
FCC-specific:
Three FCC sources, all US government public-domain data: Form 477 on FCC Open Data (Socrata), the BDC Public Data API, and the FCC Geo API
Every Form 477 tool and resource works without credentials and reads the June 2021 filing, the last one; BDC data is exposed only as bulk-file manifests.
fcc_list_downloadsis advertised to MCP clients only when bothFCC_BDC_USERNAMEandFCC_BDC_HASH_VALUEare configuredThe area tools accept every nonempty alphabetical combination of
aDSL,ccable,ffiber,oother,ssatellite, andwfixed wireless. The defaultacfowexcludes satellite; explicitacfoswincludes it. Deployment tools use numeric technology codes insteadArea speed keys select download/upload pairs in Mbps:
0.2→ 0.2/0.2,4→ 4/1,10→ 10/1,25→ 25/3 (default),100→ 100/10,250→ 250/25, and1000→ 1000/100. Historical population aggregates cannot establish current BEAD eligibility or address service; the 100/10 tier does not establish 100/20 availabilityCoverage analysis reads the pre-aggregated Area Table (
xvwq-qtaj), not the block-level deployment table, so state- and county-scale queries stay fastOptional local Form 477 mirror (
FCC_MIRROR_ENABLED=true) serves queries from SQLite, falling back to the live API for anything not ingested
Agent-friendly output:
Filter echo: search, summary, and ranking tools return
appliedFilters, and every Form 477 result carriesdataVintagePartial results say so:
scanTruncatedandscanRowCapflag a result drawn from a capped upstream scan (fcc_search_providers,fcc_find_underserved), and an empty match returns anoticeinstead of an errorTyped failures: reasons such as
block_not_found,invalid_geography_id_shape, andcredentials_required, each with a recovery hint
Getting started
Public Hosted Instance
A public instance is available at https://fcc-broadband.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"fcc-broadband-mcp-server": {
"type": "streamable-http",
"url": "https://fcc-broadband.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"fcc-broadband-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/fcc-broadband-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"fcc-broadband-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/fcc-broadband-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
Optional: FCC BDC credentials for
fcc_list_downloadsand BDC filing periods. Generate a token at broadbandmap.fcc.gov under "Manage API Access".Optional: a Socrata app token (
FCC_OPENDATA_APP_TOKEN) for higher Form 477 rate limits.
Installation
Clone the repository:
git clone https://github.com/cyanheads/fcc-broadband-mcp-server.gitNavigate into the directory:
cd fcc-broadband-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env and set FCC_BDC_USERNAME, FCC_BDC_HASH_VALUE, and FCC_OPENDATA_APP_TOKEN as neededConfiguration
Variable | Description | Default |
| FCC account email for the BDC API. Needed by | none |
| API token hash from broadbandmap.fcc.gov "Manage API Access". Pairs with | none |
| Socrata app token; raises FCC Open Data rate limits. | none |
| Serve Form 477 queries from the local SQLite mirror where its coverage allows. |
|
| Directory holding the mirror SQLite files. |
|
| Transport: |
|
| HTTP server port. |
|
| HTTP session mode: |
|
| Authentication: |
|
| Log level ( |
|
| Directory for log files (Node.js only). |
|
| Storage backend: |
|
| Enable OpenTelemetry. |
|
See .env.example for the full list of optional overrides.
BDC credentials can come from the process environment or .env; process values take precedence. Empty, whitespace-only, and unsubstituted placeholder values count as absent. Restart after configuring both credentials to enable fcc_list_downloads; Form 477 filing periods remain available without them.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t fcc-broadband-mcp-server .
docker run --rm -p 3010:3010 fcc-broadband-mcp-serverThe Dockerfile defaults to HTTP transport and stateless session mode, logging to /var/log/fcc-broadband-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them. The image also ships the mirror scripts and a writable data/ directory.
Local Form 477 mirror
Form 477 is frozen at the June 2021 filing, so it can be ingested once into a local SQLite index. The mirror is off by default, and the full corpus is about 9 GB of source data and takes hours to ingest, so the bootstrap can be scoped to the states you query:
bun run mirror:init -- --states 11,53 # specific states by 2-digit FIPS (11 = DC, 53 = WA)
bun run mirror:init -- --full # the whole corpus
bun run mirror:verify # coverage, row counts, SQLite integrityThen set FCC_MIRROR_ENABLED=true. In Docker, run the same scripts with docker exec <container> bun run mirror:init -- --states 11,53. Run them from a source checkout or the image: the scripts import through the @/ path alias, which an npm install does not map.
Block and geography lookups serve from the mirror once the queried state is fully ingested; anything else falls back to the live API.
Geography discovery and name resolution always use the live 2021 lookup: the mirror does not retain its year column. Missing names do not discard coverage statistics.
fcc_search_providers,fcc_get_provider, and geographies with no state in their GEOID (cbsa,tribal,nation) serve from the mirror only after a--fullingest.Mirror name search matches word prefixes (
comcfinds "Comcast") where the live API matches any substring (mcast), so a mid-word fragment can return fewer results.The ingest is idempotent and resumes an interrupted run from its saved cursor. Set
FCC_OPENDATA_APP_TOKENfirst for a full ingest. Bun uses the built-inbun:sqlite; Node.js needs the optionalbetter-sqlite3peer dependency.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| Prompt definitions ( |
| FCC Open Data (Socrata) service for Form 477 deployment, area, and provider tables; |
| BDC Public Data API service — authenticated filing periods and download manifests. |
| FCC Geo API service — lat/lon to census block FIPS. |
| Build, devcheck, and packaging scripts, plus |
| Published broadband-analysis guide, also served as an MCP skill resource. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools and resources via the barrels in
src/mcp-server/*/definitions/index.tsWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Socrata returns every field as a string, so parse counts and speeds (
has_0–has_3more,maxaddown,maxadup) explicitly
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
FCC public geo/census APIs (geo.fcc.gov) MCP.
FCC Open Data (opendata.fcc.gov) Socrata MCP.
Broadband availability, providers, speeds, and BEAD classification from the FCC
Query U.S. Census Bureau data, variables, and geography via MCP.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceRemote MCP server exposing US Census (ACS 5-year) and FEMA flood data. Works as a connector in both Claude and ChatGPT.-
- AlicenseBqualityDmaintenanceEnables access to high-value US public data sources via MCP, including federal agencies, state portals, and platforms like Socrata, ArcGIS, and CKAN, with tools for searching, querying, and geographic resolution.16MIT
- AlicenseNot gradedqualityBmaintenanceMCP server to query U.S. Census Bureau data, variables, and geography through 7 tools supporting dataset discovery, variable search, geography resolution, and data queries with suppression code decoding.717 npm3Apache 2.0
- AlicenseNot gradedqualityBmaintenanceAccess EPA environmental data — facility compliance (ECHO), toxic releases (TRI), Superfund sites, drinking water systems, environmental justice screening (EJScreen), and real-time air quality (AirNow) via MCP.628 npm2Apache 2.0