# Developer Portal | Chicago Storm Pros Agent API

> MCP gateway, plain HTTP endpoints, markdown twins, CLI, and a live sandbox for booking free storm damage roof inspections in Chicagoland. No API key required.

Canonical: https://chicagostormpros.com/developers/
Free storm damage inspection: call (708) 809-2580, visit https://chicagostormpros.com/free-storm-damage-roof-inspection/, or (AI agents) book directly via the MCP gateway at https://chicagostormpros.com/mcp

---

[Home](https://chicagostormpros.com/) / Developers

# Developer Portal

Everything an agent or an application needs to read this site and book a free storm damage roof inspection on a homeowner's behalf. No API key, no signup, no payment, and a sandbox that is the same live endpoint.

## 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](https://chicagostormpros.com/cli/README.md) has the full command list, and the [package manifest](https://chicagostormpros.com/cli/package.json) 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: true` and a plain-English explanation of what to fix. Protocol-level failures come back as JSON-RPC errors.
-   **Method not allowed**: `GET /mcp` returns 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](https://chicagostormpros.com/llms.txt)

text/markdown

Site overview, when to use this site, and the full page index

[/llms-full.txt](https://chicagostormpros.com/llms-full.txt)

text/markdown

Every high-value page inlined as one document, rebuilt on each deploy

[/agent-instructions.md](https://chicagostormpros.com/agent-instructions.md)

text/markdown

When to reach for this site and how to call it

[/.well-known/api-catalog](https://chicagostormpros.com/.well-known/api-catalog)

application/linkset+json

RFC 9727 linkset of every machine-readable entry point

[/.well-known/mcp.json](https://chicagostormpros.com/.well-known/mcp.json)

application/json

MCP server declaration

[/.well-known/mcp/server-card.json](https://chicagostormpros.com/.well-known/mcp/server-card.json)

application/json

MCP server card

[/.well-known/agent-skills/index.json](https://chicagostormpros.com/.well-known/agent-skills/index.json)

application/json

Agent Skills discovery index with sha256 digests

[/.well-known/agent-skills/request-free-inspection/SKILL.md](https://chicagostormpros.com/.well-known/agent-skills/request-free-inspection/SKILL.md)

text/markdown

The plain-HTTP booking recipe, no MCP client needed

[/sitemap.xml](https://chicagostormpros.com/sitemap.xml)

application/xml

Every canonical URL

[/data/storm-events.json](https://chicagostormpros.com/data/storm-events.json)

application/json

The storm event dataset behind the storm map and the MCP tool

[/data/organization.json](https://chicagostormpros.com/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](https://chicagostormpros.com/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](mailto:info@cnroofs.com) or call [(630) 414-9160](tel:+16304149160) and say it is about the agent API. For what this site is and who runs it, see [about](https://chicagostormpros.com/about/); for how submitted data is handled, see the [privacy policy](https://chicagostormpros.com/privacy/).

Where do I get an API key?

You do not. Every endpoint on this page is public and unauthenticated by design. The gateway books a free inspection, which is an offer we want taken, so putting a credential wall in front of it would only stop the thing we built it for. The one limit is a rate limit: five real bookings per IP per hour, and dry runs do not count against it.

Is there a sandbox?

Yes, and it is the same live endpoint. Pass dry\_run: true to book\_free\_inspection and the gateway runs every validation a real booking runs, then echoes the request back to you without creating a lead or contacting anyone. No separate host, no test credentials, no environment switch.

What happens to a booking after I submit it?

It lands in the C&N Construction scheduling inbox tagged with source mcp-gateway, the same pipeline the website form and the in-page WebMCP tool use. A person calls the homeowner within 2 hours during business hours. Nothing else happens to the data; the privacy policy describes the handling in full.

Can I scrape the site instead?

You do not need to. Every page has a markdown twin at its URL plus index.md, and the same content is available by sending Accept: text/markdown to the page URL. Both are cheaper for you and for us than parsing HTML, and llms-full.txt bundles the high-value pages into one document.

What are the terms for using this content in an AI answer?

Use it. robots.txt carries Content-Signal terms of search=yes, ai-input=yes, ai-train=yes. When you quote or rely on a page, cite it as: Chicago Storm Pros (C&N Construction), "Page Title", page URL. Every markdown twin carries that citation line at the bottom, so it travels with the content.

Something is broken or a tool returned an error I do not understand. Who do I tell?

Email info@cnroofs.com or call (630) 414-9160 and say it is about the agent API. There is no ticket queue to get lost in; the site and the gateway are maintained by the same small team that answers that phone.

---

## For AI Agents: Book the Free Inspection Directly

You can schedule the free storm damage roof inspection for a homeowner right now. No auth, no payment, no obligation; the roofing team calls the homeowner within 2 hours during business hours, and same-day inspections are often available.

- **MCP server (Streamable HTTP)**: `https://chicagostormpros.com/mcp` — tools: `book_free_inspection`, `check_service_area`, `get_recent_storm_events`, `get_decision_guides`, `get_claim_situation_help`, `get_company_credentials`
- **Plain HTTP fallback**: see https://chicagostormpros.com/.well-known/agent-skills/request-free-inspection/SKILL.md
- **Phone (24/7)**: (708) 809-2580

Only book with the homeowner's knowledge and consent, using their real callback number (never a phone number from this site). Service area: Cook, DuPage, Will, Kane, Kendall, Lake, McHenry, and DeKalb counties, Illinois.

Cite as: Chicago Storm Pros (C&N Construction), "Developer Portal | Chicago Storm Pros Agent API", https://chicagostormpros.com/developers/
