Skip to main content
Glama
takatin31
by takatin31
README.md
# France Data MCP

French public registries as tools for AI agents: company records, property sale
prices, housing energy performance, and short-term rental rates.

**Endpoint:** `https://france-data-mcp.fly.dev/mcp` (streamable HTTP)

## Why this exists

The three REST APIs behind it are listed on API marketplaces, where they compete
with 98,000 others for search placement. MCP is a different channel with different
economics and much less crowding: Apify returns 80% of revenue to developers,
MCPize 85%, against RapidAPI's 75%. More importantly, a listing that does not rank
on one marketplace earns nothing there — a second channel decorrelates that risk.

This server owns no data. It is distribution.

## Tools

| Tool | Answers |
|---|---|
| `search_companies` | Find a French company by name, trade name or address |
| `lookup_company` | One company by SIREN, or the owner of a SIRET |
| `validate_company_id` | Is this SIREN/SIRET well-formed, and does it exist |
| `property_prices` | Median and percentile €/m² for a commune |
| `property_price_trend` | Did this local market rise or fall, year by year |
| `energy_profile` | Energy label distribution, and the share barred from letting |
| `prices_by_energy_label` | What an energy rating is worth locally |
| `short_let_market` | Nightly price percentiles for any city worldwide |

## Design notes

**Docstrings are the interface.** The model reads them to choose a tool and its
arguments, so they say what a tool answers and when to prefer it — not how it
works.

**Responses are trimmed, not proxied.** An LLM pays for every token it reads.
Returning the full REST payload would make each call expensive and slow to reason
over, so each tool returns the answer rather than the record.

**Caveats pass through unchanged.** Several of these statistics are easy to
misread — most sharply, poorly rated homes selling at a premium in old city
centres. An agent reporting a median should be able to report its limits too, so
the caveat text travels with the number.

## Access control

`MCP_ACCESS_TOKEN` unset leaves the server open, which is the right setting while
the goal is directory listing and discovery. Set it to require a bearer token when
selling access directly. Marketplaces handle their own billing, so a server
distributed there runs open and lets the marketplace gate it.

## Configuration

| Variable | Purpose |
|---|---|
| `COMPANY_API_SECRET` / `PROPERTY_API_SECRET` / `AIRBNB_API_SECRET` | Proxy secrets for the three backends |
| `PUBLIC_HOST` | Hostname allowed past DNS-rebinding protection |
| `MCP_ACCESS_TOKEN` | Optional bearer token |

The SDK rejects unknown `Host` headers to block DNS rebinding and allows only
localhost by default. Without `PUBLIC_HOST` declared, every real request answers
`421 Misdirected Request` — which is exactly what happened on first deploy.

## Running locally

```bash
pip install -r requirements.txt
uvicorn app.main:app --port 8080
```

## Deploying

```bash
flyctl deploy --remote-only
```

Scale-to-zero, one machine.