Servidor MCP

OpenPublica

com.openpublica/civic-meetings

Qué hace este MCP

Searches US local-government meetings, transcripts, adopted plans, budgets, and AI-generated summaries with document and page-level citations.

discover_meeting_vocabulary
Discover category and topic filters
Discover the valid category and topic filter values before filtering a search. Meeting `category_tag`s are opaque UUIDs and topics have no fixed list, so you cannot guess them. Call this first to get the real values, then pass a returned `category_tag` (from `categories[].tags`) or `topic` string into `search_meetings_semantic` / `list_recent_meetings`. Scope with a government and/or date range; calls without explicit dates default to a recent window (returned as `default_window_days`).
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'discover_meeting_vocabularyArguments', 'properties': {'end_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'End Date', 'default': None, 'description': 'Optional latest date, MM-DD-YYYY.'}, 'start_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Start Date', 'default': None, 'description': 'Optional earliest date, MM-DD-YYYY.'}, 'topic_limit': {'type': 'integer', 'title': 'Topic Limit', 'default': 50, 'maximum': 200, 'minimum': 1, 'description': 'Max topics to return, most common first (1-200).'}, 'government_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Government Id', 'default': None, 'description': 'Optional account_id to scope the vocabulary to one government.'}, 'government_ids': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'title': 'Government Ids', 'default': None, 'description': 'Optional list of account_ids to scope to several governments. Overrides government_id.'}}}
Esquema de salida
{'type': 'object', 'title': 'discover_meeting_vocabularyDictOutput', 'additionalProperties': True}
find_governments_by_name
Find governments by name
Resolve a place *name* to the governments OpenPublica tracks there. Use this when you know a city/state name but not its coordinates — it returns matching governments with their `account_id` (prefix matches first), which you then pass to the search/list tools. Prefer this over `find_local_governments` when starting from a name rather than a latitude/longitude.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'find_governments_by_nameArguments', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max governments to return (1-50).'}, 'query': {'type': 'string', 'title': 'Query', 'description': "A place name to search for, e.g. 'Sacramento', 'San Francisco, CA', or a state like 'Texas'."}}}
Esquema de salida
{'type': 'object', 'title': 'find_governments_by_nameDictOutput', 'additionalProperties': True}
find_governments_by_zip
Find governments by ZIP code
Resolve a ZIP code to nearby tracked governments. Convenience wrapper: geocodes the ZIP, then finds the governments OpenPublica tracks nearest that point. Returns their `account_id`s plus the resolved location. An empty `governments` list means none are tracked near that ZIP yet.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'find_governments_by_zipArguments', 'required': ['postal_code'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max governments to return (1-50).'}, 'postal_code': {'type': 'string', 'title': 'Postal Code', 'description': "A US ZIP code, e.g. '95814'."}}}
Esquema de salida
{'type': 'object', 'title': 'find_governments_by_zipDictOutput', 'additionalProperties': True}
find_local_governments
Find governments near a location
Discover which governments OpenPublica tracks near a coordinate. Returns nearby governments with their `account_id`, which you can pass to the other tools to scope results to a specific city or board. Note OpenPublica only covers a limited set of US localities; an empty result means none are tracked near that point yet.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'find_local_governmentsArguments', 'required': ['longitude', 'latitude'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Max governments to return (1-50).'}, 'latitude': {'type': 'number', 'title': 'Latitude', 'maximum': 90, 'minimum': -90, 'description': 'Latitude of the location of interest.'}, 'longitude': {'type': 'number', 'title': 'Longitude', 'maximum': 180, 'minimum': -180, 'description': 'Longitude of the location of interest.'}}}
Esquema de salida
{'type': 'object', 'title': 'find_local_governmentsDictOutput', 'additionalProperties': True}
get_coverage_overview
Get coverage overview
Get OpenPublica's overall coverage: total governments, states, and meetings indexed. DC is tracked but is not a state, so it is reported separately as `includes_dc` — read the pair as "N states and DC".
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'get_coverage_overviewArguments', 'properties': {}}
Esquema de salida
{'type': 'object', 'title': 'get_coverage_overviewDictOutput', 'additionalProperties': True}
get_document
Get document metadata
One document's metadata. Use read_document_pages to read it. If an `availability` key is present, read it before quoting figures: its `problems` are transcription-lint findings, most often a footnote marker that may have been merged into the number it annotates. No such key means the document transcribed cleanly.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'get_documentArguments', 'required': ['document_id'], 'properties': {'document_id': {'type': 'string', 'title': 'Document Id', 'description': 'Document id from list_government_documents or search_documents.'}}}
get_government_info
Get government profile
Get a tracked government's profile: name, location, and meeting categories.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'get_government_infoArguments', 'required': ['government_id'], 'properties': {'government_id': {'type': 'string', 'title': 'Government Id', 'description': 'The account_id of the government.'}, 'include_weekly_summary': {'type': 'boolean', 'title': 'Include Weekly Summary', 'default': False, 'description': 'If true, include the AI-generated weekly digest (markdown). Default false.'}}}
Esquema de salida
{'type': 'object', 'title': 'get_government_infoDictOutput', 'additionalProperties': True}
get_government_stats
Get government meeting stats
Get meeting-activity stats for a government over a recent window. Returns total meeting count, a per-day activity map, and a breakdown of meeting categories — useful for "how active has X been lately?" questions.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'get_government_statsArguments', 'required': ['government_id'], 'properties': {'days': {'type': 'integer', 'title': 'Days', 'default': 30, 'maximum': 365, 'minimum': 1, 'description': 'Look-back window in days (1-365).'}, 'government_id': {'type': 'string', 'title': 'Government Id', 'description': "account_id of the government, or 'all' for corpus-wide stats."}}}
Esquema de salida
{'type': 'object', 'title': 'get_government_statsDictOutput', 'additionalProperties': True}
get_meeting
Get meeting
Get a single meeting's full AI summary and topics. Set `include_transcript=true` to also retrieve the complete transcript text for direct quotation. Returns an error object if the meeting is not found.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'get_meetingArguments', 'required': ['meeting_id'], 'properties': {'meeting_id': {'type': 'string', 'title': 'Meeting Id', 'description': 'The meeting_id returned by a search/list tool.'}, 'include_transcript': {'type': 'boolean', 'title': 'Include Transcript', 'default': False, 'description': 'If true, also fetch the full meeting transcript (can be long). Default false.'}}}
Esquema de salida
{'type': 'object', 'title': 'get_meetingDictOutput', 'additionalProperties': True}
list_government_documents
List government documents
List a government's adopted plan and budget documents. Each entry carries `covers` — every general-plan element that document answers for. A city that publishes one bound general plan satisfies all eight with the same PDF, so do not conclude an element is unpublished because no entry is named after it. `status` says what the entry offers: `converted` is searchable and readable; `superseded` is a retired edition, still stored but not searchable; and **`failed` means we hold this document and could not read it — it is not evidence the city published nothing.** Cite `source_url` in that case; it is always the city's own copy. An `availability` block appears ONLY when something is wrong with a document, and `availability.reason` says what. No `availability` key means there is nothing to report.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'list_government_documentsArguments', 'required': ['government_id'], 'properties': {'government_id': {'type': 'string', 'title': 'Government Id', 'description': 'account_id from find_local_governments.'}, 'include_superseded': {'type': 'boolean', 'title': 'Include Superseded', 'default': False, 'description': 'Also include prior editions retired by a newer document.'}}}
list_recent_meetings
List recent meetings
Browse meetings newest-first, optionally filtered by government, type, topic, or date. Use this for "what are the most recent meetings" or to page through a government's history. For topical questions, prefer `search_meetings_semantic`.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'list_recent_meetingsArguments', 'properties': {'page': {'type': 'integer', 'title': 'Page', 'default': 1, 'minimum': 1, 'description': '1-based page number for older results.'}, 'limit': {'type': 'integer', 'title': 'Limit', 'default': 10, 'maximum': 25, 'minimum': 1, 'description': 'Meetings per page (1-25).'}, 'topic': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Topic', 'default': None, 'description': "Optional topic filter — a topic name from discover_meeting_vocabulary, e.g. 'Affordable Housing'."}, 'end_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'End Date', 'default': None, 'description': 'Optional latest date, MM-DD-YYYY.'}, 'start_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Start Date', 'default': None, 'description': 'Optional earliest date, MM-DD-YYYY.'}, 'category_tag': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Category Tag', 'default': None, 'description': "Optional meeting-type filter — an opaque category_tag from discover_meeting_vocabulary (not a guessable slug; don't invent it)."}, 'government_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Government Id', 'default': None, 'description': 'account_id to list meetings for (from find_local_governments). Omit to list across all governments.'}}}
Esquema de salida
{'type': 'object', 'title': 'list_recent_meetingsDictOutput', 'additionalProperties': True}
read_document_pages
Read document pages
Read a page range of a document as markdown. Pages are transcribed from rendered pixels, so tables and scanned text come through as text. A page that could not be transcribed appears as a marked hole rather than being silently dropped — if you see one, say so instead of reading past it. Text is assembled from page windows, so `covered` may be slightly wider than what you asked for; cite the page numbers in `covered`, not `requested`.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'read_document_pagesArguments', 'required': ['document_id', 'first_page', 'last_page'], 'properties': {'last_page': {'type': 'integer', 'title': 'Last Page', 'minimum': 1, 'description': 'Last page to read. Spans longer than 40 pages are clamped to 40 from first_page.'}, 'first_page': {'type': 'integer', 'title': 'First Page', 'minimum': 1, 'description': 'First page to read (1-based, as the PDF renders).'}, 'document_id': {'type': 'string', 'title': 'Document Id', 'description': 'Document id from list_government_documents or search_documents.'}}}
search_documents
Search documents
Search adopted plan and budget documents, returning page-cited excerpts. Each hit's `text` is a short passage around the match, not the full page — call read_document_pages with the hit's `first_page` to read it in context. Every hit carries `first_page`/`last_page` and `source_url`. Quote those when citing: the page number is what makes the claim checkable against the city's own copy. This is word matching, not semantic search — try the terms a plan would actually use. Only currently-served documents are searchable, so an empty result is not evidence the government has no such policy; check list_government_documents for what is held and what could not be read. A hit with `document_complete: false` comes from a document with transcription findings. Verify it against `source_url` before quoting a number from it.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'search_documentsArguments', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 10, 'maximum': 50, 'minimum': 1, 'description': 'Maximum excerpts to return.'}, 'query': {'type': 'string', 'title': 'Query', 'description': "Words to find in plan and budget text, e.g. 'accessory dwelling unit parking'."}, 'government_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Government Id', 'default': None, 'description': 'Optional account_id to restrict the search to one government.'}}}
search_meetings_semantic
Search meetings
Search OpenPublica meeting summaries by meaning, exact terms, or both. The best default tool for "what has been said/decided about X" questions. Results carry a `relevance_score` (semantic, 0-1) and/or `keyword_score` (BM25) plus `highlights`, so you can triage matches by confidence. If the response sets `degraded_to_vector`, the keyword index was unavailable and results are semantic-only — do NOT treat them as exact-term matches. Narrow with `category_tag`/`topic` (get valid values from `discover_meeting_vocabulary`), a date range, or one or more governments. Returns a summary preview; call `get_meeting` with a returned `meeting_id` for the full summary or transcript.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'search_meetings_semanticArguments', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 10, 'maximum': 25, 'minimum': 1, 'description': 'Max meetings to return (1-25).'}, 'query': {'type': 'string', 'title': 'Query', 'description': "What to search for in plain language, e.g. 'short-term rental regulations' or 'police budget overtime'."}, 'topic': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Topic', 'default': None, 'description': "Optional topic filter — a topic name from discover_meeting_vocabulary, e.g. 'Affordable Housing'. Restricts to meetings that discussed it."}, 'end_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'End Date', 'default': None, 'description': 'Optional latest meeting date, MM-DD-YYYY.'}, 'min_score': {'anyOf': [{'type': 'number', 'maximum': 1.0, 'minimum': 0.0}, {'type': 'null'}], 'title': 'Min Score', 'default': None, 'description': 'Optional semantic relevance floor 0-1 (default 0.4). Raise to return only strong matches; lower to widen recall. Applies to semantic matching only — keyword (BM25) hits are not filtered by it.'}, 'match_type': {'anyOf': [{'enum': ['semantic', 'keyword', 'hybrid'], 'type': 'string'}, {'type': 'null'}], 'title': 'Match Type', 'default': None, 'description': "How to match: 'semantic' (default, by meaning — best for concepts/paraphrases), 'keyword' (exact terms — best for names, ordinance numbers, quoted phrases), or 'hybrid' (both, rank-fused). Use keyword/hybrid when the query has a literal string an embedding might miss."}, 'start_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Start Date', 'default': None, 'description': 'Optional earliest meeting date, MM-DD-YYYY.'}, 'category_tag': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Category Tag', 'default': None, 'description': 'Optional meeting-type filter — an opaque category_tag from discover_meeting_vocabulary (not a guessable slug).'}, 'government_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Government Id', 'default': None, 'description': 'Optional account_id (from find_local_governments) to restrict the search to one government.'}, 'government_ids': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'title': 'Government Ids', 'default': None, 'description': 'Optional list of account_ids to search across several governments at once (e.g. to compare cities). Overrides government_id.'}}}
Esquema de salida
{'type': 'object', 'title': 'search_meetings_semanticDictOutput', 'additionalProperties': True}
search_meeting_transcript
Search meeting transcript
Find exact quotes/passages inside one meeting's transcript. Use this to pull direct quotations without loading a whole (often very long) transcript: it fetches the transcript server-side, scans it, and returns only the matching passages with approximate `start`/`end` timecodes when available. Exact matches rank first, with a fuzzy fallback. Prefer this over `get_meeting(include_transcript=true)` when you only need specific quotes.
Solo lectura Acceso externo
Esquema de entrada
{'type': 'object', 'title': 'search_meeting_transcriptArguments', 'required': ['meeting_id', 'query'], 'properties': {'query': {'type': 'string', 'title': 'Query', 'description': "The phrase or terms to find in the transcript, e.g. 'rent stabilization' or a speaker's exact words."}, 'meeting_id': {'type': 'string', 'title': 'Meeting Id', 'description': 'The meeting_id (from a search/list tool) whose transcript to search.'}, 'max_passages': {'type': 'integer', 'title': 'Max Passages', 'default': 5, 'maximum': 20, 'minimum': 1, 'description': 'Max matched passages to return (1-20).'}, 'context_chars': {'type': 'integer', 'title': 'Context Chars', 'default': 300, 'maximum': 2000, 'minimum': 0, 'description': 'Characters of surrounding context per side of a match (0-2000).'}}}
Esquema de salida
{'type': 'object', 'title': 'search_meeting_transcriptDictOutput', 'additionalProperties': True}
Añadido
get_coverage_overview
17 de September de 2026 a las 12:36
Añadido
search_documents
17 de September de 2026 a las 12:36
Añadido
read_document_pages
17 de September de 2026 a las 12:36
Añadido
get_document
17 de September de 2026 a las 12:36
Añadido
list_government_documents
17 de September de 2026 a las 12:36
Añadido
discover_meeting_vocabulary
17 de September de 2026 a las 12:36
Añadido
get_government_stats
17 de September de 2026 a las 12:36
Añadido
get_government_info
17 de September de 2026 a las 12:36
Añadido
find_governments_by_zip
17 de September de 2026 a las 12:36
Añadido
find_governments_by_name
17 de September de 2026 a las 12:36
Añadido
find_local_governments
17 de September de 2026 a las 12:36
Añadido
search_meeting_transcript
17 de September de 2026 a las 12:36
Añadido
get_meeting
17 de September de 2026 a las 12:36
Añadido
list_recent_meetings
17 de September de 2026 a las 12:36
Añadido
search_meetings_semantic
17 de September de 2026 a las 12:36