Skip to main content
Glama

search_offenders

Search US sex-offender registries for one person and/or location.

Fans out across all 58 registries (or the ones named in `jurisdictions`),
de-duplicates people across registries, scores each match, and returns the
normalized records. Supply whatever identifiers you have — all args are
optional but at least a name, location, or free-text `q` should be given.

Returns a SearchResponse object (docs/openapi.yaml / FIELD-DICTIONARY.md):
  - status: 'complete' | 'partial'  (partial = a source errored, or a source
    could not be searched to completion)
  - counts: { records, sourcesQueried, sourcesIncomplete }
  - warnings: [str] — ALWAYS present, `[]` when the search ran clean
  - sourceStatus: [ { source, status, matched, fromCache, note,
    incomplete, incompleteReason } ]  per-registry outcome

★ READ `counts.sourcesIncomplete` BEFORE REPORTING A RESULT. Above 0, `records`
is a LOWER BOUND: those registries could not be searched to the end, and an
empty or short result is NOT evidence that a person is unregistered. Say so.
`warnings[0]` states it in plain language; relay it rather than summarising it
away.
  - records: [ Record ], each with:
      recordId, matchConfidence, matchBasis[],
      name {first, middle, last, suffix, full}, aliases[], nicknames[],
      dob, dobPrecision, age, sex, race, ethnicity, height, weight,
      eyeColor, hairColor, marks, addresses[{type,line1,city,county,state,zipcode,lat,lng}],
      offense {crime,statute,riskLevel,tier,convictionDate,...}, flags{absconder,predator},
      source {jurisdiction,registryName,recordUrl,scrapedAt,sourceUpdatedAt}, sources[],
      dobVerification, unverified
      (offenses[], stateData, images[] are populated only when extensive=true)

Auth: uses the caller's X-API-Key (request header or OFFENDERSEARCH_API_KEY env).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qNoFree-text search across name/alias/address/city/state/zip (all tokens must appear).
ageNoAge filter, used when DOB is unknown. Matched +/-1 year for birthday drift.
dobNoDate of birth 'YYYY-MM-DD'. Improves match precision; drives dobVerification (dob_match / year_match).
latNoLatitude for a GIS radius search (pair with lng).
lngNoLongitude for a GIS radius search (pair with lat).
cityNoResidence city filter.
matchNoFuzzy tolerance: strict=exact; balanced=nicknames/variants/initials/typos on first name, exact last; broad=also prefix/typo on last name.balanced
stateNo2-letter state/territory code (e.g. 'IL', 'PR'), or the full name. A residence FILTER — it does NOT change which registries run; all 58 are still searched. It filters as a UNION: a record is kept when it has an address in that state OR that state's registry is the one holding it. Each record carries `registrationState` and `addressStates` so you can tell which half matched; for the registration half alone, pass `jurisdictions` instead.
addressNoFuzzy street-address filter (every token must appear in some record address).
zipcodeNoResidence ZIP (first 5 digits used).
extensiveNoIf true, request extensive detail (retains offenses[], stateData, images). A light call drops them.
freshnessNoCache/pricing tier: daily=<=24h (default), weekly=<=7d.daily
last_nameNoSurname — the primary match key, e.g. 'Smith'.
first_nameNoGiven name, e.g. 'John'.
deadline_msNoMax time to wait, in ms (default 120000 / 2 min). Lower for a faster bounded response; partial results return status='partial'.
radius_milesNoGIS radius in miles around lat/lng. Defaults to 1 when a point is given; capped at 100.
jurisdictionsNoRegistry codes to query (e.g. ['IL','TX']). Omit/null = ALL 58 registries. See get_registry_coverage for codes.
location_scopedNoOPT-IN ONLY, and never inferred from `state`. If true AND a state is set, run only the registries covering that state instead of all 58. It is a cost knob that COSTS RECALL: anyone registered by another state's registry while residing in the requested state is excluded (7.0% of records). The response reports counts.sourcesSkippedByScope and a NARROWED SEARCH warning when it applies. Leave it false unless the caller explicitly wants the cheaper, narrower search.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure and meets it thoroughly. It reveals that results may be partial, that counts.sourcesIncomplete makes records a lower bound, that warnings are always present, and that registries can fail without invalidating the search. It also exposes the auth mechanism and the difference between light and extensive calls.

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 long but well-organized: a one-line summary, then fan-out behavior, a clear warning section, a structured return-field list, and an auth note. Critical operational guidance (read sourcesIncomplete before reporting) is highlighted early and in plain language. Every section earns its place given the 18-parameter surface and absence of an output schema.

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 complex 18-parameter read tool with no output schema, the description is remarkably complete. It documents the response structure, per-source status fields, cache tiers, geo-search behavior, jurisdiction control, and the crucial lower-bound caveat. An agent has enough context to call it correctly and interpret its results without additional documentation.

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

Parameters5/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds substantial meaning beyond field names and types. It clarifies subtle behaviors such as `state` being a residence filter that does not change which registries run, `location_scoped` being an opt-in recall-reducing knob, `match` levels affecting fuzzy tolerance, and `deadline_ms` causing partial results. This materially improves an agent's ability to choose correct parameter combinations.

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 opens with a specific verb and resource: 'Search US sex-offender registries for one person and/or location.' It goes beyond a vague summary by explaining the fan-out, de-duplication, scoring, and normalized record output. The resource is clearly distinct from siblings like search_criminal at a glance.

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?

The description gives clear guidance on when to call the tool: when searching sex-offender registries, and it explains what identifiers to supply ('at least a name, location, or free-text q should be given'). It also references get_registry_coverage for registry codes, pointing the agent to the right companion tool. It does not explicitly contrast with search_criminal or batch_search, but the resource scope makes the primary context clear.

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.

TDQS

A4.5/5.0
Disambiguation5/5

Each tool maps to a distinct function: single vs batch registry search, criminal-record search, and coverage metadata for criminal versus registry sources. Despite 'offenders' and 'criminal' both being person-search domains, the descriptions make the boundary clear, and batch_search explicitly references search_offenders as its single-row equivalent.

Naming Consistency4/5

search_criminal/search_offenders and get_criminal_coverage/get_registry_coverage follow a consistent get_/search_ plus domain pattern. batch_search is the only mild deviation because it does not name the domain, but it remains readable and snake_case-consistent.

Tool Count5/5

Five tools is well-scoped for a records-search API: two search modes, a batch variant, and two coverage catalogs. No tool feels redundant or missing for the apparent purpose.

Completeness4/5

The surface covers single and batch registry search, criminal-record search, and coverage/health metadata for both domains. A batch criminal-search option would be a natural addition, but the current set has no dead ends for its read-only search scope.