Skip to main content
Glama

Commonwealth-MCP

Python tools for Virginia public data, with a command-line interface and an MCP server for AI assistants. For policy researchers and developers building applications for Virginia residents.

Try the browser demos · Search the tools · Run examples · Add a data source · Design and remaining work

Independent project. Not affiliated with or maintained by the Commonwealth of Virginia.

Start here

MCP (Model Context Protocol) lets an AI client call functions supplied by a server. Here, those functions query government records and return structured results. The same functions are callable from Python and from the CLI without an AI model; they are not yet a supported public API (decision 0015 in design/architecture.md), so a release may rename them.

The browser demos use recorded responses and require no installation. To run the tools locally, install uv and Git, then run these commands in a macOS or Linux terminal:

git clone https://github.com/pranava0x0/Commonwealth-MCP.git
cd Commonwealth-MCP
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e . --group dev
.venv/bin/python examples/one_address_every_question.py

The example prints results for an address in Sterling: a parcel found in statewide records, a zoning coverage gap, and no matching landmark records within the query radius. It runs offline by default. Add --live to query the government services. See examples/ for five other workflows.

On Windows, virtual-environment executables live under .venv\Scripts\.

To point an AI client at the server, let the CLI write the config:

.venv/bin/commonwealth configure claude-code   # or claude, cursor, vscode, codex

It fills in the absolute path to this checkout. Add --dry-run to see the change without making it.

Without a checkout

The source manifests, the jurisdiction table and the skills ship inside the package, so a wheel works on its own:

uv tool install commonwealth-mcp       # once it is published; see issue #40
commonwealth doctor
commonwealth skills list               # where the bundled skills are on disk

uv tool install puts the command on your PATH with its own environment. uv pip install would refuse here, because it installs into a virtual environment and this path has none.

The examples, the recorded fixtures and the tests are repo-only.

Server and skills in one install

plugins/commonwealth-mcp/ is a plugin bundle: the server entry and the six skills together. In a client that reads a marketplace:

/plugin marketplace add pranava0x0/Commonwealth-MCP
/plugin install commonwealth-mcp@commonwealth-mcp

Install the package first, so commonwealth serve is on the path. For a client with no plugin system, commonwealth configure <client> writes the server entry on its own; skills then travel as files, copied from a directory commonwealth skills list prints into the client's skills folder.

Related MCP server: civic-library-mcp

What works

Question

Registered sources

Which government covers a place?

Names, FIPS codes, addresses, ZIP codes and coordinates; the table contains 133 counties and independent cities and 189 towns

What parcel is here?

Fairfax County, Loudoun County, Richmond City, Charles City County, the Town of Leesburg, and VGIN statewide parcels

How is a parcel zoned?

Fairfax County, Loudoun County, Richmond City, and the Towns of Leesburg and Vienna. A point in a town returns the town's layer and the county's, both unranked

Which address points, buildings, roads or public places are nearby?

VGIN statewide layers; VDOT road routes

Which water-quality stations are nearby?

DEQ monitoring stations, including historical stations

Where is a government boundary?

VGIN locality and town polygons

What does a Code of Virginia section say?

Section lookup by citation

Which part of the Code covers this subject?

The Code's own table of contents: titles, chapters, sections. A walk to a citation, not a full-text search — no public endpoint offers one

When does a local government meet?

Richmond City, Alexandria City, Albemarle County, Hampton City and Petersburg City, from the agenda platform each publishes through. The platform has no cancellation field, so a cancellation is read from the publisher's comment and labelled as a reading

Where are the hospitals and urgent care?

Loudoun County's own map of them — a county's list, not a state licensing register, with no hours or services

A registered statewide layer does not guarantee complete or current records for every place. Read each result's sources, dates, coverage and warnings. School attendance zones, transit service areas and other special districts are not resolved by the locality table.

Virginia's independent cities are separate from counties. A mailing city may differ from the governing locality, and towns can span counties. Ambiguous names return candidates for the caller to choose from.

When two registered sources cover a query, both can be returned. Their records remain separate. Zoning results describe GIS records; confirm applicable requirements with the locality and its adopted ordinance.

No matching records means the query found none in the sources checked. A registry gap means no source is registered for that question and place. Neither establishes that a feature or service does not exist.

Use an AI client

Preview a client configuration change:

.venv/bin/commonwealth configure claude-code --dry-run

Remove --dry-run to write it. Other supported configuration targets are claude, codex, cursor, and vscode. Existing server entries are preserved. The server uses local stdio transport:

.venv/bin/commonwealth serve

Client configuration support does not imply hosted access. There is no public hosted endpoint in this project.

Use the CLI or Python

A live CLI query. A PIN is the number a locality gives a parcel; the spacing inside it is the county's and matters:

.venv/bin/commonwealth tools call geo.find_parcel \
  --args '{"jurisdiction": "Fairfax County", "pin": "0102 14  0231"}'

The same capability in Python:

import asyncio
from commonwealth.runtime import load_context
from commonwealth.domains.geo import find_parcel

async def main():
    result = await find_parcel(
        load_context(), jurisdiction="Fairfax County", pin="0102 14  0231")
    print(result.model_dump_json(indent=2))

asyncio.run(main())

Results include data, source references, retrieval dates, coverage and warnings. Large retrieved results may have a commonwealth:// resource handle with an expiry, normally 24 hours. A handle contains what was retrieved; it does not remove upstream query limits.

What remains

Directly integrated local sources cover a handful of places: Fairfax, Loudoun and Charles City counties, Richmond City, and the Towns of Leesburg and Vienna for parcels and zoning, and five localities for public meetings. Adding another locality's layer is the most useful contribution and the best-documented path (CONTRIBUTING.md); the state's open-data portal lists many of them (issue #60).

Packaging landed on 2026-09-08: the source manifests, the jurisdiction table and the skills ship inside the wheel, so an install works without a checkout. What remains before the server is published is a release version and the upload itself (issue #40). State legislation and full-text Code search are tracked in issue #11 and issue #12. The legislature publishes bills and votes as keyless bulk files (design/source-quirks.md § 20), so #11 waits on an adapter rather than a key. #12 waits on the publisher, whose search backend reports itself down.

Budgets, procurement, school statistics, transit, permits and service requests need source discovery and adapters. They are proposed areas of work, not available tools. The development priorities explain the order and acceptance criteria.

Develop and contribute

COMMONWEALTH_DENY_NETWORK=1 .venv/bin/pytest
.venv/bin/python tools/build_site.py --fixtures
python3 tools/check_writing.py --code

The tests replay recorded government responses. To check current service availability separately, run .venv/bin/commonwealth doctor --live.

Location

Purpose

examples/

Runnable workflows

CONTRIBUTING.md

Source onboarding and development checks

design/

Current architecture, contracts and planned work

src/commonwealth/

Python implementation

sources/

Source manifests and jurisdiction records

plugins/commonwealth-mcp/

The plugin bundle: the server entry, the client manifests, and skills/ — instructions for multi-tool workflows

tests/, evals/

Offline tests and workflow evaluations

docs/

Published site and audit records

research/

Historical research; verify dated claims before reuse

License

Code: Apache-2.0. Registry: CC0. Documentation prose: CC-BY-4.0. Recorded government responses retain their publishers' terms. See NOTICE and THIRD_PARTY_DATA.yml.

Available Tools

5 tools
civic.get_code_sectionA
Read-only

Get the text of a Code of Virginia section by its citation (e.g. '1-500', '18.2-57'). Direct lookup only — this is not a full-text search; the caller must already know or have found the section number. Results carry the section's own citation history exactly as published, with a link to the live page. A missing section (repealed, renumbered, or never existed) returns found=False, not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
citationYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
coverageYes
evidenceNo
warningsNo
resourcesNo
_executionNo
provenanceNo
next_actionsNo
requires_user_choiceNo

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds meaningful behavioral detail: results carry citation history exactly as published, include a link to the live page, and missing sections return found=False rather than an error. This sets accurate expectations beyond the structured annotations. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. The primary action is front-loaded, followed by critical lookup limitations, then result behavior. Every sentence earns its place and the length is appropriate for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully equips an agent to call the tool correctly: a clear purpose, citation format examples, a lookup-only warning, and missing-section behavior. An output schema exists, so return value structure does not need to be repeated. Nothing necessary for correct invocation is omitted.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description carries the full burden of explaining the single 'citation' parameter. It provides concrete examples ('1-500', '18.2-57') and clarifies that the value is a Code of Virginia section citation. This adds substantial meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb and resource: 'Get the text of a Code of Virginia section by its citation.' It further distinguishes itself from full-text search by stating 'Direct lookup only,' which separates it from any search-style sibling. The sibling tools are in different domains (jurisdiction, zoning, parcels), so no ambiguity remains about what this tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool: the caller must already know or have found the section number. It also gives an explicit exclusion: 'this is not a full-text search.' This is actionable guidance that prevents misuse without requiring inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

geo.find_boundariesA
Read-only

Get a Virginia jurisdiction's official boundary: FIPS, GNIS, area, jurisdiction type, bounding box, and the publisher's own centroid. Use to confirm WHICH government's territory is meant and how big it is. Independent cities are returned as their own territory, never as part of the county sharing their name. Screening geometry only — it is generalized and the publisher disclaims survey use, so never decide from it which side of a boundary an address sits on. Pass detail='full' for vertices. Not a containment test: to find which jurisdiction covers a point, use registry.resolve_jurisdiction with lon/lat.

ParametersJSON Schema
NameRequiredDescriptionDefault
detailNoconcise
jurisdictionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
coverageYes
evidenceNo
warningsNo
resourcesNo
_executionNo
provenanceNo
next_actionsNo
requires_user_choiceNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and openWorldHint annotations, the description discloses that geometry is generalized, the publisher disclaims survey use, and it must never be used to decide which side of a boundary an address sits on. It also explains the independent-city behavior, which is a suprising edge case.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: function, usage context, edge case, geomery caveat, parameter guidance, and sibling distinction. Key constraints are front-loaded, and the warning about surveying is prominent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema presumably documents return fields, so the description focuses on what is not elsewhere specified: when to use the tool, how the geometry behaves, independent-city behavior, and the detail parameter. For an agent selecting and invoking this tool, all necessary context is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates by explaining that detail='full' requests vertices and by framing jurisdiction as a Virginia jurisdiction whose territory is returned as separate for independent cities. It does not specify the jurisdiction value format, but the parameter semantics are meaningfully clarified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description has a specific verb and resource: 'Get a Virginia jurisdiction's official boundary,' and lists concrete return contents (FIPS, GNIS, area, jurisdiction type, bounding box, centroid). It also distinguishes itself from sibling registry.resolve_jurisdiction by explicitly stating it is not a containment test.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states exactly when to use this tool ('confirm WHICH government's territory is meant and how big it is') and when not to use it ('Not a containment test... use registry.resolve_jurisdiction'). This gives clear routing guidance against the sibling tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

geo.find_parcelA
Read-only

Find parcel records in a Virginia jurisdiction by parcel PIN or by a lon/lat point. Pass the user's jurisdiction string as given — resolution and its ambiguities are handled here, and candidate lists must go back to the user unchosen. Results carry provenance and coverage; an empty result with coverage.registry='none' means Commonwealth has no source there, not that no parcel exists. Not for street addresses yet (no geocoding in this release).

ParametersJSON Schema
NameRequiredDescriptionDefault
latNo
lonNo
pinNo
jurisdictionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
coverageYes
evidenceNo
warningsNo
resourcesNo
_executionNo
provenanceNo
next_actionsNo
requires_user_choiceNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint and openWorldHint, but the description adds material behavioral context beyond them: results carry provenance and coverage, an empty result with coverage.registry='none' means no source rather than no parcel, and jurisdiction-resolution ambiguity is handled internally. This is exactly the kind of operational nuance an agent needs to interpret results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact yet dense; every sentence serves a purpose. The core action is front-loaded, followed by critical operational guidance, and no words are wasted on restating schema fields or repeating annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two query modes, jurisdiction-resolution semantics, candidate disambiguation, provenance/coverage concerns, and an open-world empty-result case, the description covers essentially all behavioral requirements. The output schema covers return shape, so the description only needs to explain semantics, which it does thoroughly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 0%, the description compensates by explicitly naming the PIN, the lon/lat point, and the jurisdiction string, and by explaining how jurisdiction should be passed ('as given'). It adds meaning beyond the bare schema, though it does not fully detail parameter constraints such as coordinate format or whether pin and lon/lat are mutually exclusive beyond the 'or' phrasing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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: 'Find parcel records in a Virginia jurisdiction by parcel PIN or by a lon/lat point.' It also scopes the geographic domain and identifies the two supported query modes, making the purpose unambiguous and naturally distinct from sibling tools like geo.find_zoning or geo.find_boundaries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly instructs the agent to pass the user's jurisdiction string as given and states that resolution/ambiguities are handled inside the tool, which also implies not to pre-resolve via registry.resolve_jurisdiction. It gives a useful exclusion ('Not for street addresses yet') and a handling rule ('candidate lists must go back to the user unchosen'). It does not explicitly name the zoning/boundaries siblings as alternatives for other query types, so it stops short of full alternative mapping.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

geo.find_zoningA
Read-only

Find the zoning district(s) for a parcel PIN or lon/lat point in a Virginia jurisdiction. Screening only: results state the GIS layer's answer, never a legal determination — repeat the screening_only warning to the user. When two official sources are registered, both are queried and any disagreement is shown, not reconciled. Use geo.find_parcel first when you need the parcel record itself.

ParametersJSON Schema
NameRequiredDescriptionDefault
latNo
lonNo
pinNo
jurisdictionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
coverageYes
evidenceNo
warningsNo
resourcesNo
_executionNo
provenanceNo
next_actionsNo
requires_user_choiceNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the readOnly/openWorld/destructive annotations by explaining that the tool reports the GIS layer's answer, requires repeating a screening_only warning, and queries both registered official sources while showing disagreements rather than reconciling them. These are meaningful behavioral traits not present in the structured metadata.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the main purpose, followed immediately by the key caveats and sibling routing. There is no filler or repetition of schema/annotation information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a read-only screening tool: it covers input modes, jurisdiction scope, legal caveat, dual-source behavior, and a sibling alternative. Since an output schema exists, the description does not need to document return fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description carries the burden of explaining parameters. It clarifies the two locator modes ('parcel PIN or lon/lat point') and the jurisdiction scope, but it does not explicitly state the at-least-one-of pin/lat/lon requirement or coordinate format details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb and resource: 'Find the zoning district(s) for a parcel PIN or lon/lat point in a Virginia jurisdiction.' It clearly distinguishes itself from siblings by stating it answers zoning screening questions, not parcel-record lookups or legal determinations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit usage context: use it for zoning screening only, and names an alternative with a routing condition: 'Use geo.find_parcel first when you need the parcel record itself.' It also tells the agent the result is never a legal determination, covering a when-not-to-rely case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

registry.resolve_jurisdictionA
Read-only

Resolve a Virginia jurisdiction from a name, alias, or FIPS code, or from a lon/lat point by point-in-polygon against official boundaries. Use FIRST whenever a place is named or a coordinate is given: Virginia has independent cities that are not inside the counties sharing their names (Fairfax City is not in Fairfax County), and towns that sit inside a county so BOTH governments apply — read layered_authorities, do not assume the resolved leaf answers everything. Pass query OR lon/lat, never both. If the result carries candidates with requires_user_choice, present them to the user and never pick one yourself. Not for street addresses yet (no geocoding in this release).

ParametersJSON Schema
NameRequiredDescriptionDefault
latNo
lonNo
queryNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
coverageYes
evidenceNo
warningsNo
resourcesNo
_executionNo
provenanceNo
next_actionsNo
requires_user_choiceNo

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, and non-destructive hints; the description adds substantial behavioral context beyond those hints. It explains point-in-polygon resolution, Virginia's independent-city versus county quirk, layered authorities that can apply simultaneously, and the requirement to surface requires_user_choice candidates rather than silently picking one. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and immediately follows with essential context about Virginia's jurisdictional quirks. Every sentence earns its place: input modes, the crucial XOR constraint, user-choice handling, and the no-geocoding limitation. It is dense but structured and avoids filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no required parameters, an output schema present, and complex jurisdictional semantics, the description is remarkably complete. It covers input modes, geographic pitfalls, layered authorities, user-decision handling, and the known limitation about street addresses. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the full semantic burden. It does: query is explained as a name, alias, or FIPS code; lat and lon are tied to coordinate-based point-in-polygon resolution; and the mutual exclusivity of query versus lat/lon is made explicit. This adds meaning far beyond the bare schema properties.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource: resolve a Virginia jurisdiction from a name, alias, FIPS code, or lon/lat point. It also differentiates from sibling tools by noting this is the tool to use FIRST when a place or coordinate is given, and by explicitly excluding street addresses, which distinguishes it from potential geocoding or boundary tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: use it whenever a place is named or a coordinate is given. It also provides clear exclusions (not for street addresses), a critical input rule (query OR lon/lat, never both), and a decisive handling instruction for requires_user_choice candidates, leaving no ambiguity about how to proceed.

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.

  1. 5 tool updatesv0.1.0
    • First observedcivic.get_code_section
    • First observedgeo.find_boundaries
    • First observedgeo.find_parcel
    • First observedgeo.find_zoning
    • First observedregistry.resolve_jurisdiction

TDQS

A4.8/5.0

Scored across 5 tools

Disambiguation5/5

Each tool addresses a distinct resource/action: jurisdiction resolution, parcel lookup, zoning lookup, boundary geometry, and legal code text. The only potential overlap is between find_parcel and find_zoning, but their outputs are clearly different.

Naming Consistency5/5

All tools follow a prefix.verb_noun pattern with consistent snake_case: registry.resolve_jurisdiction, geo.find_zoning, geo.find_parcel, geo.find_boundaries, civic.get_code_section. The domain prefixes make grouping and purpose predictable.

Tool Count5/5

With 5 tools, the server is well-scoped for the Virginia civic/geographic domain. Each tool fills a distinct role, and the set is neither bloated nor too sparse.

Completeness4/5

The set covers the core read-only workflows: resolve a jurisdiction, get boundaries, find a parcel, get zoning, and retrieve a code section. However, there is no full-text search for code sections and no geocoding for street addresses, so agents must already know section numbers or accept coordinates/PINs. These are explicitly out of scope but still limit the surface.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables searching and querying Virginia Open Data (datahub.va.gov) via the Socrata API, providing tools to search datasets, run SoQL queries, and retrieve metadata.
    3 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to answer DFW civic and property questions using official data sources without API keys.
    9
    87 npm
    2
    Apache 2.0