Back to list
breverdbidder

zonewise-mcp-server

by breverdbidder

ZoneWise - Florida's expert zoning intelligence platform. Wise about zoning.

0🍴 0📅 Jan 25, 2026

SKILL.md


name: zonewise-mcp-server description: Implements MCP (Model Context Protocol) server for ZoneWise zoning queries. Exposes tools for district lookup, permitted uses, setbacks, density calculations, and site analysis. Built with FastMCP (Python) or MCP SDK (TypeScript). Triggers on: MCP server, tool implementation, protocol handler, zoning API, Claude integration, tool definitions.

ZoneWise MCP Server

Overview

MCP server exposing ZoneWise zoning data to AI assistants (Claude, etc.) through standardized tool interfaces.

Architecture

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Claude/AI      │────▶│  MCP Server     │────▶│  ZoneWise DB    │
│  Assistant      │◀────│  (FastMCP)      │◀────│  (Supabase)     │
└─────────────────┘     └─────────────────┘     └─────────────────┘

Quick Start

Python (FastMCP)

from fastmcp import FastMCP

mcp = FastMCP("ZoneWise")

@mcp.tool()
def zonewise_lookup(jurisdiction: str, district_code: str) -> dict:
    """Look up zoning district information."""
    return lookup_district(jurisdiction, district_code)

if __name__ == "__main__":
    mcp.run()

TypeScript (MCP SDK)

import { Server } from "@modelcontextprotocol/sdk/server";

const server = new Server({
  name: "zonewise",
  version: "1.0.0"
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "zonewise_lookup") {
    return lookupDistrict(request.params.arguments);
  }
});

Available Tools

1. zonewise_lookup

Full district information lookup.

Input:

{
  "jurisdiction": "melbourne",
  "district_code": "R-1A"
}

Output:

{
  "district_name": "Single-Family Residential",
  "category": "residential",
  "permitted_uses": {...},
  "dimensional_standards": {...},
  "density": {...},
  "municode_url": "https://..."
}

2. zonewise_permitted_uses

Check if a specific use is allowed.

Input:

{
  "jurisdiction": "palm_bay",
  "district_code": "C-1",
  "use": "restaurant"
}

Output:

{
  "use": "restaurant",
  "status": "conditional",
  "conditions": ["Special exception required", "Parking minimum: 1/100sf"],
  "municode_reference": "Section 185.12"
}

3. zonewise_setbacks

Get setback requirements for a district.

Input:

{
  "jurisdiction": "satellite_beach",
  "district_code": "RS-1"
}

Output:

{
  "front_ft": 25,
  "side_ft": 7.5,
  "rear_ft": 20,
  "corner_side_ft": 15,
  "waterfront_ft": 50,
  "notes": ["Increased setbacks within FEMA flood zones"]
}

4. zonewise_density

Get density and FAR information.

Input:

{
  "jurisdiction": "cocoa_beach",
  "district_code": "R-3"
}

Output:

{
  "max_units_per_acre": 12,
  "far": 0.5,
  "max_lot_coverage_pct": 50,
  "max_building_height_ft": 45,
  "min_lot_size_sf": 5000
}

5. zonewise_jurisdiction

Identify jurisdiction from address.

Input:

{
  "address": "123 Ocean Ave, Satellite Beach, FL 32937"
}

Output:

{
  "jurisdiction": "satellite_beach",
  "confidence": 0.95,
  "method": "address_parse"
}

6. zonewise_site_analysis

Comprehensive site feasibility analysis.

Input:

{
  "parcel_id": "12345678",
  "proposed_use": "multi-family",
  "proposed_units": 8
}

Output:

{
  "feasible": true,
  "district": "R-3",
  "max_allowed_units": 12,
  "buildable_area_sf": 15000,
  "constraints": ["Flood zone AE", "Wetland buffer"],
  "approval_path": "by_right"
}

Tool Registration Schema

{
  "tools": [
    {
      "name": "zonewise_lookup",
      "description": "Look up complete zoning district information for Florida properties. Returns permitted uses, setbacks, density limits, and Municode source URL.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "jurisdiction": {
            "type": "string",
            "description": "Municipality name (e.g., 'melbourne', 'palm_bay', 'satellite_beach')"
          },
          "district_code": {
            "type": "string",
            "description": "Zoning district code (e.g., 'R-1A', 'C-2', 'PUD')"
          }
        },
        "required": ["jurisdiction", "district_code"]
      }
    }
  ]
}

Error Handling

class ZoneWiseError(Exception):
    """Base exception for ZoneWise MCP errors."""
    pass

class DistrictNotFoundError(ZoneWiseError):
    """District code not found in jurisdiction."""
    pass

class JurisdictionNotFoundError(ZoneWiseError):
    """Jurisdiction not in coverage area."""
    pass

@mcp.tool()
def zonewise_lookup(jurisdiction: str, district_code: str) -> dict:
    try:
        result = lookup_district(jurisdiction, district_code)
        if not result:
            raise DistrictNotFoundError(
                f"District '{district_code}' not found in {jurisdiction}"
            )
        return result
    except Exception as e:
        return {
            "error": True,
            "error_type": type(e).__name__,
            "message": str(e),
            "suggestion": "Verify district code with local planning department"
        }

Authentication

MCP server supports optional API key authentication:

from fastmcp import FastMCP
from fastmcp.auth import APIKeyAuth

mcp = FastMCP("ZoneWise", auth=APIKeyAuth("ZONEWISE_API_KEY"))

Deployment

Local Development

python -m zonewise_mcp.server
# Server running on stdio

Production (Cloudflare Workers)

npx wrangler deploy

Docker

FROM python:3.11-slim
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["python", "-m", "zonewise_mcp.server"]

Testing

import pytest
from zonewise_mcp.server import zonewise_lookup

def test_lookup_valid_district():
    result = zonewise_lookup("melbourne", "R-1A")
    assert result["district_name"] == "Single-Family Residential"
    assert "permitted_uses" in result

def test_lookup_invalid_district():
    result = zonewise_lookup("melbourne", "INVALID")
    assert result["error"] == True

Rate Limiting

from fastmcp.middleware import RateLimiter

mcp.add_middleware(RateLimiter(
    requests_per_minute=60,
    requests_per_day=1000
))

Logging

All MCP calls logged to Supabase mcp_requests table:

  • Timestamp
  • Tool name
  • Input parameters
  • Response (truncated)
  • Latency
  • Error (if any)

Integration with Claude

Once deployed, add to Claude's MCP configuration:

{
  "mcpServers": {
    "zonewise": {
      "command": "python",
      "args": ["-m", "zonewise_mcp.server"],
      "env": {
        "SUPABASE_URL": "...",
        "SUPABASE_KEY": "..."
      }
    }
  }
}

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon