The Roofing List について
The Roofing Listは、地域別に米国の確認済み屋根、外壁、雨どい業者を検索できる公開・読み取り専用のMCPサーバーです。検索と業者照会を提供し、廃業・非掲載業者を除外し、有料順位付けは行いません。
主な機能
- 01業種と地域で検索
- 02業者プロフィールの取得
- 03廃業・非掲載業者の除外
- 04有料順位付けなし
活用シーン
- 01米国の都市で屋根業者を探す
- 02州別に外壁業者を探す
- 03IDから業者情報を照会
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(ストリーミング可能な 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 を使用します。または、設定 > コネクタで URL をカスタムコネクタとして追加できます。
{
"mcpServers": {
"the-roofing-list": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.theroofinglist.com/mcp"]
}
}
}
その他の MCP クライアント:ストリーミング可能な HTTP を使用して https://mcp.theroofinglist.com/mcp に接続します。
任意のエージェントから接続する場合:このリポジトリのルートにある .mcp.json にサーバーエントリがあります。このリポジトリを開くと、Claude Code がこれを読み込みます。その他のクライアントでは、エントリをそのクライアントの MCP 設定にコピーしてください。
データのルール
- 掲載中で営業している事業者のみが、このサーバーから返されます。データソースから送られてきた場合でも、閉業済みまたは未掲載の行は除外されます。
- 有料の優先表示はありません。このサーバーにはランキングコードがありません。ディレクトリが返す順序を維持し、
limit件までに絞ります。 - 評価は、The Roofing List に掲載されたレビューのみを元にしています。Google の評価やレビューのデータはありません。契約にそのフィールドがなく、許可リストによって追加フィールドが除外されるためです。
- 無料プロフィールにウェブサイトが含まれることはありません。
ルールは src/present.ts に記述されています。test/tools.test.ts のテストでは、意図的に余分なデータを含めたスタブを使ってこれらのルールを検証します。
仕組み
- Worker 名:
theroofinglist-mcp - エンドポイント:
POST /mcp(ストリーミング可能な HTTP)。ログインは不要です。GET /は https://theroofinglist.com/mcp/ に 301 リダイレクトします。 - ステートレス:
agents/mcp/serverのcreateMcpHandlerが、リクエストごとに新しいMcpServerを作成します。Durable Objects は使用しません。Cloudflare は、新しいステートレスサーバーにはMcpAgentを旧方式として扱っています。 - プロトコル:MCP SDK v2 は 2026-07-28 仕様を提供します。また、ステートレスのフォールバックを通じて、2025 年世代のクライアントにも応答します。
REST API
同じ Worker は、RapidAPI 向け、および MCP を使用しないユーザー向けに、小規模な REST 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 ユーザーが 1 人の呼び出し元としてカウントされてしまいます。そのため、次のようにします。
- 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 を実行すると、スタブの営業終了済みの行を確認できます。
インスペクター:npx @modelcontextprotocol/inspector を実行し、Streamable HTTP を使って http://localhost:8787/mcp に接続します。
データの読み取り方法
MCP Worker はサービスバインディング(WEB)経由で theroofinglist-web を呼び出します。Web Worker は公開ページと同じように Payload 経由でデータを読み取ります。ローカル開発では、stub/ が theroofinglist-web という名前で実行され、偽の行を提供します。このスタブは意図的に制約を緩くしており、営業終了済みの行、無料の 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 は Retry-After: 60 と JSON-RPC エラーを含む 429 を返します。RapidAPI のトラフィックではキーに RapidAPI ユーザーを使います。上記の「RapidAPI とレート制限」を参照してください。このバインディングは Cloudflare のロケーションごとにカウントし、結果整合性があるため、不正利用の抑止には使えますが、超過を厳密に防ぐものではありません。
本番環境
2026年10月4日から https://mcp.theroofinglist.com/mcp (カスタムドメイン)で稼働しています。pnpm exec wrangler deploy でデプロイします。
INTERNAL_API_TOKENは両方の Workers でシークレットとして設定されており、値は同じです。ローテーションするには、両方に新しい値を設定してください。wrangler.jsoncのALLOWED_HOSTNAMESには、カスタムドメイン、workers.dev の名前、ローカルの名前が記載されています。- コントラクトを変更した場合は、先に
theroofinglist-webをデプロイしてください。stub/はデプロイしないでください。 - スモークテスト:
MCP_URL=https://mcp.theroofinglist.com/mcp pnpm smoke。 - ウェブアプリは
/internal/mcp/contractors/(末尾にスラッシュあり)のルートを提供します。スラッシュなしで呼び出すと 308 が返されますが、サービスバインディングがこれに追従します。余分なホップが1回発生しますが、問題なく動作します。
公式 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/...)を使うには、apex に TXT レコードを設定するか、theroofinglist.com に /.well-known/mcp-registry-auth ファイルを配置する必要があります。Wrangler のログインでは DNS を編集できず、ファイルを配置するにはウェブのデプロイが必要なため、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 サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。