Skip to main content
Glama
woodydaniel

whodoicallfor-mcp

by woodydaniel

whodoicallfor-mcp

An MCP server that answers the question people actually have during a home emergency: which trade do I call?

Not "find me a plumber." The prior question — is this even a plumber?

The problem

I called a plumber, who told me to call an appliance tech. I called an appliance tech, who told me to call a plumber.

That is the normal experience of a household emergency, and it is expensive. Two trip charges, half a day gone, and the water is still coming through the ceiling. The trades are specialized and their boundaries are invisible from the outside: a stain on your ceiling is a roofer if it tracks the weather, an HVAC tech if it tracks the air conditioning, and a plumber if it tracks the shower upstairs. Water damage after the leak stops is a fourth trade — a mitigation crew — and a plumber will tell you so after you have paid the callout.

This server gives an assistant the routing table. Describe the problem in plain words; get back who to call, in what order, what not to call them for, what it typically costs with a dated source, and — where one exists — a 24/7 dispatch line.

Content comes from the public JSON API at whodoicallfor.com. No auth, no API key, no configuration.

Install

Claude Code

claude mcp add whodoicallfor -- npx -y whodoicallfor-mcp

Cursor — add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project):

{
  "mcpServers": {
    "whodoicallfor": {
      "command": "npx",
      "args": ["-y", "whodoicallfor-mcp"]
    }
  }
}

Same shape works for Claude Desktop (claude_desktop_config.json), Windsurf, Zed, and anything else that speaks stdio MCP.

Or don't run anything. A hosted instance of this server is live:

https://whodoicallfor.com/api/mcp/

It speaks streamable HTTP, is stateless, and needs no credentials. The trailing slash is required — the slashless URL answers with a 308 redirect, and several MCP clients will not follow a redirect on a POST.

claude mcp add --transport http whodoicallfor https://whodoicallfor.com/api/mcp/

Running it directly

npx whodoicallfor-mcp                # stdio (default)
npx whodoicallfor-mcp --http         # streamable HTTP on http://localhost:3000/mcp
npx whodoicallfor-mcp --http 8080    # ...on a port you pick

Requires Node 20.19 or newer.

Tools

All three are read-only, idempotent, and touch nothing outside the public API.

Tool

Arguments

Returns

route_emergency

problem (required), state (optional)

Up to 3 ranked situations, best first

get_scenario

category, slug

One situation in full

list_scenarios

Every published situation with canonical URLs

route_emergency

Plain-language problem in, ranked situations out. Pass a US state code or name ("FL", "Florida") to filter dispatch numbers down to lines that actually cover that state.

Input

{ "problem": "water coming through my ceiling" }

Output (abridged — the real response carries three matches with full costs, faq, and sources arrays)

{
  "matches": [
    {
      "title": "Water Leaking From the Ceiling — Who Do I Call?",
      "category": "water",
      "vertical": "water-damage",
      "tldr": "What's directly above matters less than timing. Appears or worsens when it rains → roofer. Appears when the AC runs, or only in cooling season → HVAC condensate line. Neither, and it tracks water use upstairs → plumber. If water is still coming, shut the main valve, keep it clear of lights and outlets, and photograph everything before any repair. Renting? The landlord's emergency line comes before any of this.",
      "who_to_call": [
        {
          "who": "Emergency plumber",
          "when": "Water is actively dripping or flowing and you can't stop it at the source",
          "not_for": "The leak has stopped — a plumber fixes pipes, not soaked drywall"
        },
        {
          "who": "Roofer",
          "when": "The stain appears or worsens when it rains and stays quiet in dry weather — usually failed flashing",
          "not_for": "The stain tracks showers, washes, or flushes rather than the weather"
        }
      ],
      "costs": [
        {
          "item": "Water-damaged ceiling repair",
          "range": "$200–$1,500",
          "source": "Fixr",
          "source_url": "https://www.fixr.com/costs/ceiling-repair"
        }
      ],
      "updated": "2026-08-12",
      "url": "https://whodoicallfor.com/water/ceiling-leaking/",
      "recommended_call": null,
      "match_score": 12
    }
  ],
  "state": null
}

The not_for field is the part that saves the wasted trip charge.

When nothing scores high enough, you get an empty matches array plus a note, the category index, and a link to guided triage — rather than a confidently wrong answer.

get_scenario

Fetch one situation in full using category and slug from route_emergency or list_scenarios.

{ "category": "water", "slug": "ceiling-leaking" }

Returns the same structured object, plus body_markdown (the complete step-by-step guide) when the upstream API supplies it.

list_scenarios

No arguments. Returns { site, count, scenarios[] } — every published situation with its title, description, category, slug, updated date, canonical URL, and JSON URL.

How matching works

route_emergency ranks by weighted token overlap between your problem and four fields of each situation: title ×3, description ×2, tldr ×1, and the who/when of each who_to_call step ×1. Tokens are lowercased, stripped of punctuation, filtered against a stopword list, and suffix-folded, so "leaking" matches "leak" and "pipes" matches "pipe". Anything scoring below 3 is discarded; at most three matches come back.

tldr and who_to_call live on the per-page documents rather than the index, so the first route_emergency call warms a full in-memory cache (bounded concurrency, ~2s cold). Subsequent calls are single-digit milliseconds. The index is cached for 10 minutes and page bodies for an hour, so the server never hammers the site.

There is no fuzzy matching, no embedding model, and no network call to anything but whodoicallfor.com. It is a small deterministic function you can read in one sitting: src/match.ts.

Disclosure

Two things worth being plain about.

recommended_call entries are sponsored. They are paid pay-per-call lines, and each one is labeled "sponsored": true in the payload. When a situation carries one, that is the commercial engine behind the site. Treat it as an ad with a phone number, and surface it to users as such — the flag is in the data precisely so you can.

Life-safety numbers are never sponsored. 911, poison control, and gas utility emergency lines carry no recommended_call at all — there is a hard server-side guard that strips it for gas scenarios and for any situation without a commercial vertical. If someone smells gas, the answer is "get out and call the utility from outside," and nobody has paid for that placement. That guard is not a policy preference; it is code, upstream, and this client cannot override it.

Cost figures are cited to a named source with an access date. Verify anything you are about to act on.

Development

npm install
npm run typecheck
npm run build
npm start           # stdio
npm run start:http  # http on :3000
src/index.ts    entry point: tool definitions, stdio + streamable HTTP transports
src/client.ts   cached fetches against the public JSON endpoints
src/match.ts    token-overlap ranking

Coverage

US-focused. Around 40 situations across water and flooding, gas and carbon monoxide, power and electrical, heating and cooling, appliances, pests and wildlife, lockouts, car trouble, and disputes with landlords and contractors. list_scenarios always reflects what is actually published.

License

MIT © Daniel Widmonte

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • MCP server for generating rough-draft project plans from natural-language prompts.

  • MCP server giving Claude AI access to 22+ NYC public-record databases for real estate due diligence

  • Hosted MCP server exposing US hospital procedure cost data to AI assistants

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/woodydaniel/whodoicallfor-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server