whodoicallfor-mcp
MCP server that helps users identify which trade to call during home emergencies by analyzing natural-language problem descriptions and providing ranked matches with costs, sources, and dispatch lines.
README
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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。