Skip to main content
Glama
README.md
<div align="center">

# Rootbank

**Land-viability intelligence for would-be small farmers** — a free, open-source
MCP server that plugs into Claude, Cursor, or any MCP-capable AI to answer the
two questions that matter about a piece of land:

> 1. **Is this plot actually good for growing food?**
> 2. **Can I legally put a home on it?**

…and finds real land for sale to score in the first place.

_A tool for stewards, not speculators._

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)](pyproject.toml)
[![CI](https://github.com/omardaaboul/rootbank/actions/workflows/ci.yml/badge.svg)](https://github.com/omardaaboul/rootbank/actions/workflows/ci.yml)
[![tests](https://img.shields.io/badge/tests-43%20passing-brightgreen)](tests/)

</div>

---

## Why this exists

> **Everyone should own land — because this is what will make you rich.**
> Not money, not nice cars — but land you can cultivate, grow, and enrich;
> land that provides for you and your family, your neighbours, and your
> community; land that feeds animals and sustains life.
>
> — the reason this project exists

Most of what the real-estate market does with land is speculating on it. This
tool is for the people who want a piece of ground to *own, live on, and care
for* — water, topsoil, a workable season, and the honest answer about whether
they're actually allowed to build on it. It does not guess: every signal comes
from a named public source, and anything it can't know is flagged, never
invented.

**Works in the US, France, and Cyprus** — and scores land anywhere Open-Meteo +
OSM have data. Exactly what's available differs by country, so here's the honest
picture:

## Country coverage

| Country | Score land (`assess_land`) | Find land for sale (`find_land`) | Flood / dwelling check |
|---|---|---|---|
| **United States** | ✅ full climate + water + farmland + land-type | ✅ farms.com + Craigslist (live) | ✅ FEMA flood zone |
| **Cyprus** | ✅ full | ✅ index.cy (live; Greek/English titles) | ⚠️ no flood data — flags "confirm with planning authority" |
| **France** | ✅ full | 🔜 browser-locked (leboncoin.fr, offer.com.cy) — not yet scraped | ⚠️ no flood data — flags "confirm with mairie/DDT" |
| **Everywhere else** (anywhere Open-Meteo + OSM have data) | ✅ climate, water, farmland, land-type, access | ❌ no listing source wired | ⚠️ no flood data |

**Verdict legend:** ✅ = works now · ⚠️ = works, with an honest "confirm locally"
note · 🔜 = registered but needs a browser (see `land_sources.browser_only`)

**What's global vs. country-specific:**
- **Global (works almost anywhere):** climate (precipitation, growing season,
  hardiness), water features, farmland, land type, roads/access — this is what
  `assess_land` scores, and it uses Open-Meteo + OpenStreetMap, both worldwide.
- **Country-specific:** `find_land` listings come from per-country sites; flood
  zones come from **FEMA, which is US-only** — so the dwelling-flood check really
  only applies to the US, and elsewhere it honestly says "confirm with your local
  planning authority" rather than guessing.

## Tools

| Tool | What it does |
|---|---|
| `assess_land` | Scores a parcel for micro-farm viability **and** dwelling feasibility — precipitation, growing season, water access, farmland context, land type, tree cover, neighbours/privacy, **soil (fertility, pH, texture → well-recharge)**, access, flood zone. Returns an evidence-backed **promising / requires_look / likely_mismatch** verdict. |
| `find_land` | Finds real land for sale from free sources with **price, size, photos, description, location** — and a `country`/`state` filter. |
| `zone` | Explains a **planning-zone code** and whether a dwelling is allowed on farmland — for **France** (`A`/`U`/`AU`/`N` + STECAL/extension rules, "logement de fonction" conditions), **Cyprus** (`Γη3`/`ΚΑ6`/`H2`), and the **US** (agricultural districts). |
| `land_sources` | Lists the free public data sources + licenses used (transparency & attribution). |
| `about_rootbank` | Plain-language explanation of what to look for in land. |

Everything is **evidence-backed**: each signal names its source, and missing data
is reported as missing — never treated as "good."

## Quickstart

```bash
git clone https://github.com/omardaaboul/rootbank.git
cd rootbank
python3 -m venv .venv
.venv/bin/pip install -e ".[test]"
.venv/bin/rootbank                  # start the server (stdio)
```

### Connect it to Claude / Cursor / OpenCode / Gemini / any MCP client

Microfarm is a **standard MCP server**, so any tool that supports MCP can use it.
The exact setup depends on the client:

**Claude Desktop** — `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "rootbank": {
      "command": "python3",
      "args": ["-m", "rootbank.server"],
      "env": { "PYTHONPATH": "/absolute/path/to/rootbank" }
    }
  }
}
```

**Claude Code** — `claude mcp add`:
```bash
claude mcp add rootbank -- python3 -m rootbank.server
```

**Cursor** — `.cursor/mcp.json`:
```json
{
  "mcpServers": {
    "rootbank": {
      "command": "python3",
      "args": ["-m", "rootbank.server"],
      "env": { "PYTHONPATH": "/absolute/path/to/rootbank" }
    }
  }
}
```

**OpenCode** — `opencode.json` (repo) or `~/.config/opencode/config.json`:
```jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "rootbank": {
      "type": "local",
      "command": ["python3", "-m", "rootbank.server"],
      "cwd": "/absolute/path/to/rootbank",
      "enabled": true,
      "timeout": 10000
    }
  }
}
```

**Gemini CLI** — `~/.gemini/settings.json`:
```json
{
  "mcpServers": {
    "rootbank": {
      "command": ["python3", "-m", "rootbank.server"],
      "env": { "PYTHONPATH": "/absolute/path/to/rootbank" }
    }
  }
}
```

**VS Code** (built-in Copilot MCP / extension) — `.vscode/mcp.json`:
```json
{
  "servers": {
    "rootbank": {
      "type": "stdio",
      "command": "python3",
      "args": ["-m", "rootbank.server"],
      "env": { "PYTHONPATH": "/absolute/path/to/rootbank" }
    }
  }
}
```

> **A note on ChatGPT.** ChatGPT supports MCP **only as a *remote HTTPS* server**,
> and that capability is currently limited to Business/Enterprise plans. A local
> `stdio` server (what this repo runs by default) **cannot** be plugged into
> ChatGPT directly. To use it in ChatGPT you'd need to host the server remotely
> and give ChatGPT its HTTPS URL — a real step, not a config tweak. For local use,
> Claude, Cursor, OpenCode, or Gemini CLI are the simple paths.

Then just ask your assistant:

> *"Is this plot in Dordogne good for a small farm, and can I build a house on it?"*
>
> *"Find me land under €150k in Paphos District and tell me which looks worth a visit."*

## What the results look like

```
assess_land("Polemi, Paphos, Cyprus")
→ promising | 75
  [positive] adequate_precipitation: ~426 mm/yr
  [positive] long_season:            ~363 growing days/yr
  [positive] water_access:           5 water feature(s) nearby
  [positive] farmland:               27 farm land tag(s) nearby
  [caution]  land_type:              built-up
  [caution]  tree_cover:             little/no mapped tree cover
  [caution]  privacy:                23 structures nearby
  [positive] soil_fertility:         ~42 g/kg organic carbon
  [caution]  soil_ph:                pH ~7.8
  [caution]  well_recharge:          ~33% clay / ~23% sand
  [positive] access:                 158 road segment(s) nearby

zone("A", "France")   → explains agricultural zone + when a dwelling is allowed
zone("Γη3", "Cyprus") → agricultural zone, min ~4,000m² for one rural dwelling
```

## Data sources & attribution

These are the free, keyless public sources behind every answer. When you use
this project or its data in your own work, please credit the sources below —
several require attribution by license.

| Source | What it provides | License / attribution |
|---|---|---|
| [Open-Meteo Geocoding](https://open-meteo.com/en/docs/geocoding-api) | place name → lat/lon, elevation | [CC BY 4.0](https://open-meteo.com/en/licence) |
| [Open-Meteo Historical Climate](https://open-meteo.com/en/docs/historical-weather-api) | precipitation, temperature, growing days | [CC BY 4.0](https://open-meteo.com/en/licence) |
| [Open-Meteo Elevation](https://open-meteo.com/en/docs/elevation-api) | surface elevation | [CC BY 4.0](https://open-meteo.com/en/licence) |
| [ISRIC SoilGrids](https://www.isric.org/explore/soilgrids) | topsoil: organic carbon, pH, clay/sand/silt texture, CEC | [CC BY 4.0](https://www.isric.org/) |
| [OpenStreetMap](https://www.openstreetmap.org/about) via [Overpass API](https://overpass-api.de/) | water features, buildings, roads, farmland, trees | [ODbL](https://www.openstreetmap.org/copyright) |
| [FEMA National Flood Hazard Layer](https://www.fema.gov/flood-maps/national-flood-hazard-layer) | flood zone at a point (US only) | US federal, public domain (data), ArcGIS service by FEMA |
| [farms.com](https://www.farms.com/classifieds/real-estate/) | US farm/land listings (find_land) | site content is theirs; we link to listings |
| [Craigslist](https://www.craigslist.org/) | US land by-owner listings (find_land) | site content is theirs; we link to listings |
| [index.cy](https://index.cy/) | Cyprus plots/land listings (find_land) | site content is theirs; we link to listings |

**Open-Meteo** aggregates national weather services; its API is licensed
[CC BY 4.0](https://open-meteo.com/en/licence) and we gratefully use it.
**OpenStreetMap** data is © OpenStreetMap contributors under the
[Open Database License](https://www.openstreetmap.org/copyright). Listing
content belongs to the respective marketplaces — we surface and link through to
their pages, never re-host their images.

## Land type, zone & the "can I build a dwelling here?" question

- **Land type** (farmland / pasture / forest / scrub / built-up / waterfront) and
  **tree cover** are detected from OpenStreetMap and reported in every assessment.
- **Official zoning** — what you're *legally* allowed to build or do on land — is
  **not available from free national data**. It's set by local planning authorities
  (US county, Cyprus Planning Authority, French mairie/DDT), and recorded on title
  deeds / cadastres / PLU documents that aren't freely machine-queryable. The
  `zone` tool explains the **codes** (France `A`/`U`/`N`, Cyprus `Γη`/`ΚΑ`, US
  agricultural districts) and their usual building rules — including the specific
  conditions for a *farm dwelling / logement de fonction* — and tells you exactly
  what to confirm with the local authority. It is a guide, never a substitute for
  the official record.

## Honest limits

- **Zoning / dwelling law is local.** This tool is an initial screen from public
  data (flood + farmland context); it does **not** replace the official ordinance.
  Always verify in person and with local officials.
- **Flood data is US-only** (FEMA). Outside the US it's honestly reported as
  unavailable — never falsely "no hazard."
- **Some listing sites are browser-locked** (landbanksearch, govdeals, farmflip,
  Bazaraki, land.cy, offer.com.cy, leboncoin.fr). They're registered but not yet
  scraped; `land_sources` shows the boundary of what's reachable vs. browser-only.
- **Geo-region names** like "Limousin" (abolished in 2016) may not geocode —
  use a current town or district.
- **Greek listing titles** get a basic word-level translation; obscure place
  names may stay in Greek.

## Development

```bash
.venv/bin/ruff check rootbank tests   # lint
.venv/bin/ruff format --check rootbank tests
.venv/bin/mypy rootbank               # type-check
.venv/bin/pytest tests/ -q             # 43 tests (mocked providers, deterministic)
```

CI runs lint, format, type-check, tests, and a package build on
Python 3.10 / 3.11 / 3.12.

## Project layout

```
rootbank/
├── rootbank/
│   ├── server.py       ← FastMCP server (5 tools)
│   ├── engine.py       ← orchestration + cache + find_land
│   ├── providers.py    ← free data providers (Open-Meteo, SoilGrids, OSM, FEMA)
│   ├── listings.py     ← land-listing collectors (farms.com, Craigslist, index.cy)
│   ├── scorer.py       ← evidence-backed viability + dwelling scoring
│   ├── zones.py        ← planning-zone explainer (France, Cyprus, US)
│   └── models.py       ← typed pydantic models
├── tests/              ← 43 tests
├── configs/            ← ready-to-use MCP client configs (Claude, Cursor,
│                         OpenCode, Gemini CLI, VS Code, generic)
├── .github/workflows/ci.yml
└── pyproject.toml
```

## License & disclaimer

MIT licensed — you're free to use, modify, and share it.

**This is not financial, legal, or real-estate advice.** Always verify a property
in person and with the local planning authority before relying on it. Data comes
from the free public sources above and may be incomplete or imperfect.

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: assessing viability, finding listings, explaining zoning codes, listing data sources, and providing background education. There is no practical overlap that would confuse an agent.

Naming Consistency3/5

The naming is readable and uniform in style with underscores, but it mixes conventions: assess_land and find_land follow verb_noun, while zone, land_sources, and about_microfarm are noun or prepositional style. The inconsistency is noticeable but not chaotic.

Tool Count5/5

Five tools is a well-scoped set for a specialized micro-farm research server. Each tool addresses a distinct part of the domain without redundancy or bloat.

Completeness5/5

The tool set covers the full user journey: learning about micro-farming, seeing available land, assessing a specific parcel, and understanding zoning implications. It also includes transparency about data sources, leaving no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues