Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Underground Utility Permit Review Server

БесплатноНе проверен

Provides Claude with read-only access to pending excavation permit reviews and nearby underground utility lines, enabling portfolio-wide risk triage, conflict i

GitHubEmbed

Описание

Provides Claude with read-only access to pending excavation permit reviews and nearby underground utility lines, enabling portfolio-wide risk triage, conflict identification, and verification recommendations. It answers questions like which permits have unverified gas lines within strike range, and summarizes risk by city or recommends potholing priorities.

README

An MCP server that gives Claude direct, read-only access to a portfolio of pending excavation permit reviews and the underground utility lines near each one.

The permit review dashboard answers these questions for a human looking at a screen. This answers them for an agent — same data, same scoring rules, no interface.

Zero dependencies. node server.js is the entire install.


Why build this

A dashboard assumes a person sits down and browses. That works until the question is "across every permit I have open, what's about to hurt someone?" — at which point browsing twenty-four cases is the wrong shape of work.

The interesting shift is that the tools aren't a mirror of the database. There is no "conflicts" table; find_utility_conflicts exists because triage across a portfolio is a real question a reviewer asks and a screen answers badly. Designing the tool boundaries around questions rather than tables is most of the product work here.

What Claude can do with it

You:    Which pending permits have unverified gas lines within 5 feet of the dig?

Claude: [find_utility_conflicts · utility_types=["Gas line"] · max_distance_ft=5]

        Two, and both are high risk:

        Firestone Blvd. & Studebaker Rd. — 2 in gas main, 2.4 ft from the excavation,
        Level D. That's a county record with no independent verification, so the
        position is approximate and the line is well inside strike range.

        Artesia Blvd. & Carpintero Ave. — 2 in gas line at 4 ft, Level C. The county
        record and the independent detection disagree on diameter, so neither can be
        relied on until someone confirms it.

        I'd pothole both before either permit is signed.

Other things it handles well:

  • "Summarise my permit portfolio risk by city."
  • "I have one crew for one day. What should they pothole?"
  • "Walk me through PRM-1001 and tell me what's unresolved."
  • "How much of the county record have we actually corroborated?"

Install

Requires Node 18+. Nothing to npm install.

1. Point Claude Desktop at it. Edit the config file:

  • macOS ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "utility-permits": {
      "command": "node",
      "args": ["/absolute/path/to/utility-mcp-server/server.js"]
    }
  }
}

The path must be absolute — Claude Desktop doesn't run from your project directory.

2. Restart Claude Desktop. Fully quit it; closing the window isn't enough.

3. Confirm. The tools appear in the tool menu. Ask "what permit tools do you have?"

The tools

Tool The question it answers
search_permits Which cases match this filter?
get_permit What's the full review for this one case?
find_utility_conflicts Across everything, what's dangerous to dig near?
portfolio_summary How are we doing overall, and where is risk concentrated?
recommend_verification Given a limited field budget, what do we pothole first?

Every tool is annotated readOnlyHint: true. Nothing here can approve a permit or dispatch a crew. That's a deliberate boundary, not an unfinished feature: an agent that can sign off on an excavation without a human in the loop is a liability, and the fastest way to lose a utility customer's trust is to build one.

Results link back into the dashboard

Every result carries a deep link to the human UI — down to the specific utility line that triggered it:

https://erincheong.github.io/permit-review-dashboard/#permit=PRM-1001&line=4&set=PRM-2008,PRM-1001&label=Gas+lines+within+5+ft

That opens the permit with the offending line already expanded and highlighted, and Back returns to the permits from the query rather than the full portfolio.

The agent is a second door onto the same data, not a replacement for it. It's good at "across everything, what's dangerous." It's bad at "let me see the county record with my own eyes." So it hands off to the thing that's good at that, and remembers where you came from.

Hash routing rather than query strings, so the links also work against a copy opened straight off the filesystem. Point them elsewhere with UTILITY_DASHBOARD_URL.

Provenance travels with every result

Every utility line comes back carrying its ASCE 38-02 quality grade, what that grade means in plain language, and where the record came from. The server's instructions tell the model to keep them attached:

A Level D record is not a known position — it is a decades-old drawing whose source disclaims any guarantee of accuracy, and treating it as fact is how people get hurt.

This matters more for an agent than for a dashboard. A human looking at a red badge infers uncertainty. A model summarising into prose will flatten "county record, unverified, position approximate" into "there's a gas line at 4 feet" unless the data fights back.

One scoring module, two surfaces

src/scoring.js holds the risk rules, and the dashboard uses the same ones. If they diverged, a reviewer and an agent could look at the same permit and disagree about whether it's safe to approve — which is worse than either being wrong alone. The test suite asserts the server's numbers for the shared corridors match what the dashboard displays.

Protocol notes

This is a dual-era server, written directly against the spec rather than an SDK.

MCP changed its negotiation model in revision 2026-07-28: instead of an initialize handshake establishing a session, every request carries its own protocol version in _meta and the server accepts or rejects each one independently. Older clients still open with initialize. This server speaks both:

Client Flow
Modern (2026-07-28) server/discovertools/call with _meta on every request
Legacy (2025-11-25, 2025-06-18) initializenotifications/initializedtools/call

An unsupported version gets UnsupportedProtocolVersionError (-32022) listing what the server does support, so the client can retry instead of guessing.

Transport rule worth knowing: stdio MCP is newline-delimited JSON, and the server must write nothing to stdout that isn't a valid MCP message. A stray console.log corrupts the stream and the server appears to hang — it's the single most common way these break. All logging here goes to stderr, and there's a test asserting stdout stayed clean.

Writing the protocol by hand instead of importing the SDK was a deliberate choice: it's about 250 lines, and it means there's nothing in this repo I can't explain.

Tests

122 checks, run against a real spawned server process speaking actual JSON-RPC over stdio — nothing stubbed.

npm test          # or: node tests/verify_server.js

Covers both handshakes, version rejection, every tool's behaviour and schema conformance, error handling for unknown tools and bad arguments, malformed-JSON resilience, the rule that notifications are never answered, stdout hygiene, determinism across processes, and cross-artifact agreement with the dashboard.

The schema validator is hand-written (~30 lines) so the test suite has no dependencies either.

Data

The first six permit cases are real corridors from the LA County Substructure Grid Map (County of Los Angeles Open Data), carried over verbatim from the dashboard. The other eighteen are synthetic, generated from a fixed seed so the portfolio is big enough for search and filtering to mean something.

Every case carries a dataSource field saying which it is. An agent answering questions about this data should never have to guess whether a record is real — and neither should anyone watching a demo.

Per the county's own disclaimer, it makes no warranty as to the accuracy, timeliness, or completeness of the data, and recommends utility research be conducted under the supervision of a licensed civil engineer. That disclaimer is why county-only records are graded Level D by default.

Known limitations

  • No spatial geometry. Distances are precomputed scalars, not a real GIS layer. A production version sits on PostGIS and takes a bore path, not a permit ID.
  • Read-only by design, so there's no write path to argue about yet. When there is, it should require explicit human confirmation rather than a tool annotation.
  • No auth. stdio means it runs as the local user with their file permissions. A hosted version needs real per-customer access control, since permit and utility data is commercially sensitive and sometimes security-sensitive.
  • Consequence weights are asserted, not derived. Gas at 10× and fiber at 1× is a judgment. In a real deployment those come from the customer's own liability exposure and would differ between a gas utility and a fiber contractor.

from github.com/erincheong/utility-permit-mcp-server

Установка Underground Utility Permit Review Server

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/erincheong/utility-permit-mcp-server

FAQ

Underground Utility Permit Review Server MCP бесплатный?

Да, Underground Utility Permit Review Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Underground Utility Permit Review Server?

Нет, Underground Utility Permit Review Server работает без API-ключей и переменных окружения.

Underground Utility Permit Review Server — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Underground Utility Permit Review Server в Claude Desktop, Claude Code или Cursor?

Открой Underground Utility Permit Review Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Underground Utility Permit Review Server with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории ai