Offendersearch
Server Details
Search US sex-offender registries and criminal records, with per-source citations.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- Clavaa/offendersearch-quickstart
- GitHub Stars
- 0
TDQS
Scored across 5 tools
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.
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.
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.
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.
Available Tools
5 toolsbatch_searchAInspect
Run many person/location lookups in one call (row-in / row-out).
Each row goes through the SAME engine as search_offenders, so a row's records
are identical to what a single search would return. A row that fails is
reported with status='error' in place and never aborts the batch. Max 1000 rows.
Returns: { count, results: [ { index, status, counts{records,sourcesQueried,
sourcesIncomplete}, warnings: [str], records: [Record], error? } ] } in input
order. ★ A row with `counts.sourcesIncomplete > 0` could not be searched to the
end — its `records` are a LOWER BOUND, not a clean 'no match'.
Auth: uses the caller's X-API-Key (request header or OFFENDERSEARCH_API_KEY env).
| Name | Required | Description | Default |
|---|---|---|---|
| match | No | Fuzzy tolerance applied to every row (see search_offenders). | balanced |
| queries | Yes | List of query objects (max 1000). Each may set any of: firstName, lastName, dob (YYYY-MM-DD), age, city, state, zipcode, address, lat, lng, radiusMiles, q. One row in = one result out, in input order. | |
| extensive | No | Request extensive detail (offenses[], stateData, images) for every row. | |
| freshness | No | Cache/pricing tier applied to every row: daily=<=24h (default), weekly=<=7d. | daily |
| jurisdictions | No | Registry codes applied to EVERY row (e.g. ['FL','TX']). Omit = all 58 registries. | |
| location_scoped | No | Apply per-state scoping to every row (see search_offenders). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: row-by-row engine equivalence, error handling (status='error', never aborts batch), max rows, return format, and the crucial caveat about sourcesIncomplete meaning 'lower bound'. It also documents authentication via X-API-Key or env var. This is rich, transparent context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is densely informative without fluff. The first sentence captures the core function, then proceeds logically: behavior, return format, caveat, auth. The use of bullets and the star-marked warning keep critical caveats prominent. Every sentence earns its place despite length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter tool with no output schema, the description covers all essential aspects: the input query format, return structure with counts and errors, error semantics, the lower-bound warning, authentication, and a pointer to search_offenders for shared parameter meanings. An agent can invoke it correctly and interpret results accurately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds significant semantic value: explains 'queries' as row-in/row-out with input order, enumerates allowed fields, and outlines result structure. It also interprets match/freshness/jurisdictions by referencing search_offenders for context. This goes well beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with 'Run many person/lookup lookups in one call (row-in / row-out)', clearly stating the tool's verb, resource, and batching behavior. It explicitly distinguishes from siblings by noting 'same engine as search_offenders', making its niche unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for multiple lookups ('many... in one call') and references search_offenders as the single-query alternative, but does not explicitly say 'use this instead of search_offenders when you have multiple queries'. It provides constraints (max 1000 rows) but not a direct usage contrast.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_criminal_coverageAInspect
List the criminal-record jurisdictions searched, with kind and status.
Use it to discover which states and counties are reachable and which are
answering today, before relying on an empty result. Depth is uneven by design:
counties publish independently, so a state with many county jurisdictions is
not "better covered" than one that publishes a single statewide source — it is
differently structured.
Returns the jurisdiction roster; each entry carries its code, the state it
belongs to, the kind of records it holds (jail / prison / court / warrant /
registry) and whether it is currently answering.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden, and it does so well: it reveals that the data is dynamic ('currently answering'), that coverage depth varies, and that a state with many county jurisdictions is not necessarily better covered. It stops short of mentioning refresh behavior or operational constraints like rate limits, but for a zero-parameter listing tool the key traits are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short paragraphs, each earning its place: one states the core action, one gives usage context and an interpretive caveat, and one clarifies the return contents. It is front-loaded and avoids filler or restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with no output schema, the description is nearly complete: it explains what is returned, how to use the result, and how to interpret an important data-quality nuance. It does not explicitly contrast with the similar-sounding get_registry_coverage sibling, which would have made the tool boundary fully unambiguous.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is little to add beyond the baseline. The description still enriches the output semantics by explaining what each jurisdiction entry will contain—code, state, kind, and status—giving an agent a mental model even without schema-provided parameter docs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'List the criminal-record jurisdictions searched, with kind and status.' It clearly distinguishes the tool's coverage-mapping purpose from the sibling search tools, which focus on queries rather than jurisdiction availability.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance to use this tool 'before relying on an empty result,' which tells an agent when the tool matters. It also explains how to interpret uneven coverage, but it does not explicitly name alternatives or state when not to use this tool versus get_registry_coverage or the search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_registry_coverageAInspect
List every registry we cover plus its scope, legal status, and health.
Public coverage catalog (no API key required). Use it to discover the
`jurisdictions` codes accepted by search_offenders / batch_search and to
check per-registry freshness/health before relying on a result.
Returns: { count, registries: [ SourceInfo ] } where each SourceInfo is:
- id: registry code (e.g. 'IL', 'TX', 'PR')
- name: human-readable registry name
- covers: [state codes] a registry covers ('*' = national / all)
- scope: 'state' | 'national'
- status: 'live' | 'building'
- legal: { commercialUse: 'allowed'|'restricted'|'prohibited'|'unknown' }
- health: { lastSuccessAt, typicalLatencyMs, ageSeconds, freshFor }
`health` is OPERATIONAL COVERAGE METADATA about our ingest schedule, published
for transparency. It is NOT a quality warning about a search result: a search
serves every registry's best available data regardless of `freshFor`, so a
registry listing only 'weekly' still contributes its records to a
freshness='daily' search. Do NOT tell a user their search results are stale,
unreliable or out of date on the basis of these fields — they are not. The only
completeness signal that belongs in an answer is `counts.sourcesIncomplete` /
`warnings[]` from the search response itself.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It thoroughly explains the return shape, the meaning of each SourceInfo field, and the crucial semantic distinction that health fields are operational metadata, not search-quality indicators. It also states that no API key is required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average, but every section earns its place: a one-sentence purpose, a structured return field listing, and a critical behavioral warning that prevents misinterpretation. The most important caveat about health fields is clearly separated and emphasized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter tool with no output schema, the description is exceptionally complete. It covers the purpose, use cases, return contract, field enums, and operational semantics, including exactly what the health fields should and should not be used for. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters and 100% schema coverage, so there is no parameter semantics burden for the description. The description adds no parameter-level meaning, but none is needed. Baseline 4 for a no-parameter tool is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List every registry we cover plus its scope, legal status, and health.' This clearly identifies what the tool does. However, it does not explicitly distinguish itself from the sibling tool get_criminal_coverage, relying on name similarity rather than an explicit differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: discover jurisdiction codes accepted by search_offenders/batch_search and check per-registry freshness/health. It also gives a strong 'do not' instruction against interpreting health fields as search-quality warnings, which is essential for correct use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_criminalAInspect
Search US criminal records — county jail bookings, state prison custody, court cases and warrants.
Covers county jail rosters, statewide prison systems, court sources, warrant
systems and statewide registries across the states, DC and the territories,
plus the federal layer — which is a separate system holding offences no state
search will surface.
A surname is REQUIRED. Supply firstName and a DOB or birth year wherever you
have them: a bare common surname returns thousands of people, and the scoring
cannot tell you which one is yours.
Each record carries `recordType`, and YOU MUST READ IT BEFORE CHARACTERISING
ANYONE:
- a jail booking is an ARREST-stage record — charges at booking are
frequently reduced, dismissed, or never filed. It is NOT a conviction.
- prison custody implies a sentence, and therefore a conviction.
- a court record carries the DISPOSITION — the authoritative statement of
how a case actually ended.
- a warrant means the person is SOUGHT. Nothing has been tested.
Never describe someone as convicted on the strength of a booking record.
Records also carry: name, aliases, dob/birthYear/dobPrecision, sex, race,
state, county, custody status and facility, sentence and parole detail,
`cases`, `sources` (per-source citation), and `matchConfidence`/`matchBasis`
explaining why it matched. `counts.records` is the total found and
`counts.recordsReturned` the number in this page.
Not a consumer report: results must not be used for FCRA-covered decisions
(employment, tenancy, credit) without appropriate process.
| Name | Required | Description | Default |
|---|---|---|---|
| age | No | Approximate current age, when neither DOB nor birth year is known. | |
| dob | No | Date of birth, YYYY-MM-DD. The single strongest disambiguator. | |
| limit | No | Max records to return. Default 50. | |
| state | No | 2-letter state code (e.g. 'TX'). Narrows to that state's jurisdictions. | |
| county | No | County name, to narrow within a state. | |
| lastName | Yes | REQUIRED surname. The criminal corpus refuses an unbounded query — a name is the field that cannot be enumerated. | |
| birthYear | No | Birth year alone, when a full DOB is unknown. | |
| firstName | No | Given name. Strongly recommended: a bare common surname returns thousands. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description assumes the full disclosure burden and does it well: it defines what each recordType implies, warns that bookings are not convictions, that warrants mean 'SOUGHT', and attaches FCRA restrictions. It even instructs the agent to read recordType before characterizing anyone. This is far beyond the minimum.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded with the core purpose and organized into readable paragraphs; the surname/recordType/FCRA guidance is all substantive. A few phrases, like the federal-layer explanation, are useful context rather than waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, it documents the returned record fields (name, aliases, dob, sex, race, state, county, custody, sentence, cases, sources, matchConfidence/matchBasis) and the pagination counts. It covers search behavior, caveats, and legal constraints, leaving the agent enough to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema already describes all 8 parameters, so baseline is 3; the description adds real value by explaining that surname is non-optional, that firstName + DOB or birthYear strengthen matching, and that a common surname yields thousands of results. It also calls DOB 'the single strongest disambiguator,' which is not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a clear verb and resource: "Search US criminal records" and enumerates county jail bookings, prison custody, court cases, and warrants. Scope is unambiguous, but it never explicitly distinguishes itself from the sibling search_offenders or tells the agent which searches are excluded, so sibling differentiation is absent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit invocation guidance — 'A surname is REQUIRED' and advises supplying firstName plus DOB/birth year 'wherever you have them' — and explains why (bare common surnames return thousands). It doesn't state when to prefer a sibling tool like search_offenders, so no exclusions/alternatives are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_offendersAInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Free-text search across name/alias/address/city/state/zip (all tokens must appear). | |
| age | No | Age filter, used when DOB is unknown. Matched +/-1 year for birthday drift. | |
| dob | No | Date of birth 'YYYY-MM-DD'. Improves match precision; drives dobVerification (dob_match / year_match). | |
| lat | No | Latitude for a GIS radius search (pair with lng). | |
| lng | No | Longitude for a GIS radius search (pair with lat). | |
| city | No | Residence city filter. | |
| match | No | Fuzzy tolerance: strict=exact; balanced=nicknames/variants/initials/typos on first name, exact last; broad=also prefix/typo on last name. | balanced |
| state | No | 2-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. | |
| address | No | Fuzzy street-address filter (every token must appear in some record address). | |
| zipcode | No | Residence ZIP (first 5 digits used). | |
| extensive | No | If true, request extensive detail (retains offenses[], stateData, images). A light call drops them. | |
| freshness | No | Cache/pricing tier: daily=<=24h (default), weekly=<=7d. | daily |
| last_name | No | Surname — the primary match key, e.g. 'Smith'. | |
| first_name | No | Given name, e.g. 'John'. | |
| deadline_ms | No | Max time to wait, in ms (default 120000 / 2 min). Lower for a faster bounded response; partial results return status='partial'. | |
| radius_miles | No | GIS radius in miles around lat/lng. Defaults to 1 when a point is given; capped at 100. | |
| jurisdictions | No | Registry codes to query (e.g. ['IL','TX']). Omit/null = ALL 58 registries. See get_registry_coverage for codes. | |
| location_scoped | No | OPT-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
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.
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.
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.
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.
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.
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.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
- First observed
batch_search - First observed
get_criminal_coverage - First observed
get_registry_coverage - First observed
search_criminal - First observed
search_offenders
Related MCP Connectors
US public-records lookups: people search, reverse phone, property and criminal records.
Research a person's public footprint from a name, phone, email, or username. Sourced.
Is this person indexed on that data-broker domain? A three-state verdict, with the evidence.
US crime scores, incidents, neighborhood demographics, rent data, and offender search by address.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables searching all US sex-offender registries from any MCP client, returning scored, de-duplicated records with provenance and per-registry status.-
- AlicenseNot gradedqualityDmaintenanceScreens individuals and entities against the OIG LEIE exclusion list, returning candidate matches that require human verification.MIT
- AlicenseNot gradedqualityCmaintenanceEnables querying US federal criminal docket metadata, such as party names, courts, docket numbers, and filing dates, through search and recent-case tools.MIT
- AlicenseNot gradedqualityCmaintenanceChecks names against US FinCEN financial crime lists for compliance and AML due diligence, with a single read-only tool.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.