cian-mcp
# cian-mcp
Локальный MCP-сервер (Python, stdio) для поиска квартир на [cian.ru](https://www.cian.ru)
через живой авторизованный браузерный контекст. Подключается к opencode (или любому
другому MCP-клиенту) и предоставляет инструменты:
- `auth_login` — ручной вход в видимом браузере (телефон + SMS), сессия сохраняется.
- `auth_status` — проверка валидности сессии.
- `search_offers` — поиск объявлений о продаже квартир по фильтрам.
- `get_offer` — детальная карточка лота с историей цены.
## Почему так
У Циана нет покупательского API, а веб защищён агрессивной анти-бот системой
(Qrator, JS-challenge, капчи). Основной путь — реальная навигация браузера
(`page.goto`), исполняющая JS и выставляющая нужные куки. `context.request`
используется как ускорение в уже «прогретой» сессии. Подробности — в
`openspec/changes/cian-search-mcp/design.md`.
## Требования
- Python 3.12+
- Десктоп с графическим дисплеем (для `auth_login` нужен видимый браузер;
на headless-сервере или чистом SSH без проброса дисплея вход не сработает).
## Установка
```bash
make build # pip install -e . (устанавливает пакет и зависимости)
playwright install chromium # скачать браузер Playwright
```
Или вручную:
```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
playwright install chromium
```
## Запуск тестов и линтера
```bash
make test # pytest
make cover # pytest + coverage (порог 80%)
make lint # ruff check
make fmt # ruff format
```
## Запуск сервера
```bash
make run # python -m cian_mcp
```
## Конфигурация opencode
Сервер работает по stdio. Добавьте его в конфиг opencode как локальный
stdio MCP-сервер, например:
```jsonc
// opencode.json (или .opencode/config)
{
"mcp": {
"cian-search": {
"type": "local",
"command": ["python", "-m", "cian_mcp"],
"cwd": "/path/to/cian"
}
}
}
```
Укажите `cwd` в корне проекта, чтобы `data/` (профиль браузера и БД) создавалась
рядом с репозиторием.
## Первый вход
1. Агент вызывает `auth_login`.
2. Открывается видимое окно браузера на странице входа Циана.
3. Вы входите вручную (телефон + SMS-код).
4. После успешного входа сервер фиксирует сессию; профиль сохраняется в локальную
директорию `data/browser_profile/`.
5. При последующих запусках авторизованный контекст восстанавливается из профиля.
`auth_login` идемпотентен: при уже валидной сессии он вернёт сообщение, что вход
не требуется.
## Примеры вызовов инструментов
```
auth_login()
-> { "status": "ok", "message": "Вход выполнен, сессия сохранена ..." }
auth_status()
-> { "status": "authorized", "message": "Сессия валидна." }
search_offers(city_id=1, rooms=[2], price_min=8000000, price_max=15000000, limit=20, page=1)
-> { "status": "ok", "page": 1, "limit": 20, "next_page": 2,
"offers": [ { "offer_id": "...", "url": "...", "price": ..., "price_per_m2": ... }, ... ] }
get_offer(url="https://www.cian.ru/sale/flat/287001234/")
-> { "status": "ok", "source": "network", "offer_id": "...", "price": ...,
"price_history": [ {"price": ..., "seen_at": "..."} ], ... }
```
`get_offer` поддерживает `force_refresh: true` — всегда идёт в сеть в обход кэша.
## Локальные данные и приватность
Профиль браузера (куки, localStorage) и SQLite-кэш хранятся строго в локальной
директории `data/`, которая добавлена в `.gitignore`. Значения кук и заголовков
авторизации **никогда не логируются** и не передаются никаким внешним сервисам,
кроме самого cian.ru в ходе запросов.
## Дисклеймер (ToS Циана)
Использование автоматизированных запросов к cian.ru может противоречить
пользовательскому соглашению (Terms of Service) Циана. Этот проект
предназначен **исключительно для личного использования** под собственным
аккаунтом, в низком («человеческом») темпе, для помощи в поиске квартиры.
Проект не предназначен для массового скрапинга, коммерческого использования
или обхода защит. Ответственность за соблюдение применимых правил и законов
несёт пользователь.
TDQS
Scored across 4 tools
Each tool maps to a distinct concern: authentication (login/status) versus listing retrieval (search/detail). There is no overlap or confusion between list-level and item-level operations.
Tool names follow a clear snake_case verb_noun pattern: auth_login/auth_status share an auth_ prefix, and search_offers/get_offer share the offers resource. The pattern is predictable and easy to navigate.
Four tools is well-scoped for a focused Cian real estate browsing server: two for session management and two for offer discovery/detail. No tool feels redundant.
The surface covers the full read-only workflow: authenticate, verify session, search listings, and retrieve full offer details. No critical missing operation exists for the apparent purpose.