About Offendersearch
Offendersearch is a REST API for checking US sex-offender registries and criminal records. It searches 58 state, district, and territory registries and returns confidence-scored matches with source citations.
Key features
- 01Search across 58 registries at once
- 02Screen by name, birth date, or age
- 03Search by ZIP code and radius
- 04Batch-screen records
- 05Return citations and official links
Use cases
- 01Check whether a person appears in public registry records
- 02Find registry records near a location
- 03Screen an entire roster in one request
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://mcp.offendersearch.app/mcpclaude mcp add --transport http app-offendersearch-offendersearch https://mcp.offendersearch.app/mcp{"mcpServers":{"app-offendersearch-offendersearch":{"type":"http","url":"https://mcp.offendersearch.app/mcp"}}}Open in Cursor{"servers":{"app-offendersearch-offendersearch":{"type":"http","url":"https://mcp.offendersearch.app/mcp"}}}Open in VS Code{"mcpServers":{"app-offendersearch-offendersearch":{"type":"http","url":"https://mcp.offendersearch.app/mcp"}}}{"mcpServers":{"app-offendersearch-offendersearch":{"serverUrl":"https://mcp.offendersearch.app/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
5| Parameter | Type | Required | Description |
|---|---|---|---|
| q | any | No | Free-text search across name/alias/address/city/state/zip (all tokens must appear). |
| age | any | No | Age filter, used when DOB is unknown. Matched +/-1 year for birthday drift. |
| dob | any | No | Date of birth 'YYYY-MM-DD'. Improves match precision; drives dobVerification (dob_match / year_match). |
| lat | any | No | Latitude for a GIS radius search (pair with lng). |
| lng | any | No | Longitude for a GIS radius search (pair with lat). |
| city | any | No | Residence city filter. |
| match | enum | No | Fuzzy tolerance: strict=exact; balanced=nicknames/variants/initials/typos on first name, exact last; broad=also prefix/typo on last name.strict | balanced | broad |
| state | any | 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 | any | No | Fuzzy street-address filter (every token must appear in some record address). |
| zipcode | any | No | Residence ZIP (first 5 digits used). |
| extensive | boolean | No | If true, request extensive detail (retains offenses[], stateData, images). A light call drops them. |
| freshness | enum | No | Cache/pricing tier: daily=<=24h (default), weekly=<=7d.daily | weekly |
| last_name | any | No | Surname — the primary match key, e.g. 'Smith'. |
| first_name | any | No | Given name, e.g. 'John'. |
| deadline_ms | integer | No | Max time to wait, in ms (default 120000 / 2 min). Lower for a faster bounded response; partial results return status='partial'. |
| radius_miles | any | No | GIS radius in miles around lat/lng. Defaults to 1 when a point is given; capped at 100. |
| jurisdictions | any | No | Registry codes to query (e.g. ['IL','TX']). Omit/null = ALL 58 registries. See get_registry_coverage for codes. |
| location_scoped | boolean | 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. |
Details
From the project READMEOffendersearch — API Quickstart
Screen anyone against all 58 US sex-offender registries — every state, DC and the territories — with a single REST call.
- 🌐 Website: https://offendersearch.app
- 📖 Docs: https://offendersearch.app/docs
- 🧾 OpenAPI spec: https://offendersearch.app/openapi.json
- 🔗 Base URL:
https://api.offendersearch.app
Get a key at offendersearch.app — the free trial is 25 searches with no card. Then set it:
export OFFENDERSEARCH_KEY="sk_your_key"
One call, 58 registries
curl https://api.offendersearch.app/v1/search \
-H "Authorization: Bearer $OFFENDERSEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{ "query": { "firstName": "John", "lastName": "Smith", "dob": "1982-04-11" } }'
Every match is scored for confidence and cited to its source, with a photograph and a link to the official registry record. A date of birth or age sharpens the match.
Search an area (no name)
curl https://api.offendersearch.app/v1/search \
-H "Authorization: Bearer $OFFENDERSEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{ "query": { "zipcode": "92501", "radiusMiles": 2 } }'
Screen a whole roster
POST /v1/batch checks many records in one call — see the docs.
Examples in this repo
| Language | File |
|---|---|
Node.js (zero-dep, fetch) | node/search.mjs |
Python (requests) | python/search.py |
| curl | curl/search.sh |
Generate a typed client in any language from the OpenAPI spec.
Responsible use
Results are public-record data and not a consumer report. Don't use them for employment, tenancy, or other FCRA-covered decisions without the process the law requires — and never to identify, target, or harass anyone. For awareness and safety.
License
MIT
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.