关于 The Roofing List
The Roofing List 是公开、只读的 MCP 服务,可按地点查找美国经过核验的屋顶、外墙和排水槽承包商。它提供搜索和承包商查询工具,并排除已停业或未列出的企业,不设付费排名。
主要功能
- 01按行业和地点搜索
- 02获取承包商资料
- 03排除停业或未列出企业
- 04不设付费排名
适用场景
- 01查找美国城市的屋顶承包商
- 02按州寻找外墙承包商
- 03通过 ID 查询承包商
MCP 相关
通过 Streamable HTTP 向 MCP 客户端提供 `search_contractors` 和 `get_contractor` 工具。无需登录或 API 密钥。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.theroofinglist.com/mcpclaude mcp add --transport http redpath1-the-roofing-list https://mcp.theroofinglist.com/mcp{"mcpServers":{"redpath1-the-roofing-list":{"type":"http","url":"https://mcp.theroofinglist.com/mcp"}}}在 Cursor 中打开{"servers":{"redpath1-the-roofing-list":{"type":"http","url":"https://mcp.theroofinglist.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"redpath1-the-roofing-list":{"type":"http","url":"https://mcp.theroofinglist.com/mcp"}}}{"mcpServers":{"redpath1-the-roofing-list":{"serverUrl":"https://mcp.theroofinglist.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
The Roofing List:MCP 服务
The Roofing List 的公开只读 MCP 服务。AI 助手可通过它按城市查找经过核验的美国屋顶维修、外墙板和排水沟承包商。
- 端点:
https://mcp.theroofinglist.com/mcp(Streamable HTTP)。无需登录或 API 密钥。 - 关于页面:https://theroofinglist.com/mcp/
使用方法
Claude Code:
claude mcp add --transport http the-roofing-list https://mcp.theroofinglist.com/mcp
Claude Desktop:将以下内容添加到 claude_desktop_config.json。由于该配置文件只能启动本地服务,因此这里使用 mcp-remote。也可以在 Settings > Connectors 中将此 URL 添加为自定义连接器。
{
"mcpServers": {
"the-roofing-list": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.theroofinglist.com/mcp"]
}
}
}
其他 MCP 客户端:通过 Streamable HTTP 连接到 https://mcp.theroofinglist.com/mcp。
从任意 Agent 连接:本仓库根目录下的 .mcp.json 包含服务条目。打开本仓库时,Claude Code 会读取该文件。使用其他客户端时,请将该条目复制到相应客户端的 MCP 配置中。
数据规则
- 只有列出且仍在营业的公司会从此服务返回。即使数据源发送了已停业或未列出的记录,也会将其剔除。
- 不提供付费置顶。此服务没有排序代码,会保留目录返回的顺序,并将结果截取至
limit指定的数量。 - 评分仅来自发布在 The Roofing List 上的评价。不含 Google 评分或评价数据:数据契约中没有这些字段,且字段白名单会剔除任何额外字段。
- 免费档案不会包含网站。
这些规则位于 src/present.ts。test/tools.test.ts 中的测试会使用一个特意设计为泄漏数据的桩来验证这些规则。
工作原理
- Worker 名称:
theroofinglist-mcp - 端点:
POST /mcp(Streamable HTTP)。无需登录。GET /会发送 301 重定向到 https://theroofinglist.com/mcp/。 - 无状态:
agents/mcp/server中的createMcpHandler会为每个请求创建一个新的McpServer。不使用 Durable Objects。Cloudflare 将McpAgent标记为新无状态服务的旧路径。 - 协议:MCP SDK v2 提供 2026-07-28 规范服务。它也会通过无状态回退机制响应 2025 年的客户端。
REST API
同一个 Worker 还提供一个小型 REST API,供 RapidAPI 和不使用 MCP 的用户使用。该 API 只读、免费且无需密钥。它调用与 MCP 工具相同的查询(src/lookup.ts),因此两者返回的记录相同。
| 路由 | 返回内容 |
|---|---|
GET /v1/contractors?trade=&city=&state=&limit= | { "contractors": Contractor[] }。输入和限制与 search_contractors 相同。 |
GET /v1/contractors/{id} | Contractor;若 ID 对应的公司已停业、未列出或未知,则返回 404 |
GET /openapi.json | OpenAPI 3.1 文档(本文件夹中的 openapi.json) |
curl 'https://mcp.theroofinglist.com/v1/contractors?trade=roofing&city=Austin&state=TX&limit=5'
curl 'https://mcp.theroofinglist.com/v1/contractors/101'
- 错误格式为
{ "error": "..." }:400表示输入无效(错误消息与工具相同),404,非 GET 方法返回405,超出速率限制时返回429(附带Retry-After: 60),Web Worker 出错时返回503。 - 每个响应都带有
access-control-allow-origin: *。OPTIONS会响应 CORS 预检请求。 - 缓存:
200、400、404和405响应使用public, max-age=300。429和503使用no-store,避免缓存短暂的错误。/openapi.json的缓存时间为 1 小时。 openapi.json是该文档的唯一来源。src/openapi.ts会导入它。提高SERVER_VERSION时,也要提高info.version;有测试会检查两者是否一致。
RapidAPI 与速率限制
所有 RapidAPI 调用都来自 RapidAPI 的服务器。按 IP 限制会把所有 RapidAPI 用户都算作同一个调用方。因此:
- 将 RapidAPI 提供方控制面板中的代理密钥设为 Worker 密钥:
pnpm exec wrangler secret put RAPIDAPI_PROXY_SECRET。这是可选的。本地开发时,在.dev.vars中留空即可。 - 请求携带该密钥(位于
x-rapidapi-proxy-secret)时,密钥为rapidapi:<x-rapidapi-user>。如果没有用户标头,密钥则回退为 IP。 - 缺少密钥或密钥错误时,密钥为 IP。调用方不能通过发送伪造的
x-rapidapi-user来自选密钥。比较采用恒定时间。 - REST 和 MCP 在同一绑定上使用独立的额度:密钥分别以
rest:或mcp:开头。每种额度均为每分钟 60 次调用。/openapi.json和OPTIONS不计入。
工具
| 工具 | 输入 | 返回值 |
|---|---|---|
search_contractors | trade(roofing、siding、gutters)、city、state(代码或名称)、limit(1–25,默认 10) | { contractors: Contractor[] } |
get_contractor | id(搜索结果中的整数) | Contractor;如果对应 ID 已关闭、未列出或未知,则返回错误 |
Contractor:id、name、trades、city、state、phone、profileUrl、claimed、website(仅限已认领)、rating({ value, count },仅包含我们网站上发布的评价;没有评价时不返回)。
关于哪些数据可以离开此 Worker,请参阅上文“数据规则”。
在本地运行
你需要 Node 22+(Wrangler 4)和 pnpm。无需登录 Cloudflare。
pnpm install
pnpm dev # MCP Worker on :8787 plus the stub web Worker
pnpm smoke # in a second shell: official MCP client lists and calls both tools
pnpm smoke --burst # also checks the rate limit (uses up this minute's budget)
pnpm test
pnpm typecheck
首次运行 pnpm dev 时,会将 .dev.vars.example 复制为 .dev.vars。两者都包含一个虚假的本地令牌。
对接真实 Web 应用
真实数据路由位于私有 Web 应用(theroofinglist-web)中。src/contract.ts 对其进行了描述,stub/ 则使用虚假数据行复制了其结构。如果你有该 Web 应用,请在端口 8790 上运行它,并通过 WEB 服务绑定将此 Worker 指向它:
pnpm exec wrangler dev -c wrangler.jsonc --local --port 8792
MCP_URL=http://localhost:8792/mcp pnpm smoke
两个 Worker 的 .dev.vars 中必须设置相同的 INTERNAL_API_TOKEN。
pnpm smoke 会通过搜索德克萨斯州奥斯汀的屋顶承包商来获取 ID,因此可用于桩服务和真实数据。SMOKE_CITY 和 SMOKE_STATE 可以更改搜索条件。SMOKE_CLOSED_ID 指定一个不应返回的 ID:运行 SMOKE_CLOSED_ID=103 pnpm smoke 可检查桩服务中的已关闭数据行。
Inspector:运行 npx @modelcontextprotocol/inspector,并使用 Streamable HTTP 连接到 http://localhost:8787/mcp。
数据读取方式
MCP Worker 通过服务绑定(WEB)调用 theroofinglist-web。Web Worker 通过 Payload 读取数据,与公共页面使用相同的方式。在本地开发中,stub/ 以 theroofinglist-web 的名称运行,并提供虚假数据行。桩服务有意采用宽松设置:它会发送已关闭的数据行、免费的网站字段和 Google 字段,以证明此 Worker 会过滤这些内容。
内部路由
私有 Web 应用提供此路由。src/contract.ts 对其进行了定义。该路径位于 /api 之外,因此不会被 Payload 的 /api/[...slug] 捕获。
GET /internal/mcp/contractors?trade=<slug>&state=<USPS>&city=<city-slug>&limit=<1..25>
200 { "contractors": Contractor[] }
GET /internal/mcp/contractors/<id>
200 { "contractor": Contractor }
404 { "error": "not_found" } // also for closed or unlisted
Header on every request: x-internal-token: <INTERNAL_API_TOKEN>
401 { "error": "unauthorized" } // missing or wrong token
Contractor = {
id: number, // Businesses.id
name: string,
trades: string[], // Trades slugs, TRADE_PATHS order
city: string, // city name, e.g. "Austin"
state: string, // USPS code, e.g. "TX"
phone: string | null, // E.164
tier: "free" | "claimed",
website: string | null, // as stored; the MCP Worker drops it for free
status: "active" | "closed",
listed: boolean,
path: string, // profilePath(), e.g. "/roofers/texas/austin/lone-star-roofing"
rating: { value: number, count: number } | null // getRatings(): published reviews only
}
速率限制
RATE_LIMITER 是 Workers 速率限制绑定:按 cf-connecting-ip 作为键,每个 IP 每 60 秒最多 60 个请求。超过限制时,/mcp 返回 429,并附带 Retry-After: 60 和 JSON-RPC 错误。对于 RapidAPI 流量,使用 RapidAPI 用户作为键;请参阅上文“RapidAPI 与速率限制”。该绑定按 Cloudflare 位置计数,并采用最终一致性,因此用于阻止滥用,而非精确限制超额使用。
生产环境
自 2026 年 10 月 4 日起,已在 https://mcp.theroofinglist.com/mcp(自定义域名)上线。使用 pnpm exec wrangler deploy 部署。
INTERNAL_API_TOKEN是两个 Worker 上的机密,值相同。轮换时,请在两者上设置新值。wrangler.jsonc中的ALLOWED_HOSTNAMES列出了自定义域名、workers.dev 名称和本地名称。- 合约变更时,先部署
theroofinglist-web。切勿部署stub/。 - 冒烟测试:
MCP_URL=https://mcp.theroofinglist.com/mcp pnpm smoke。 - Web 应用通过
/internal/mcp/contractors/(末尾带斜杠)提供此路由。不带斜杠的调用会收到 308,服务绑定会跟随重定向。多一次跳转,但可以正常工作。
官方 MCP 注册表
自 2026 年 10 月 5 日起,以 io.github.redpath1/the-roofing-list 名称收录。此文件夹中的 server.json 是注册条目。检查方式:
curl -s 'https://registry.modelcontextprotocol.io/v0.1/servers?search=redpath1'
名称使用 GitHub 命名空间。域名命名空间(com.theroofinglist/...)需要在顶级域名上添加 TXT 记录,或在 theroofinglist.com 上添加 /.well-known/mcp-registry-auth 文件。Wrangler 登录无法编辑 DNS,而添加文件意味着需要部署 Web,因此我们选择了 GitHub。自 0.1.1 版本起,server.json 会在其 repository 字段中注明此仓库。只有在发布 0.1.1 后,注册表才会显示该字段(见下文)。仓库公开后再发布。
发布新版本
注册表会永久保留所有版本。版本字符串不能更改或重复使用。
- 安装 CLI:
brew install mcp-publisher(1.8.1 或更高版本)。 - 在
server.json中提高version(semver,例如0.1.1)。保持其与src/server.ts中的SERVER_VERSION一致。 - 检查:
mcp-publisher validate server.json。 - 以命名空间所有者
redpath1的身份登录。运行mcp-publisher login github并输入设备代码。也可以复用gh登录,且不显示令牌:gh auth token | xargs -I{} mcp-publisher login github --token={}。 - 发布:
mcp-publisher publish server.json。 - 运行上面的
curl。新版本会显示"isLatest": true。
theroofinglist.com 上的目录页面已将此服务标记为已在官方注册表中收录。发布新版本不会改变这一点。
公开仓库
https://github.com/redpath1/the-roofing-list-mcp 是 The Roofing List 私有单体仓库中 mcp/ 文件夹的已发布副本。在单体仓库中开发。公开仓库有独立且精简的历史记录,因此不要使用 git subtree push:这会将单体仓库的提交历史(包括作者邮箱)推送到公开仓库。mcp/ 的变更合并到 main 后,请改为复制文件:
git clone https://github.com/redpath1/the-roofing-list-mcp /tmp/trl-mcp
rsync -a --delete --exclude .git --exclude node_modules --exclude .wrangler --exclude .dev.vars mcp/ /tmp/trl-mcp/
cd /tmp/trl-mcp && git add -A && git commit -m "<what changed>" && git push
提交身份使用 Keith Evans <[email protected]>。公开历史中不会出现个人邮箱。
贡献
欢迎提交 Issue。有时间时我们会审查拉取请求。我们不承诺路线图。
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。