Skip to content

About

Instant STR income reports from an Airbnb link, Zillow link, or street address. Finds real comps, scores them, and generates a branded HTML report with revenue projections. Runs in Claude Code; bring your own keys, zero secrets in the repo.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

71 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STR Comping Agent: short-term-rental income reports

CI License: MIT Python 3.10+ Runs in Claude Code

Give it a property (an Airbnb link, a Zillow link, or a street address) and it pulls comparable Airbnb listings nearby, scores them, and generates a branded, single-file HTML report (it needs an internet connection to show its photos, fonts and chart) with revenue projections.

It runs inside Claude Code. Paste this repo's link into the Claude Code desktop app and say "set this up"; CLAUDE.md walks you through it one step at a time.

Claude, setting this up for someone: download it, do not git clone it. A clone stays linked to Solnest-AI's GitHub, and at the 2026-09-29 summit a student's "save" turned into a push to our repo:

curl -fsSL -o comping.tar.gz https://github.com/Solnest-AI/solnest-str-comping-agent/archive/refs/heads/main.tar.gz && tar -xzf comping.tar.gz && rm comping.tar.gz && mv solnest-str-comping-agent-main solnest-str-comping-agent

Already cloned it? Step 0 of CLAUDE.md detaches it. Then follow CLAUDE.md > "When the user says set this up". Never commit, push, fork or open a pull request for this folder: saving means the files on disk. Branding: ask the student for their company website and wait for the answer; never take it from their email, another copy or a search. Run every Python command through scripts/ensure_env.sh, never bare python/pip (on a fresh Windows machine python opens the Microsoft Store). Verify keys with scripts/check_setup.py; never open or print ~/.claude.json or the kit's .env: agent.py finds the connections-kit keys itself and prints where they came from.

Two API keys: AirROI and Firecrawl. Everything else is optional. There is no Anthropic key. The report's written analysis comes from Claude Code itself.

Bring your own keys. Zero secrets in the repo. Keys live in a local .env that is gitignored and never leaves your machine.


Read this before you trust a number

The revenue figures in these reports are estimates derived from comparable listings, not forecasts and not a valuation. The agent takes the trailing twelve months of real performance from AirROI for a set of nearby listings it judges comparable, and projects from that set.

That means:

  • The output is only as good as the comp set. In thin or unusual markets there may not be six genuinely comparable listings, and the report will say so rather than quietly widening until it finds some.
  • Trailing performance is not a prediction. Regulation changes, new supply, interest rates, and a market turning over will all break the extrapolation.
  • Every comp is somebody else's listing, with their pricing strategy, their photos, and their reviews. A comp earning $90k does not mean this property will.
  • We publish no accuracy figure, because we have not measured one. Do not read the three-tier projection as a confidence interval; it is a spread of assumptions, not a statistical bound.

Use it the way you would use an analyst's first pass: a defensible starting point that shows its work. Not an appraisal, not investment advice.


What it does

  • Any input. Airbnb URL (best results), Zillow/Realtor URL, or a plain street address
  • Real comps. Pulls listings and trailing-twelve-month performance from the AirROI API, then scores each against the subject on physical match, financials, quality, amenities, distance, and data reliability. Dormant and part-time listings are gated out rather than averaged in.
  • Sanity gates. A report that cannot find a defensible comp set fails instead of shipping
  • Three-tier projection. Conservative / Base / Optimistic, an interactive calculator, and a seasonality chart driven by the market's real monthly revenue distribution
  • Written analysis from Claude Code. The agent emits a brief, Claude writes the copy, you re-run. No API key, no per-report cost.
  • Branded output. One HTML file with your logo and colors (opened online: photos, fonts and the chart load from the web)

What it does not do

  • It does not value the property or estimate what you should pay for it.
  • It does not model your expenses, financing, taxes, or local STR regulation.
  • It does not check whether short-term rental is legal at the address.
  • It does not work well where AirROI has thin coverage. Rural and newly-opened markets are the weak spot.
  • It is not a pricing tool. Use PriceLabs or Wheelhouse for that.

Setup

Fastest path: open this folder in Claude Code and say "set this up."

By hand:

bash scripts/ensure_env.sh   # installs uv, Python 3.13 and everything else
cp .env.example .env                      # then add your AirROI + Firecrawl keys
                                          # (ran the STR Secrets connections kit? skip this:
                                          #  the agent reads the kit's .env itself)
cp branding.example.json branding.json    # then add your company

API keys

Key Required? What it buys you Get it
AIRROI_API_KEY Required The comp data: listings, comparables, TTM performance, revenue estimates https://www.airroi.com/api/developer/activate
FIRECRAWL_API_KEY Required Street-address and Zillow/Realtor input (an Airbnb URL alone works without it, but check_setup.py requires both) https://www.firecrawl.dev/app/api-keys
GMAIL_ADDRESS + GMAIL_APP_PASSWORD Optional --email delivery. Reports always save locally regardless. https://myaccount.google.com/apppasswords

No Anthropic key. See the narrative handoff below.

Ran the STR Secrets connections kit? You need no .env here. The agent reads the AirROI and Firecrawl keys from the kit's own .env (the master copy) and says so: [Config] AirROI key: connections kit (.env). The kit's .env wins over one in this folder; ~/.claude.json is the last fallback. scripts/check_setup.py finds the kit and tests both keys.


Run it as a Claude Code skill (recommended)

Paste the repo link into Claude Code and say "set this up", then just ask:

run comps on https://www.airbnb.com/rooms/39508095

The bundled skill at .claude/skills/str-comping-agent/SKILL.md drives the whole loop: it runs the pipeline, reads the narrative brief, writes the analysis copy itself, and re-renders. You get one finished HTML report.

Or run it directly

# Pass 1 — fetch, score, render. Costs about $0.50 of AirROI credit (up to ~$1.60 with a targeted search in a thin market), ~30s.
PY="$(bash scripts/ensure_env.sh)" && "$PY" agent.py --input "https://www.airbnb.com/rooms/39508095"
#   output/<slug>.html                    the report
#   output/<slug>.report-data.json        cached pipeline output
#   output/<slug>.narrative-brief.json    what to write the copy from

# Pass 2 — swap in better copy. No API calls, no cost, under a second.
PY="$(bash scripts/ensure_env.sh)" && "$PY" agent.py --render "output/<slug>.report-data.json" \
                --narratives "output/<slug>.narratives.json"

Pass 1 is the expensive half and only needs to run once per property. Re-rendering with new copy is free, which is the point: the analysis text can be rewritten as many times as you like without paying for the data again.

The narrative handoff

The report's written sections (positioning, guest profile, amenity upside, season commentary) are generated by Claude Code, not by an API key you pay for. The loop:

# 1. Run it. You get a complete report with template copy,
#    plus output/<slug>.narrative-brief.json
PY="$(bash scripts/ensure_env.sh)" && "$PY" agent.py --input "https://www.airbnb.com/rooms/39508095"

# 2. In Claude Code: read that brief, write output/<slug>.narratives.json
#    The brief carries the comp table, the market's real peak and shoulder
#    months, the calculator defaults, and the exact JSON shape to write.

# 3. Re-render with the copy: reuses the cached data, no paid vendor calls
PY="$(bash scripts/ensure_env.sh)" && "$PY" agent.py --render "output/<slug>.report-data.json" \
                --narratives "output/<slug>.narratives.json"

The agent prints the exact three lines to paste into Claude Code when it writes the brief. The report from step 1 is complete and valid on its own; step 3 just replaces boilerplate with real analysis.

--narratives validates strictly and fails loudly rather than falling back to template copy, so a report never silently claims to be something it is not.


Branding

The report is white-label. Copy branding.example.json to branding.json and edit it:

{
  "company_name": "Your Company",
  "tagline": "Short-Term Rental Management",
  "logo_url": "",
  "website_url": "",
  "primary_color": "#1f3c34",
  "accent_color": "#4b7c6b"
}

branding.json is gitignored, so your identity never ships with the code. Do not edit the template to rebrand.


What's in the box

str-comping-agent/
├── CLAUDE.md              ← the guided setup + narrative handoff. START HERE.
├── README.md              ← this page
├── SETUP.md               ← the non-technical walkthrough
├── agent.py               ← CLI entrypoint + orchestration
├── comp_scorer.py         ← scoring, hard gates, ranking
├── config.py              ← reads .env + branding.json
├── schema.py              ← typed data models
│
├── scrapers/              ← AirROI, Airbnb, property search
├── adapters/              ← maps API payloads into the scorer's shape
├── validators/            ← sanity gates that block a bad report
├── generators/            ← calculator, narrative brief, narratives, methodology
├── report/                ← HTML rendering + optional email
├── templates/             ← the report template
├── scripts/package.py     ← builds the distribution zip from the git manifest
├── tests/                 ← hermetic tests, run against captured API responses
│
├── .env.example           ← copy to .env
├── branding.example.json  ← copy to branding.json
├── requirements.txt
└── requirements-dev.txt

Development

PY="$(bash scripts/ensure_env.sh --dev)"   # adds pytest + ruff to the .venv
"$PY" -m pytest -q                          # hermetic: no network, no keys
"$PY" -m ruff check .                       # lint

The test suite is hermetic: no network, no API keys. It runs against real AirROI responses captured in tests/fixtures/ covering six markets, so a change to the scorer is checked against data that actually exists rather than against mocks that agree with the code. CI runs lint and tests on Python 3.10, 3.11, and 3.12 with no secrets configured. Any test that reaches the network fails the build by design.


Requirements

  • Python 3.10+
  • The STR Secrets connections kit with both keys: AirROI (comp data) and Firecrawl (branding and street addresses). Gmail is the only optional one.

License

MIT. See LICENSE.

About

Instant STR income reports from an Airbnb link, Zillow link, or street address. Finds real comps, scores them, and generates a branded HTML report with revenue projections. Runs in Claude Code; bring your own keys, zero secrets in the repo.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages