Quickstart
Three ways in, from least to most setup. All of them are public and unauthenticated.
1. MCP client
Point any MCP client at https://chicagostormpros.com/mcp. The transport is Streamable HTTP, stateless, JSON responses, protocol versions 2025-06-18, 2025-03-26, and 2024-11-05. In Claude Code:
claude mcp add --transport http storm-pros https://chicagostormpros.com/mcp 2. Raw JSON-RPC over HTTP
No MCP library required. This lists the tools:
curl -s https://chicagostormpros.com/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' And this validates a booking without creating one:
curl -s https://chicagostormpros.com/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
"name":"book_free_inspection",
"arguments":{
"name":"Jane Doe",
"phone":"630-555-0139",
"address":"12 Elm St, Naperville IL",
"dry_run":true
}}}' 3. Command line
A zero-dependency Node client, one file, Node 18 or newer:
curl -fsSL https://chicagostormpros.com/cli/storm-pros.mjs -o storm-pros.mjs
node storm-pros.mjs area "DuPage"
node storm-pros.mjs storms
node storm-pros.mjs page /hail-damage/
node storm-pros.mjs book --name "Jane Doe" --phone "630-555-0139" \
--address "12 Elm St, Naperville IL" --dry-run Add --json to any command for the raw MCP result. The CLI readme has the full command list, and the package manifest describes the npm package.
Tools
| Tool | Arguments | What it does |
|---|---|---|
| book_free_inspection | name, phone, address, [email], [damage_description], [dry_run] | Books a free storm damage roof inspection for a Chicagoland homeowner. The scheduling team calls within 2 hours during business hours. Requires the homeowner's consent and their own callback number. |
| check_service_area | location | Answers whether an Illinois county or community is served, and returns the local page URL plus its markdown twin when one exists. |
| get_recent_storm_events | none | Returns NWS-verified Chicagoland storm events with dates, affected communities, and the insurance claim filing deadline each one carries. |
| get_decision_guides | none | Returns the decision guide index as markdown: who to hire, whether to file, what it costs, damage by roof type, and special situations. |
| get_claim_situation_help | situation, [carrier] | Claim-problem triage. Situations: denied, underpaid, adjuster_no_damage, deadline_approaching, not_yet_filed, estimate_confusing, contractor_pressure. Returns what it means, what C&N can and cannot do under Illinois law, the matching guide, and the next step. Optional carrier adds the carrier-specific claim guide. |
| get_company_credentials | none | The company's Illinois roofing license, certifications, BBB status, Google rating and review count, awards, and independent verification links in one call. Backed by /data/organization.json. |
The Sandbox
Pass dry_run: true to book_free_inspection. The gateway runs the identical validation chain a real booking runs, required fields, phone normalization, the firm-number rejection, and the fake-number check, then returns the exact payload it would have submitted and stops there. No lead is created, nobody is contacted, and the call does not spend your booking rate limit.
There is no separate sandbox host and no test credential to request, because the only difference between test and production here is whether a human gets a phone call.
The Consent Rule
Book only with the homeowner's knowledge and consent, using their real name and their own callback number. Never use a phone number found on this site: the gateway rejects all four of them outright, because a number printed on a roofing company's website is never the homeowner's number. That check exists because an agent filling a required phone field from the nearest number in its own context is a real failure mode, not a hypothetical one.
Rate Limits And Errors
- Bookings: five per IP address per hour. Dry runs are unlimited and do not count.
- Reads: unmetered. Pages, markdown twins, and the JSON datasets are static files.
- Errors: tool-level failures come back as a normal JSON-RPC result with
isError: trueand a plain-English explanation of what to fix. Protocol-level failures come back as JSON-RPC errors. - Method not allowed:
GET /mcpreturns 405 with a JSON description of the endpoint. There is no server-initiated event stream. - CORS: open, so browser-based clients work without a proxy.
Reading The Site As Markdown
Every page has a markdown twin. There are two ways to get it, and they return the same bytes:
curl -s https://chicagostormpros.com/hail-damage/index.md
curl -s -H 'Accept: text/markdown' https://chicagostormpros.com/hail-damage/ Negotiated responses carry Vary: Accept, Accept-Encoding, so an intermediate cache cannot hand your agent the HTML variant. Every page also advertises its twin in a Link header and a <link rel="alternate" type="text/markdown"> tag. A path that does not exist returns a real 404 with a short markdown body listing where to look next, so a 200 from this origin always means the page is real.
Discovery Files
| Path | Contents |
|---|---|
| /llms.txt text/markdown | Site overview, when to use this site, and the full page index |
| /llms-full.txt text/markdown | Every high-value page inlined as one document, rebuilt on each deploy |
| /agent-instructions.md text/markdown | When to reach for this site and how to call it |
| /.well-known/api-catalog application/linkset+json | RFC 9727 linkset of every machine-readable entry point |
| /.well-known/mcp.json application/json | MCP server declaration |
| /.well-known/mcp/server-card.json application/json | MCP server card |
| /.well-known/agent-skills/index.json application/json | Agent Skills discovery index with sha256 digests |
| /.well-known/agent-skills/request-free-inspection/SKILL.md text/markdown | The plain-HTTP booking recipe, no MCP client needed |
| /sitemap.xml application/xml | Every canonical URL |
| /data/storm-events.json application/json | The storm event dataset behind the storm map and the MCP tool |
| /data/organization.json application/json | The Organization identity node as standalone JSON: license, credentials, ratings, profiles. Regenerated from the homepage JSON-LD on every build |
| /robots.txt text/plain | Crawl rules plus Content-Signal terms (search, ai-input, and ai-train are all yes) |
In-Browser Tools (WebMCP)
Every page registers browser-side tools through navigator.modelContext.provideContext(): request_free_inspection, check_service_area, and get_recent_storm_events. An agent operating inside a browser session can call them without leaving the page, and they deliver into the same lead pipeline as the server-side gateway.
Structured Data
Every page carries JSON-LD: a RoofingContractor and Organization node with address, contact points, licensing, credentials, and sameAs profiles; a WebSite node; a WebPage node with a build timestamp; plus BreadcrumbList, FAQPage, HowTo, ItemList, and VideoObject where those apply. The organization node is stable at https://chicagostormpros.com/#organization, so it can be referenced rather than re-parsed.
Support
Email info@cnroofs.com or call (630) 414-9160 and say it is about the agent API. For what this site is and who runs it, see about; for how submitted data is handled, see the privacy policy.