# Connect the MCP server

> One address and your key. Every tool, what it does and what it takes.

The MCP server lets the AI model your company uses read Hey Town Hall Data directly. Your AI client connects to one address with your API key and calls the server's tools. Every tool is read-only.

## Connect

- **Address:** `https://data.heytownhall.com/mcp`
- **Header:** `Authorization: Bearer <your key>`
- **Transport:** Streamable HTTP

Most AI clients that take a remote MCP server accept a settings block like this one. Put in your own key:

```json
{
  "mcpServers": {
    "hey-town-hall-data": {
      "url": "https://data.heytownhall.com/mcp",
      "headers": { "Authorization": "Bearer htd_test_..." }
    }
  }
}
```

If your client asks for these in another form, give it the same two things: the address and the header.

Start with a sandbox key (`htd_test_`). Your client then reads the [sandbox](https://data.heytownhall.com/docs/sandbox)'s fictional towns, free. Swap in a live key when you are ready.

## Check the connection

You can check your key and the address without a client. This sends the first message a client sends:

```bash
curl https://data.heytownhall.com/mcp \
  -H "Authorization: Bearer $HTD_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'
```

The answer names the server `hey-town-hall-data`. With no key, or a key that is not valid, the server answers `401` before any handshake. A live key with no payment method answers `402`.

## What the server does

- **Protocol.** It serves the 2026-07-28 revision of the MCP specification. Clients still on the 2025-11-25 revision work too.
- **Billing.** The handshake and the tool list are free. Each tool call is one API request on its tool's meter, billed like any other request. A call that fails is not billed.
- **Rate limits.** Tool calls count against your key's [rate limit](https://data.heytownhall.com/docs/rate-limits), the same as REST requests.
- **Page size.** A tool returns 10 records unless you ask for more, and at most 50. Long text is cut at 2,000 characters. Each result carries `next_cursor` to read the next page.
- **Sources.** Every record keeps its `source_url` and `read_at`, so an answer your AI client writes can cite what it read. The server tells the client to cite them, and that a missing value is unknown, never a no.
- **Errors.** A tool that fails returns a result marked as an error, with the API's [error envelope](https://data.heytownhall.com/docs/errors) as its text.

The server tells your client to start with `find_jurisdictions` or `search_records`.

## The tools

Each tool is answered by one `/v1` endpoint, through the same gate as a REST request.

### `search_records`: Search the records

Full-text search across agenda items, motions, meeting transcripts, document and bylaw titles, and government posts, newest first. Use it to find where a subject has come up. Without a jurisdiction it searches transcripts, bylaws and posts; agenda items, motions and documents need a jurisdiction for now. Each hit names its family, id, jurisdiction, date, a snippet, source_url and read_at.

Answered by [`GET /v1/search`](https://data.heytownhall.com/docs/reference/search/get-v1-search), billed as one search request.

- `q` (required): Words to find. Quotes keep a phrase; a leading minus leaves a word out.
- `in`: Limit to these kinds of record.
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `find_jurisdictions`: Find jurisdictions

Find public bodies (municipalities, regional districts, counties, school districts, First Nations, special districts) by name, region, kind or parent. Gives the jurisdiction ids the other tools filter by.

Answered by [`GET /v1/jurisdictions`](https://data.heytownhall.com/docs/reference/jurisdictions/get-v1-jurisdictions), billed as one records request.

- `name`: Words in the name.
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: municipality, regional_district, school_district, first_nation, …
- `parent`: A parent jurisdiction id.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `jurisdictions_at_point`: Who governs a point

Every jurisdiction whose boundary covers a latitude and longitude: the municipality, the regional district or county, the school district and so on.

Answered by [`GET /v1/jurisdictions/at`](https://data.heytownhall.com/docs/reference/jurisdictions/get-v1-jurisdictions-at), billed as one records request.

- `lat` (required): Latitude, -90 to 90.
- `lng` (required): Longitude, -180 to 180.

### `list_meetings`: List meetings

Council, board and committee meetings, newest first, with their date, kind, the vendor they were read from, and when the agenda first appeared.

Answered by [`GET /v1/meetings`](https://data.heytownhall.com/docs/reference/meetings/get-v1-meetings), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: council, committee_of_the_whole, public_hearing, board, committee, other.
- `topic`: A business topic id, such as "short_term_rentals", "data_centres", "solar_and_storage", "telecom_siting", "zoning", "procurement".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `get_meeting`: Get a meeting

One meeting with its agenda items, documents, recordings and motions.

Answered by [`GET /v1/meetings/{id}`](https://data.heytownhall.com/docs/reference/meetings/get-v1-meetings-id), billed as one records request.

- `meeting_id` (required): A meeting id from list_meetings.

### `get_transcript`: Get a meeting's transcript

A meeting's recording transcript, in order, a page at a time, without speaker labels. An empty page means no transcript is held yet.

Answered by [`GET /v1/meetings/{id}/transcript`](https://data.heytownhall.com/docs/reference/meetings/get-v1-meetings-id-transcript), billed as one transcripts request.

- `meeting_id` (required): A meeting id from list_meetings.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_agenda_items`: List agenda items

Agenda items, newest meeting first, with the recommendation, a plain-words summary where one passed its check, and business topics.

Answered by [`GET /v1/agenda-items`](https://data.heytownhall.com/docs/reference/meetings/get-v1-agenda-items), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `topic`: A business topic id, such as "short_term_rentals", "data_centres", "solar_and_storage", "telecom_siting", "zoning", "procurement".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `meeting_id`: A meeting id from list_meetings.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_motions_and_votes`: List motions and votes

Motions as the minutes print them, with mover, seconder, outcome and vote counts. Give motion_id to get one motion with each member's recorded vote.

Answered by [`GET /v1/motions`](https://data.heytownhall.com/docs/reference/decisions/get-v1-motions), billed as one records request.

- `motion_id`: One motion, with its recorded votes.
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: A key decision's kind, such as bylaw_reading.
- `topic`: A business topic id, such as "short_term_rentals", "data_centres", "solar_and_storage", "telecom_siting", "zoning", "procurement".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `meeting_id`: A meeting id from list_meetings.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_attendance`: List attendance

Who the minutes say was present or absent at meetings.

Answered by [`GET /v1/attendance`](https://data.heytownhall.com/docs/reference/decisions/get-v1-attendance), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `meeting_id`: A meeting id from list_meetings.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_documents`: List documents

Documents a government publishes: staff reports, budgets, plans, bylaws, notices, with their link and whether their text is held. Give meeting_id for a meeting's agenda package, minutes and attachments instead.

Answered by [`GET /v1/documents`](https://data.heytownhall.com/docs/reference/documents/get-v1-documents), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: staff_report, budget, plan, bylaw, agenda, minutes, notice, map, form, other.
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `meeting_id`: A meeting id from list_meetings.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_bylaws`: List bylaws

Bylaws by number, title, kind, adoption date and core subject (subject "fees_charges" is a fees and charges bylaw), with their source.

Answered by [`GET /v1/bylaws`](https://data.heytownhall.com/docs/reference/documents/get-v1-bylaws), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: bylaw, amendment, consolidated, repeal.
- `subject`: zoning, building, animal_control, fire_burning, noise, trees, business_licence, fees_charges or other.
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_defined_terms`: List defined terms

The terms a government's bylaws define (for example 'accessory building'), each with the start of its definition as printed. Use it to learn a place's own word for a thing before searching.

Answered by [`GET /v1/defined-terms`](https://data.heytownhall.com/docs/reference/documents/get-v1-defined-terms), billed as one records request.

- `term`: Words in the term.
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_fees`: List published fees

Each fee row a permit's fee page prints, the label and amount as printed (never parsed). A body's whole fees and charges schedule is a bylaw: list_bylaws with subject fees_charges.

Answered by [`GET /v1/fees`](https://data.heytownhall.com/docs/reference/land-use/get-v1-fees), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: The permit kind, such as building or business_licence.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_budgets`: List budgets and financial statements

Budget and financial statement documents a government publishes, with their links. They are documents, not budget data; list_financials gives audited statement lines.

Answered by [`GET /v1/budgets`](https://data.heytownhall.com/docs/reference/money/get-v1-budgets), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: budget or financial_statement.
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_financials`: List financial statements

Audited financial statements by jurisdiction and year. Give report_id for the statement lines, as printed and in cents.

Answered by [`GET /v1/financial-lines`](https://data.heytownhall.com/docs/reference/money/get-v1-financial-lines), billed as one records request.

- `report_id`: A report id, for its lines.
- `statement`: With report_id: one statement, such as statement_of_operations.
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_bids`: List open bids and tenders

Open requests for proposals, tenders and quotes, with closing times.

Answered by [`GET /v1/bids`](https://data.heytownhall.com/docs/reference/posts/get-v1-bids), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_applications`: List development applications

Rezonings, development permits and subdivisions, with their address, stage and status.

Answered by [`GET /v1/applications`](https://data.heytownhall.com/docs/reference/land-use/get-v1-applications), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: rezoning, development_permit, subdivision, …
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_jobs`: List job postings

Open government job postings with pay, hours and terms. Give job_id for one posting with its sections.

Answered by [`GET /v1/jobs`](https://data.heytownhall.com/docs/reference/posts/get-v1-jobs), billed as one records request.

- `job_id`: One posting, with its sections.
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: Employment type, such as full_time.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_officials`: List elected officials

Mayors, councillors, chairs and directors as each government's own page names them.

Answered by [`GET /v1/officials`](https://data.heytownhall.com/docs/reference/people-in-office/get-v1-officials), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: mayor, councillor, chair, director.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_departments`: List departments

Departments and their published public contacts (an office's line, never a person's).

Answered by [`GET /v1/departments`](https://data.heytownhall.com/docs/reference/people-in-office/get-v1-departments), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: The department's role, such as planning.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_news_and_notices`: List news, notices and events

What governments post: news, public notices, council recaps, events and alerts. Engagement projects are kind "engagement".

Answered by [`GET /v1/news`](https://data.heytownhall.com/docs/reference/posts/get-v1-news), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: news, notice, recap, event, alert, or engagement.
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_permits`: List permits, rules and fees

Each permit a government issues, where to apply, the fee table as published and the timeline it states.

Answered by [`GET /v1/permits`](https://data.heytownhall.com/docs/reference/land-use/get-v1-permits), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: building, business_licence, …
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_works`: List road and utility works

Announced road and utility work with its days and streets.

Answered by [`GET /v1/works`](https://data.heytownhall.com/docs/reference/land-use/get-v1-works), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: road or utility.
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_press`: List local press

Local press about a government: headline, publisher and link only.

Answered by [`GET /v1/press`](https://data.heytownhall.com/docs/reference/posts/get-v1-press), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `get_platforms`: Get the software each government runs

The platform census: which vendor each government uses for meetings, permits, payments and more.

Answered by [`GET /v1/platforms`](https://data.heytownhall.com/docs/reference/jurisdictions/get-v1-platforms), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `kind`: meetings, permits, payments, garbage, parking, feeds, video.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_platform_tenants`: List vendor tenants

Each meeting vendor's tenant matched to a government and verified: the vendor census by tenant (vendor, the vendor's name for the tenant, its host, how it was matched).

Answered by [`GET /v1/platform-tenants`](https://data.heytownhall.com/docs/reference/jurisdictions/get-v1-platform-tenants), billed as one records request.

- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `region`: A two-letter province or state code, such as "BC".
- `country`: "CA" or "US".
- `vendor`: The vendor, such as legistar or civicweb.
- `since`: Only records read at or after this ISO 8601 instant.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `list_topics`: List business topic tags

The business topics given to agenda items, motions, documents and recordings. Filter by topic to follow it across governments.

Answered by [`GET /v1/topics`](https://data.heytownhall.com/docs/reference/topics/get-v1-topics), billed as one records request.

- `topic`: A business topic id, such as "short_term_rentals", "data_centres", "solar_and_storage", "telecom_siting", "zoning", "procurement".
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `kind`: meeting_item, motion, meeting_document, recording.
- `from`: On or after this date, YYYY-MM-DD.
- `to`: On or before this date, YYYY-MM-DD.
- `since`: Only records read at or after this ISO 8601 instant.
- `meeting_id`: A meeting id from list_meetings.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.

### `changes_since`: What changed since

The change feed, oldest first: each change names the family and id of the record to read. Keep the last id and pass it as `after` next time.

Answered by [`GET /v1/events`](https://data.heytownhall.com/docs/reference/changes/get-v1-events), billed as one records request.

- `after`: The last event id you read.
- `since`: Only records read at or after this ISO 8601 instant.
- `jurisdiction`: A jurisdiction id from find_jurisdictions, such as "victoria".
- `family`: meeting, agenda_item, motion, recording, bylaw, post, jurisdiction, topic_tag.
- `limit`: Records to return, 1 to 50. Default 10.
- `cursor`: next_cursor from the previous result, for the next page.
