How the database thinks about your records

Your office sends an export. What arrives is kept exactly as it arrived, then read against the parcels, owners, assessments, sales and buildings already on file, then against elevation, flood, wetlands and boundaries for the same ground. This page names the pieces.

It is written at the level of tables and functions, not columns. That is enough to have a real conversation about what is possible, and not enough to be a map for anyone else. The tool contract lives at /mcp.

The records

Nine families. Every answer PVAToday gives is assembled from these.

The parcel

The thing itself, and every version of it we have held.

TableWhat it holds
parcelOne row per parcel as of the latest export: its number, where it is, how big, what class, which districts it falls in, and its map geometry.
parcel_historyThe same parcel as earlier exports described it. Nothing is overwritten; a correction becomes a new row and the old one stays readable.

A parcel number is unique inside a county, not across counties. That is why every reply names its county, and why the record is being reshaped to carry a county code on every row.

Ownership

Who the roll says owns it, and who it said before.

TableWhat it holds
parcel_ownerThe owner of record for each parcel in the current export, with the deed reference that put them there.
parcel_owner_historyPrevious owners of record, as earlier exports carried them. This is what makes a chain of title readable without re-deriving it.

Owner mailing addresses live in these tables. They are part of the public record and are served as such — see Posture, below.

Value

What the roll assessed, by year.

TableWhat it holds
tax_assessmentAssessed value by parcel and tax year: land, improvements, the taxable total, property class and exemptions.
tax_assessment_historyPrior-year values as previously delivered, so a restatement is visible as a restatement rather than a silent edit.
tax_districtThe districts a parcel can belong to, and what they are called.

Transfers

Sales, with the honesty about which ones mean anything.

TableWhat it holds
saleRecorded transfers: date, price, deed book and page, and the validity code that says whether it was arms-length.

Most rows in a sales table are not market sales — quitclaims between family, corrections, $1 transfers. Any question about market value has to filter on the validity code first. The valuation and ratio-study tools always do; the sales list does when asked for arms-length sales only.

Improvements

What is built on the land.

TableWhat it holds
buildingStructures by parcel: type, year built, size, condition, grade and value. A parcel may have many.

The delivery record

Every export your office sent, and what changed between them.

TableWhat it holds
pva_dropOne row per export received: its date, the roll it belongs to, and the stages it passed through.
pva_unitThe individual files inside an export, each with the hash it arrived under.
pva_changeWhat moved between one export and the next, per parcel and per field: transfers, value changes, new buildings, retirements.

This is the part most record systems do not keep. It is what lets an answer say which export it came from, and what a question like "what changed since February" is answered out of.

As delivered, untouched

Your files, kept verbatim.

TableWhat it holds
pva_raw.rowsEvery delivered row, exactly as it arrived, with the file and line it came from.
pva_raw.shapeThe delivered map geometry, likewise unmodified.

Nothing is loaded over the top of these. Any processed value can be traced back to the literal line of the literal file your office sent, which is the only way to settle a disagreement about what was delivered.

Normalised

The same records, made comparable.

TableWhat it holds
pva_canon.parcelParcel rows with names, codes and formats regularised.
pva_canon.assessmentAssessment rows, likewise.
pva_canon.saleSale rows, likewise.
pva_canon.buildingBuilding rows, likewise.
pva_canon.mapMap rows, likewise.

Every county's export arrives in its own dialect. This layer is where a dialect becomes the shared vocabulary, without editing what arrived.

Who is who

Resolving the same owner across spellings. The main tables; the family has supporting ones too.

TableWhat it holds
entity.owner_name_personOwner names resolved to the individual people in them.
entity.owner_name_parsedOwner names broken into parts, so "SMITH JOHN A & MARY" is legible as people.
entity.owner_entityA canonical identity that several spellings can point at.
entity.entity_candidate_pairTwo names that might be the same owner, with a score, awaiting judgement.
entity.entity_relationshipHow resolved identities relate to one another.

This is the machinery behind "how much does this LLC own here" when the roll spells the name four ways. It is built and scoped to work across counties; it has not been run in anger yet.

What your records are read against

Around fifty reference layers for the region, refreshed on a schedule and held alongside the roll. A parcel answer can carry its flood zone, its terrain and its school district because these sit in the same place as the parcel.

Elevation and terrain

Two-foot LiDAR contours for the county, and derived slope and surface.

Aerial and oblique imagery

Three-inch orthoimagery, plus oblique frames with their flight geometry.

Flood

FEMA flood hazard layers.

Wetlands and water

National Wetlands Inventory, NHD hydrography, and watershed boundaries.

Weather history

Recorded tornado, hail and wind events.

Boundaries and districts

Census TIGER county, road and school district boundaries.

Public land and recreation

Protected areas, forest service roads, trails and designated areas.

Land cover

Cropland and land use.

Named places

Parks, schools, hospitals, churches, businesses and landmarks, with where they are. The list behind pva.today/mccracken/places.

The function inventory

26 functions live in the database (three of them in two versions). They are the questions it already knows how to answer, whether or not anything asks them yet.

11 of them are not called by anything. They were written, they work, and no product surface reaches them. If you are here to decide what to build next, that list is the shortest path from idea to working feature — the query already exists. One caution: some of them return owner mailing addresses, so none can be exposed until it goes through the same rule as everything else (see Posture, below).

Reachable through the MCP today

In use

Called by the tools any AI can use.

FunctionWhat it answers
latest_ownerThe owner of record for a parcel as of a given export.
latest_assessmentThe assessment in force for a parcel as of a given export.
neighbor_analysisWhat sits around a parcel, and how it compares.
classify_owner_typeWhether an owner name reads as a person, a company, a government body or a trust.
pva_canon_textRegularises a delivered text value so it can be compared. The loader uses it too.

Called by the county site

In use

The parcel pages and map at the county's own address. It also uses the four owner, assessment and neighbour functions above.

FunctionWhat it answers
parcel_detailEverything about one parcel, assembled in a single call.
parcel_at_pointThe parcel containing a point. Click the map, get the parcel.
parcels_in_bboxEvery parcel inside a rectangle. A map viewport, essentially.
search_parcels_textFree-text search across parcels.
search_by_owner_wordsFind owners by the words in a name, not an exact string.
get_portfolioEverything one owner holds. The county site's owner view; the public MCP answers portfolio questions its own way.
delinquent_summaryDelinquency rolled up by district and duration.

Built, not yet wired to anything

Idle

Working code in the database that neither the MCP, the county site nor the loader calls. This is the interesting list.

FunctionWhat it answers
search_parcels_nearbyParcels near a point, filtered by a term, paged.
search_owners_nearbyOwners near a point, likewise.
search_assessments_nearbyAssessments near a point, likewise.
search_parcels_with_owners_nearbyBoth at once, with an owner filter.
find_nearby_transfersRecent transfers around a point, ranked by how recent the deed book is. Not filtered to arms-length sales.
nearby_parcel_countHow many parcels within a radius.
nearby_owner_countHow many owner rows within a radius. Not distinct owners: the count is of rows, and a parcel carries one per tax year.
nearby_local_owner_countHow many of those rows carry a local (420xx) mailing ZIP.
nearby_ex420_owner_countThe complement: rows whose mailing ZIP is outside 420xx, or absent.
nearby_assessment_countHow many assessments within a radius.
nearby_total_assessedTotal assessed value within a radius.

Housekeeping

Internal

Internal helpers, listed for completeness.

FunctionWhat it answers
refresh_all_matviewsRebuilds the precomputed summaries. The loader runs it after each export is published.
_geo_pointTurns a latitude and longitude into a point.
_miles_to_metersExactly that.

Posture

What this page leaves out

Columns, types, keys, constraints and indexes. Naming a table is useful for talking about what is possible; publishing its exact shape is an attack surface and a promise about stability we are not making here.

Owner mailing addresses

They are in the record, because the roll carries them, and they are public record — the same information a county PVA publishes at the counter. What is not open to everyone is rolling one address up into every parcel behind it: serving a record and handing over a list are different acts, and the second needs a credential.

Nothing is overwritten

A correction adds a row; it does not replace one. Every answer can name the export it came from, and the delivered file and line behind it, which is what makes a disagreement about the record settleable.

One county is one county

A parcel number is unique inside a county and not across them. Every reply names its county, and the record is being reshaped so that a county code sits on every row rather than being implied by which database you opened.

Want the tools rather than the tables? The MCP contract lists every one, with arguments and replies. Want to ask the record a question in English? chat.pva.today.