Skip to content

MCP server for geocoding and residency verification using Census Geocoder and city boundary data

Notifications You must be signed in to change notification settings

govex/geocoding-mcp-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Geocoding MCP Server

MCP server providing geocoding and residency verification tools for AI workflows.

The Problem and What This Does

LLMs can hallucinate address data, giving incorrect coordinates and residency verification. To get reliable results, you need a real geocoding service. This MCP server connects AI agents to a real geocoding service (Census Geocoder) so you can ask questions in natural language while getting accurate data, no API calls or scripts needed.

Current Implementation: Local prototype where each user runs their own instance. Uses the free Census Geocoder, which has limitations (US-only, slower than commercial options, requires well-formatted addresses, no reverse geocoding). This MCP server was specifically tested using VS Code/GitHub Copilot as the Host and supported Client, but you could try using the server with other MCP-compatible applications.

Potential Use Case for Cities: This concept originated from the idea that cities could deploy a hosted MCP server as a centralized geocoding service. Multiple AI agents across applications and departments (licensing, permits, business registration) would connect to one server instance instead of each building their own geocoding integration. This is a quick exploration of that concept.

How the Geocoding MCP Server Works

flowchart TB
    User["🖥️ HOST: VS Code + GitHub Copilot LLM"]
    
    Client["📄 MCP CLIENT
    Component in Host that talks to Server"]
    
    Server["⚙️ MCP SERVER 
    server.py
    geocode, verify residency, get ward"]
    
    Census["🌐 CENSUS GEOCODER API
    Free US address geocoding"]
    
    Boundary["📍 LOCAL BOUNDARY FILES
    city_boundary.geojson
    wards.geojson"]
    
    User -->|1. Question: Is 1600 Penn Ave a DC address?| Client
    Client -->|2. Call tool: geocode_address| Server
    Server -->|3. Try abbreviated, then full name| Census
    Census -->|4. Return all matches NW and SE| Server
    Server -->|5. Check residency and districts| Boundary
    Boundary -->|6. Return results| Server
    Server -->|7. Send answer| Client
    Client -->|8. Found 2 matches: NW Ward 2 and SE Ward 6| User
    
    style User fill:#e3f2fd,stroke:#1976d2,stroke-width:4px
    style Client fill:#fff3e0,stroke:#f57c00,stroke-width:4px
    style Server fill:#e8f5e9,stroke:#388e3c,stroke-width:4px
    style Census fill:#f3e5f5,stroke:#7b1fa2,stroke-width:4px
    style Boundary fill:#fce4ec,stroke:#c2185b,stroke-width:4px
Loading

Prerequisites

  • Python 3.10+
  • VS Code with GitHub Copilot subscription
  • City boundary and district GeoJSON files

Setup

1. Install Dependencies

cd geocoding-mcp-server
uv venv # Create a virtual environment if needed
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
uv pip install -r requirements.txt

2. Download Boundary Files

This server is designed to work with any US city, but this prototype uses DC boundaries:

DC Boundary:

  1. Visit https://opendata.dc.gov/datasets/7241f6d500b44288ad983f0942b39663_10
  2. Click "Download" → "GeoJSON"
  3. Save as city_boundary.geojson in boundaries/ folder

DC Wards:

  1. Visit https://opendata.dc.gov/datasets/c5cd8b40fb784548a6680aead5f919ed_53
  2. Click "Download" → "GeoJSON"
  3. Save as wards.geojson in boundaries/ folder

The server will automatically create the boundaries/ and logs/ folders if they don't exist.

Configuring for Cities other than DC

  1. Edit the configuration section at the top of server.py:
# Change these settings to adapt for your city
CITY_NAME = "Washington DC"
CITY_KEYWORDS = ['washington', 'dc', 'district of columbia']
USE_QUADRANTS = True  # Set to False for cities without quadrant system
QUADRANTS = ['NW', 'NE', 'SE', 'SW']  # Customize or leave empty

3. Configure VS Code

cp .vscode/mcp.json.example .vscode/mcp.json

Edit .vscode/mcp.json with the absolute path to server.py:

{
  "servers": {
    "geocoding-server": {
      "command": "python", 
      "args": ["/Users/yourname/Dev/geocoding-mcp-server/server.py"]
    }
  }
}

4. Enable in VS Code

  1. Reload VS Code: Cmd/Ctrl + Shift + P → "Reload Window"
  2. Open Copilot Chat and switch to Agent mode
  3. Click tools icon to verify geocoding-server is connected
  4. You should see: geocode_address, check_residency, get_district

Available Tools

geocode_address(address)

Convert a street address to coordinates. Automatically handles:

  • Abbreviated street names (Penn Ave → Pennsylvania Avenue)
  • Multiple matches in different quadrants
  • Ambiguous addresses

Example:

geocode the address "1600 Penn Ave"

Returns both 1600 Pennsylvania Ave NW and SE with coordinates.

check_residency(address)

Verify if an address is within the city boundary. Returns is_resident: true/false with all matching addresses.

Example:

is "1600 Penn Ave" a DC address?

Returns both matches with residency status for each.

get_district(address)

Return the ward/district for an address. Only checks districts for addresses confirmed within city boundaries.

Example:

what ward is "1600 Penn Ave" in?

Returns ward information for all matching addresses in DC.

How It Works

The server uses a modular design:

  1. geocode_address: Handles all geocoding logic, searches quadrant variations
  2. check_residency: Calls geocode, then checks city boundary
  3. get_district: Calls geocode and residency check, then identifies ward

All tool interactions are logged to logs/interactions.jsonl for audit trails.

About

MCP server for geocoding and residency verification using Census Geocoder and city boundary data

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages