Skip to main content
Glama

Compare Broadband Coverage Across Areas

fcc_compare_areas
Read-onlyIdempotent

Compares broadband coverage metrics across multiple geographies of the same type and returns a ranked table sorted by unserved or underserved population. Compares historical population coverage gaps; it cannot establish current BEAD eligibility or address service. Compares the first 300 distinct geography IDs and discloses duplicates, unmatched IDs and excluded IDs, or set compare_all_states=true for all 50 states + DC. Data is from FCC Form 477 (as of June 2021).

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "geography_type": "<geography_type>"
    },
    "name": "fcc_compare_areas"
  }
}

Input Schema

NameRequiredDescriptionDefault
sort_byNo"unserved_pct" = share of population with no broadband (default). "unserved_pop" = raw headcount. "coverage_pct" = share with any coverage. "competitive_pct" = share with 2+ providers. Every option ranks worst-first, so rank 1 is the highest unserved share or headcount, or the lowest coverage or competitive share.unserved_pct
speed_downNoDownload key for a download/upload threshold pair in Mbps: 0.2=0.2/0.2, 4=4/1, 10=10/1, 25=25/3, 100=100/10, 250=250/25, 1000=1000/100. These historical population aggregates cannot establish current BEAD eligibility or address service; 100/10 does not establish 100/20 availability.25
tech_filterNoAny nonempty alphabetical combination of a=ADSL/DSL, c=cable, f=fiber, o=other (symmetric DSL, other copper, power line), s=satellite, w=fixed wireless. Default acfow excludes satellite; explicit acfosw includes every technology. acfow includes all fixed wireless and is not an exact program-technology eligibility filter.acfow
geography_idsNoFIPS GEOIDs to compare. The first 300 distinct IDs are queried; remaining distinct IDs are disclosed as excluded. For all 50 states, omit and set compare_all_states=true.
geography_typeYesGeographic level to compare. Must be uniform across all geographies in the comparison.
compare_all_statesNoWhen true, compares all 50 states + DC. Overrides geography_ids. Requires geography_type="state".

Output Schema

NameRequiredDescriptionDefault
areasNoRanked comparison of geographies by the selected sort field.
errorNoPresent when the call failed. Absent on success.
noticeNoComposed disclosure naming unmatched retained IDs, excluded unqueried IDs and duplicate IDs with their counts. Absent when none applies.
sortByNoRanking field used.
techFilterNoTechnology filter applied.
totalAreasNoTotal number of areas compared.
dataVintageNoData vintage — Form 477 data as of June 2021.
excludedIdsNoDistinct geography IDs beyond the first 300, which were not queried.
duplicateIdsNoIDs repeated in the input, listed once in first repeated-occurrence order.
unmatchedIdsNoRetained geography IDs without matching Area Table data.
geographyTypeNoGeography type compared.
speedDownMbpsNoSpeed threshold in Mbps.
appliedFiltersNoFilters and parameters applied to this comparison.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changed
    • changedInput schema / properties / geography_ids / description
      Previous value: -"Array of FIPS GEOIDs to compare (up to 50). For all 50 states, omit and set compare_all_states=true."New value: +"FIPS GEOIDs to compare. The first 300 distinct IDs are queried; remaining distinct IDs are disclosed as excluded. For all 50 states, omit and set compare_all_states=true."
    • removedInput schema / properties / geography_ids / maxItems
      Removed value: -50
    • changedInput schema / properties / sort_by / description
      Previous value: -"\"unserved_pct\" = share of population with no broadband (default). \"unserved_pop\" = raw headcount for BEAD funding. \"coverage_pct\" = share with any coverage. \"competitive_pct\" = share with 2+ providers. Every option ranks worst-first, so rank 1 is the highest unserved share or headcount, or the lowest coverage or competitive share."New value: +"\"unserved_pct\" = share of population with no broadband (default). \"unserved_pop\" = raw headcount. \"coverage_pct\" = share with any coverage. \"competitive_pct\" = share with 2+ providers. Every option ranks worst-first, so rank 1 is the highest unserved share or headcount, or the lowest coverage or competitive share."
    • changedInput schema / properties / speed_down / description
      Previous value: -"Download speed threshold in Mbps. 25 = FCC legacy standard. 100 = BEAD program standard."New value: +"Download key for a download/upload threshold pair in Mbps: 0.2=0.2/0.2, 4=4/1, 10=10/1, 25=25/3, 100=100/10, 250=250/25, 1000=1000/100. These historical population aggregates cannot establish current BEAD eligibility or address service; 100/10 does not establish 100/20 availability."
    • changedInput schema / properties / tech_filter / default
      Previous value: -"acfosw"New value: +"acfow"
    • changedInput schema / properties / tech_filter / description
      Previous value: -"Technology filter, one value: \"acfosw\" = every technology (default). \"f\" = fiber, \"c\" = cable, \"a\" = ADSL/DSL, \"o\" = other (symmetric DSL, other copper, power line), \"s\" = satellite, \"w\" = fixed wireless."New value: +"Any nonempty alphabetical combination of a=ADSL/DSL, c=cable, f=fiber, o=other (symmetric DSL, other copper, power line), s=satellite, w=fixed wireless. Default acfow excludes satellite; explicit acfosw includes every technology. acfow includes all fixed wireless and is not an exact program-technology eligibility filter."
    • changedInput schema / properties / tech_filter / enum
      Previous value: -[
      -  "acfosw",
      -  "f",
      -  "c",
      -  "a",
      -  "o",
      -  "s",
      -  "w"
      -]New value: +[
      +  "a",
      +  "ac",
      +  "acf",
      +  "acfo",
      +  "acfos",
      +  "acfosw",
      +  "acfow",
      +  "acfs",
      +  "acfsw",
      +  "acfw",
      +  "aco",
      +  "acos",
      +  "acosw",
      +  "acow",
      +  "acs",
      +  "acsw",
      +  "acw",
      +  "af",
      +  "afo",
      +  "afos",
      +  "afosw",
      +  "afow",
      +  "afs",
      +  "afsw",
      +  "afw",
      +  "ao",
      +  "aos",
      +  "aosw",
      +  "aow",
      +  "as",
      +  "asw",
      +  "aw",
      +  "c",
      +  "cf",
      +  "cfo",
      +  "cfos",
      +  "cfosw",
      +  "cfow",
      +  "cfs",
      +  "cfsw",
      +  "cfw",
      +  "co",
      +  "cos",
      +  "cosw",
      +  "cow",
      +  "cs",
      +  "csw",
      +  "cw",
      +  "f",
      +  "fo",
      +  "fos",
      +  "fosw",
      +  "fow",
      +  "fs",
      +  "fsw",
      +  "fw",
      +  "o",
      +  "os",
      +  "osw",
      +  "ow",
      +  "s",
      +  "sw",
      +  "w"
      +]
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "geographyType",
      -      "techFilter",
      -      "speedDownMbps",
      -      "sortBy",
      -      "areas",
      -      "totalAreas",
      -      "dataVintage",
      -      "appliedFilters"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "unmatchedIds",
      +      "excludedIds",
      +      "duplicateIds",
      +      "geographyType",
      +      "techFilter",
      +      "speedDownMbps",
      +      "sortBy",
      +      "areas",
      +      "totalAreas",
      +      "dataVintage",
      +      "appliedFilters"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / duplicateIds
      Added value: +{
      +  "description": "IDs repeated in the input, listed once in first repeated-occurrence order.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / excludedIds
      Added value: +{
      +  "description": "Distinct geography IDs beyond the first 300, which were not queried.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Composed disclosure naming unmatched retained IDs, excluded unqueried IDs and duplicate IDs with their counts. Absent when none applies.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / unmatchedIds
      Added value: +{
      +  "description": "Retained geography IDs without matching Area Table data.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / tech_filter / description
      Previous value: -"Technology filter. \"acfosw\" = any wired or fixed wireless. \"f\" = fiber only. \"c\" = cable only. \"a\" = DSL. \"s\" = satellite. \"w\" = fixed wireless."New value: +"Technology filter, one value: \"acfosw\" = every technology (default). \"f\" = fiber, \"c\" = cable, \"a\" = ADSL/DSL, \"o\" = other (symmetric DSL, other copper, power line), \"s\" = satellite, \"w\" = fixed wireless."
  3. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "geographyType",
      +      "techFilter",
      +      "speedDownMbps",
      +      "sortBy",
      +      "areas",
      +      "totalAreas",
      +      "dataVintage",
      +      "appliedFilters"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `no_data_found`: No area table data found for any of the requested geography IDs. `invalid_all_states_combo`: compare_all_states=true used with geography_type other than \"state\". `missing_geography_ids`: No geography_ids provided and compare_all_states is false. `invalid_geography_id_shape`: A geography_ids entry has a digit count that does not match the geography_type (state=2, county=5, cd=4, cbsa=5, place=7). Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "no_data_found",
      +            "invalid_all_states_combo",
      +            "missing_geography_ids",
      +            "invalid_geography_id_shape"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "geographyType",
      -  "techFilter",
      -  "speedDownMbps",
      -  "sortBy",
      -  "areas",
      -  "totalAreas",
      -  "dataVintage",
      -  "appliedFilters"
      -]
  4. Changed1 schema field changed
    • changedInput schema / properties / sort_by / description
      Previous value: -"\"unserved_pct\" = share of population with no broadband (default). \"unserved_pop\" = raw headcount for BEAD funding. \"coverage_pct\" = share with any coverage. \"competitive_pct\" = share with 2+ providers."New value: +"\"unserved_pct\" = share of population with no broadband (default). \"unserved_pop\" = raw headcount for BEAD funding. \"coverage_pct\" = share with any coverage. \"competitive_pct\" = share with 2+ providers. Every option ranks worst-first, so rank 1 is the highest unserved share or headcount, or the lowest coverage or competitive share."
  5. Changed1 schema field changed
    • addedOutput schema / properties / areas / items / properties / name
      Added value: +{
      +  "description": "Human-readable geography name if resolved (e.g., \"Pontotoc County, MS\").",
      +  "type": "string"
      +}
  6. Changed2 schema fields changed
    • addedOutput schema / properties / appliedFilters
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Filters and parameters applied to this comparison.",
      +  "properties": {
      +    "areasCompared": {
      +      "description": "Total number of geographies compared.",
      +      "type": "number"
      +    },
      +    "geographyType": {
      +      "description": "Geographic level compared.",
      +      "type": "string"
      +    },
      +    "sortBy": {
      +      "description": "Field used for ranking.",
      +      "type": "string"
      +    },
      +    "speedDownMbps": {
      +      "description": "Download speed threshold in Mbps.",
      +      "type": "number"
      +    },
      +    "techFilter": {
      +      "description": "Technology filter applied.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "geographyType",
      +    "techFilter",
      +    "speedDownMbps",
      +    "sortBy",
      +    "areasCompared"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "geographyType",
      -  "techFilter",
      -  "speedDownMbps",
      -  "sortBy",
      -  "areas",
      -  "totalAreas",
      -  "dataVintage"
      -]New value: +[
      +  "geographyType",
      +  "techFilter",
      +  "speedDownMbps",
      +  "sortBy",
      +  "areas",
      +  "totalAreas",
      +  "dataVintage",
      +  "appliedFilters"
      +]
  7. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare readOnly/idempotent/closed-world, but the description adds substantive behavior: truncation at the first 300 distinct IDs, disclosure of duplicates, unmatched and excluded IDs, and the June 2021 Form 477 data vintage. These are operational facts an agent cannot get from the structured fields and materially affect interpretation of results.

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

Conciseness4/5

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

Four sentences, front-loaded with the verb and output, followed by the eligibility caveat and the volume limits. Dense and mostly earning its place, though the 'cannot establish BEAD eligibility' caveat is echoed again in the speed_down and tech_filter schema descriptions, creating slight redundancy across the definition.

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

Completeness5/5

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

For a six-parameter comparison tool with an output schema and full annotation coverage, the description supplies everything left unexplained: data vintage, ranking semantics, batch cap, and the eligibility caveat. Return values are covered by the output schema, so no gap remains.

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

Parameters4/5

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

Schema description coverage is already 100%, so the baseline is 3, and the description goes beyond it by stating the 300-distinct-ID cap on geography_ids, the duplicate/unmatched disclosure, and that compare_all_states=true overrides geography_ids. It adds real meaning without restating enum values.

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?

States a specific verb ('Compares') plus resource ('broadband coverage metrics across multiple geographies of the same type') and the output shape ('ranked table sorted by unserved or underserved population'). This is clearly distinguishable from siblings like fcc_get_coverage_summary or fcc_search_availability without opening any schema.

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

Usage Guidelines4/5

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

Explicitly bounds the tool: it compares historical population coverage gaps and cannot establish current BEAD eligibility or address service, which warns the agent off misuse. It also documents the 300-ID limit and the compare_all_states escape hatch. It stops short of naming which sibling to use for single-geography summaries or current eligibility checks, so the routing guidance is implied rather than explicit.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.