Skip to main content
Glama
README.md
# flatfind — codex-style CLI for Bangalore house hunting (NoBroker)

`flatfind` takes NoBroker's real API, wraps phone+OTP login, lets you describe
what you want in plain English ("2bhk in koramangala under 30k"), searches
automatically, and scores photos GOOD/AVERAGE/BAD with whatever vision model
**you** have (Claude / OpenAI / Gemini / offline heuristic).

Built to be driven by **humans in a terminal AND by agents**
(Claude Code / Codex / OpenCode) via `--json` + a zero-dep MCP server.

## Install

**From PyPI** (once published — see below):

```bash
pipx install flatfind        # recommended: isolated CLI install
# or
pip install flatfind
# or run without installing:
uvx flatfind search "2bhk in koramangala under 30k"
```

**From source:**

```bash
git clone https://github.com/ayushrajsinghparihar/flatfind.git
cd flatfind
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
# or: pip install -e ".[dev]"
```

## 60-second tour

```bash
flatfind localities
flatfind search "2bhk in koramangala under 30k" --limit 10
flatfind show 8aa99668 --json
flatfind analyze 8aa99668
flatfind probe-params --locality koramangala   # what the API accepts/rejects
```

## Auth (phone + OTP — real NoBroker flow)

Search works **without login**. Login unlocks owner contact numbers.

```bash
flatfind auth send-otp --phone 98765XXXXX
flatfind auth login --phone 98765XXXXX --otp 123456
flatfind auth status
flatfind auth logout
```

Endpoints (reverse-engineered, see `docs/REVERSE_ENGINEERING.md`):

| step | method + endpoint | params |
|---|---|---|
| send OTP | `POST /api/v2/account/otp/send` | `phone` (+opt `otpAPP`) |
| login | `POST /api/v1/account/login/otp` (fallback `/api/v2/user/login/otp`) | `phone`, `otp` |
| search | `GET /api/v3/multi/property/RENT/filter` | `searchParam` (base64 localities), `city`, `pageNo`, `radius`, `rent`, `bhk`, `buildingType`, `orderBy`, ... |
| photos | `https://images.nobroker.in/images/<id>/<file>` | from `photos[].imagesMap` |

## Photo analysis — depends on YOUR model

| env present | backend | quality |
|---|---|---|
| `ANTHROPIC_API_KEY` | Claude Sonnet vision | best |
| `OPENAI_API_KEY` | GPT-4o-mini vision | cheap + good |
| `GEMINI_API_KEY` / `GOOGLE_API_KEY` | Gemini Flash vision | good |
| none | offline heuristic (count/resolution/owner-upload/metadata) | honest filter |

```bash
flatfind analyze <id> --model auto      # default: best available
flatfind analyze <id> --model heuristic # force offline
```

## Use from Claude Code / Codex / OpenCode

**Option A — CLI:** agents just run the commands above with `--json`.
Full playbook in `skills/SKILL.md` (drop it into your agent's skills dir).

**Option B — MCP server (zero extra deps):**

```json
// .mcp.json (Claude Code) — adapt for Codex/OpenCode
{ "mcpServers": { "flatfind": { "command": "flatfind", "args": ["mcp"] } } }
```

Tools: `search_flats`, `show_flat`, `analyze_flat`, `auth_status`, `probe_params`.

Two-layer rule: `analyze` filters, the host agent re-reads top photo URLs
with its own eyes and makes the final call.

## Repo layout

```
src/flatfind/
  cli.py               Typer CLI (search/show/analyze/auth/probe/mcp)
  config.py            paths, endpoints, session store
  nobroker/
    auth.py            send_otp / login_with_otp / status
    search.py          searchParam builder + paginated search
    probe.py           accepts-vs-rejects param prober
    detail.py          photo URL builder + summarizer
    localities.py      bundled Bangalore lat/lon table
    client.py          session + headers + cookie persistence
  agent/
    planner.py         NL -> filters (offline regex, reproducible)
    scorer.py          vision (claude/openai/gemini) + heuristic fallback
  mcp/server.py        dependency-free MCP over stdio
skills/SKILL.md        agent playbook
docs/REVERSE_ENGINEERING.md  how the API was mapped
tests/                 offline unit tests (no network)
```

## Dev

```bash
python -m pytest -q
flatfind search "2bhk in hsr layout under 28k" --limit 5 --json | head -50
```