initial
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# finn-eiendom-mcp
|
||||
|
||||
> **Private, self-hosted property analysis platform for Norwegian real estate.** Analyzes FINN listings, enriches with Eiendom.no estimates, scores against personal preferences, and surfaces bargain candidates, hybel potential, renovation upside, and risk flags. Exposed through an MCP server, a CLI, and a Python library — all sharing one service layer.
|
||||
|
||||
This is a **personal tool**. Not a SaaS, not a crawler, not legal/financial advice. Run locally, low frequency, your own data.
|
||||
|
||||
---
|
||||
|
||||
## What it does
|
||||
|
||||
```
|
||||
FINN search URL → ranked shortlist of homes
|
||||
with reasons, risks, comps, broker questions
|
||||
```
|
||||
|
||||
Specifically:
|
||||
|
||||
* Parses FINN search and listing pages.
|
||||
* Resolves each listing to an Eiendom.no `unitCode` for valuation and similar-units.
|
||||
* Builds a `unit_vector` and fetches recently-sold comparables.
|
||||
* Scores 9 components (economy, market position, comps, location, layout, outdoor, hybel, renovation, risk).
|
||||
* Classifies as *bargain*, *safe*, *hybel*, *renovation*, *lifestyle*, or *risk*.
|
||||
* Caches everything in SQLite; remembers what you've liked or rejected.
|
||||
* Detects new / removed / changed listings between runs.
|
||||
|
||||
---
|
||||
|
||||
## Three ways to use it
|
||||
|
||||
| Surface | When you want… | Entry point |
|
||||
| --------------- | -------------------------------------------------------------- | ----------------------- |
|
||||
| **CLI** | Quick triage in a terminal, scripting, cron | `finn-eiendom ...` |
|
||||
| **MCP server** | Claude Desktop, n8n, AI agents — conversational analysis | `finn-eiendom-mcp` |
|
||||
| **Python lib** | Tests, notebooks, custom scripts | `import finn_eiendom` |
|
||||
|
||||
All three call the same underlying `service.py` — same defaults, same semantics, same results.
|
||||
|
||||
---
|
||||
|
||||
## Quick start
|
||||
|
||||
### Requirements
|
||||
|
||||
* Python **3.12+**
|
||||
* `uv` (recommended) or `pip`
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
git clone <your-repo-url> finn-mcp
|
||||
cd finn-mcp
|
||||
|
||||
uv venv # or: python3.12 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
uv pip install -e ".[dev]" # or: pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
### First run (CLI)
|
||||
|
||||
```bash
|
||||
# Triage a FINN search
|
||||
finn-eiendom analyze-search 'https://www.finn.no/realestate/homes/search.html?location=...' --format table
|
||||
|
||||
# Drill into one listing
|
||||
finn-eiendom get-ad 462400360 --format markdown
|
||||
|
||||
# Mark a listing as liked
|
||||
finn-eiendom save-feedback 462400360 liked --notes "great layout, check fellesgjeld"
|
||||
|
||||
# Find similar properties to liked listings
|
||||
finn-eiendom similar-to-liked 462400360
|
||||
```
|
||||
|
||||
### First run (Claude Desktop)
|
||||
|
||||
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or the equivalent on Linux:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"finn-eiendom": {
|
||||
"command": "/absolute/path/to/finn-mcp/.venv/bin/finn-eiendom-mcp",
|
||||
"env": {
|
||||
"FINN_CACHE_PATH": "/absolute/path/to/finn-mcp/data/finn.sqlite",
|
||||
"EIENDOM_NO_ENABLED": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart Claude Desktop. Then in any chat:
|
||||
|
||||
> Analyze this FINN search and shortlist the top 5 for a couple in Oslo with a 9–12 MNOK budget, willing to renovate, prefer hybel potential:
|
||||
> `https://www.finn.no/realestate/homes/search.html?location=...`
|
||||
|
||||
For deep usage — every command, every MCP tool, every env var — see [`USAGE.md`](USAGE.md).
|
||||
|
||||
---
|
||||
|
||||
## Architecture in one screen
|
||||
|
||||
```
|
||||
CLI (typer) MCP server (FastMCP) ← thin, parallel front ends
|
||||
\ /
|
||||
\ /
|
||||
service.py ← cache + fetch orchestration
|
||||
↓
|
||||
analysis.py ← shortlist + summary
|
||||
↓
|
||||
search / ad / eiendom_no / scoring / feedback
|
||||
↓
|
||||
parser / http / cache (SQLite)
|
||||
↓
|
||||
FINN HTML + Eiendom.no JSON
|
||||
```
|
||||
|
||||
`formatting.py` lives next to `service.py` and is shared by both CLI and MCP for JSON / markdown / table rendering.
|
||||
|
||||
**Key rule:** CLI and MCP are siblings. They never call each other. Both call the same `service.py` functions. See [`PRD.md`](PRD.md) §17 for the full code-ownership constitution.
|
||||
|
||||
---
|
||||
|
||||
## Project documents
|
||||
|
||||
Read in this order depending on what you're doing:
|
||||
|
||||
| If you want to… | Read |
|
||||
| ------------------------------------- | --------------------------------------------------- |
|
||||
| Use the tool | This README, then [`USAGE.md`](USAGE.md) |
|
||||
| Understand the design | [`PRD.md`](PRD.md), especially §1, §12, §17 |
|
||||
| Contribute / extend / hack on it | [`AGENTS.md`](AGENTS.md), then [`PROJECT.md`](PROJECT.md), then `.github/instructions/*.md` |
|
||||
| Run the cleanup pass on the repo | [`CLEANUP.md`](CLEANUP.md) |
|
||||
| Build out unfinished features | [`IMPLEMENTATION.md`](IMPLEMENTATION.md) |
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
* **Phase 0 (spike):** done.
|
||||
* **Phase 1 (core MVP):** mostly done.
|
||||
* **Phase 2 (MCP + CLI):** in progress — driven by [`IMPLEMENTATION.md`](IMPLEMENTATION.md).
|
||||
* **Phase 3+ (scoring v2, agent workflows, dashboard):** future.
|
||||
|
||||
---
|
||||
|
||||
## Safety and compliance
|
||||
|
||||
* Private, low-frequency, user-triggered use only. No public deployment.
|
||||
* Configurable request delays (`FINN_REQUEST_DELAY_SECONDS`, `EIENDOM_NO_REQUEST_DELAY_SECONDS`) — defaults are conservative.
|
||||
* Aggressive caching to minimize external requests.
|
||||
* No bypassing of rate limits, bot protection, authentication, or access controls.
|
||||
* No public redistribution of FINN or Eiendom.no data.
|
||||
* Scores, estimates, and comparable sales are **decision support, not advice**. Don't substitute this for a real broker, lawyer, or technical inspector.
|
||||
|
||||
---
|
||||
|
||||
## License / use
|
||||
|
||||
Personal project. Not for redistribution. Don't expose the MCP HTTP transport on a public interface — keep it on LAN, Tailscale, or behind auth.
|
||||
Reference in New Issue
Block a user