Skip to main content
Glama
README.md
# 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

A3.9/5.0

Scored across 4 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness5/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues