This commit is contained in:
Ole
2026-05-16 06:54:17 +00:00
commit 1399f61c1a
44 changed files with 6746 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
# AGENTS.md — Workflow for AI agents on finn-eiendom-mcp
This is the master doc for any AI agent (Claude, Copilot, Cursor, etc.) working in this repo. Read this first, then the more specific files it references.
---
## Read order
Before changing code, read:
1. **`PRD.md`** — what we're building and why. Especially §17 ("Code ownership and anti-duplication") — that section is the constitution.
2. **`PROJECT.md`** — module map.
3. This file — workflow.
4. The relevant `.github/instructions/*.md`:
* `python.instructions.md` — Python conventions.
* `mcp.instructions.md` — MCP tool rules.
* `cli.instructions.md` — CLI command rules.
* `tests.instructions.md` — testing conventions.
* `clean-code.instructions.md` — best practices and DRY enforcement.
* `docs.instructions.md` — when and how to use the **context7** MCP server for library documentation.
If something in code contradicts the PRD, the PRD wins. If you change behavior, update both the PRD and the relevant instruction file in the same change.
---
## Runtime — local venv (default)
This project runs in a project-local virtualenv. Docker is supported for packaging but is not required for development.
### One-time setup
```bash
# from the project root
uv venv # or: python3.12 -m venv .venv
source .venv/bin/activate
uv pip install -e ".[dev]" # or: pip install -e ".[dev]"
```
Python **3.12+** is required.
### Daily commands
All commands are run inside the activated `.venv`:
```bash
pytest # tests
ruff check . # lint
ruff format . # format
mypy finn_eiendom # type-check
finn-eiendom --help # CLI entrypoint
finn-eiendom-mcp # MCP server (stdio)
finn-eiendom serve --transport http --port 8010 # MCP server (HTTP)
```
### Never
* Install packages globally (`pip install ...` outside a venv).
* Use `sudo pip`.
* Mutate the host Python.
* Add dependencies without updating `pyproject.toml`.
### Adding a dependency
```bash
uv pip install <package> # ad-hoc, then:
# edit pyproject.toml to record it
uv pip install -e ".[dev]" # reinstall in editable mode
```
---
## Architecture in one screen
```
cli.py (typer) mcp_server.py (FastMCP) ← thin, parallel front ends
\ /
\ /
service.py ← orchestration: get_or_fetch, analyze_*
analysis.py ← shortlist + summary
search / ad / eiendom_no / scoring / feedback
parser / http / cache
FINN HTML + Eiendom.no JSON + SQLite
```
`formatting.py` sits next to `service.py` and is shared by both CLI and MCP for `json`, `markdown`, and `table` rendering.
**The single-home rule:** every piece of logic has exactly one home. If you're tempted to add it in two places, you're wrong about one — push it down a layer and call it from both. See `PRD.md` §17.2 for the full ownership table.
---
## The five hard rules
These are non-negotiable. Architecture tests in `tests/test_architecture.py` enforce them.
1. **`mcp_server.py` and `cli.py` are siblings.** They never call each other. Both call only `service`, `formatting`, `models`, and `config`.
2. **`service.py` is the only place that combines cache + fetch.** Nothing above it touches HTTP or SQLite directly.
3. **`httpx` lives in `http.py`. Nowhere else.**
4. **`sqlite3` lives in `cache.py`. Nowhere else.**
5. **Output formatting lives in `formatting.py`.** No inline rendering in CLI or MCP tool bodies.
If you have to break one of these to ship a feature, the feature is wrong — fix the design first.
---
## Adding a feature — the checklist
For any new tool / command / behavior:
1. Decide the home using the table in `PRD.md` §17.2.
2. Write the function in `service.py` (or extend `analysis.py` if it's pure orchestration).
3. Add a test in `tests/test_service.py`.
4. Add a thin MCP tool in `mcp_server.py``response_format` aware.
5. Add a thin CLI command in `cli.py``--format` aware.
6. Add the renderer in `formatting.py` if output is non-trivial.
7. Add tests in `tests/test_mcp_server.py` and `tests/test_cli.py`.
8. Update `PRD.md` and any affected `.github/instructions/*.md`.
If steps 4 or 5 need more than ~20 lines, logic has leaked out of the service layer. Push it back down.
---
## Clean code
See `.github/instructions/clean-code.instructions.md`. Highlights:
* Type hints everywhere.
* Functions stay small; one job per function.
* Names describe intent (`get_or_fetch_ad`, not `process`).
* Comments explain **why**, never **what** the code already says.
* DRY: if you write the same regex / SQL / format string twice, extract it.
* Errors fail loudly with actionable messages. No silent `except: pass`.
* No dead code, no commented-out blocks left in the tree.
---
## Documentation lookups — use context7
When uncertain about a library's API (FastMCP decorators, Pydantic v2 validators, Typer command patterns, httpx async, msgpack, pytest-asyncio, respx, BeautifulSoup selectors, etc.), **use the `context7` MCP server**. Do not guess from training-data memory.
Pattern (full details in `.github/instructions/docs.instructions.md`):
1. `context7:resolve-library-id` with the library name → get the canonical ID.
2. `context7:query-docs` with that ID + a focused topic.
Use context7 *before* writing the code, not after a test fails. If context7 returns nothing useful, search the library's official docs, then write the smallest possible spike to verify.
---
## Safety and compliance
* Private, low-frequency use only.
* Respect FINN / Eiendom.no rate limits and bot protection.
* Cache aggressively; never bulk-harvest.
* stdio MCP servers log to **stderr only** — anything on stdout breaks the JSON-RPC frame.
* Scores and estimates are decision support, never legal / technical / financial advice.
---
## Implementation order (Phase 2)
Follow `PRD.md` §29 step-by-step. Each step is independently mergeable:
1. Switch dev workflow to local venv + update instruction files (this change).
2. Pydantic v2 cleanup.
3. Service layer + tests.
4. Formatting layer + tests.
5. HTTP retry on 5xx + tests.
6. Replace FastAPI with FastMCP stdio server.
7. CLI with typer.
8. Diff workflow.
9. Compare workflow.
10. Similar-to-liked.
11. Architecture tests.
12. README + Claude Desktop config.