Skip to main content
Glama
README.md
# blocksnet-mcp

`blocksnet-mcp` - локальный MCP-сервер городской аналитики поверх `BlocksNetAgent`.
Сервер предоставляет один основной инструмент `analyze_urban_question(...)`: принимает вопрос на
естественном языке, запускает полный рассуждающий агент BlocksNet на локальной модели города и
возвращает строгий машиночитаемый JSON.

Проект следует подходу **WIKI-LLM**: документация и директории индексируются так, чтобы LLM могла быстро
понять назначение репозитория, выбрать нужные файлы и не загружать весь проект в контекст.
Главный навигационный индекс: [docs/WIKI-LLM.md](docs/WIKI-LLM.md).

## Концепция

Выбран **Вариант 2**: не выносить 33 внутренних инструмента `blocksnet` как отдельные MCP-tools, а
обернуть агента целиком.

Причина: ценность системы не только в расчетах, а в рассуждающем слое агента:

1. PTR-цикл `predict -> test -> revise`: фальсифицируемые гипотезы до расчетов и классификация исхода.
2. RAG по инструментам: короткие описания плюс полные карточки через `find_tools` / `get_tool_help`.
3. Инварианты качества M1-M3, C1/C2/C3, C-Hyp: проверка заземленности, измеренности и самосогласованности.
4. Измеренные предложения развития: TPE-оптимизация зон и сценарная проверка `before -> after`.

MCP-слой остается тонким: читает настройки, вызывает `BlocksNetAgent.run(...)`, сериализует результат.

## Текущий объем

Текущий MVP рассчитан на локальную работу:

| Область | Решение |
|---|---|
| Транспорт | `stdio`, сервер запускается MCP-клиентом как подпроцесс |
| Данные | локальная папка `data/` через `DATA_DIR` |
| LLM | внешний OpenAI-совместимый API (`CHAT_URL`, `API_KEY`, `MODEL`) |
| Инструмент | `analyze_urban_question(question, max_iterations?)` |
| Выход | JSON с планом, результатом, гипотезами, измеренными эффектами, ограничениями и артефактами |

Вне текущего объема: UrbanDB-контекст (`scenario_id` / `project_id`), HTTP-транспорт, Bearer-авторизация,
Docker-деплой и регистрация в MAS. В этом репозитории реализован только локальный stdio MCP.

## Архитектура MVP

```text
Локальный MCP-клиент
  -> stdio
  -> blocksnet_mcp.server
  -> tools_mcp.analyze_urban_question
  -> BlocksNetAgent.run(question)
  -> serialize.to_json(result)
  -> JSON-ответ MCP-клиенту
```

Структура репозитория:

```text
blocksnet-mcp/
├── README.md
├── .env.example
├── .gitignore
├── requirements.txt
├── .python310/          # локальный Python 3.10.11, gitignored
├── .venv/               # локальное окружение Python 3.10.11, gitignored
├── docs/
│   ├── README.md
│   ├── WIKI-LLM.md
│   ├── overview_and_concept.md
│   ├── architecture.md
│   ├── tool_contract.md
│   ├── deployment.md
│   ├── mcp_repository_plan.md
│   ├── mas_integration_reference.md    # 🕘 Future-справка, gitignored
│   └── mas_registration.md             # 🕘 Future-справка, gitignored
├── blocksnet_mcp/
│   ├── README.md
│   ├── server.py
│   ├── tools_mcp.py
│   ├── serialize.py
│   ├── settings.py
│   └── __init__.py
├── blocksnet_agent/
│   ├── README.md
│   └── ... ядро агента из blocksnet-agent (agent.py / hypotheses.py / metrics.py / tools/...)
├── data/
│   ├── README.md                 # опц., локальный индекс
│   ├── service_type.json
│   ├── archetypes.csv
│   ├── service_aliases.json
│   ├── blocks_with_services.gpkg         # gitignored
│   ├── acc_mx.pickle                     # gitignored
│   └── <local-city-sandbox>/             # gitignored (например, saint_petersburg/)
├── tests/
│   ├── README.md
│   ├── test_serialize.py
│   ├── test_tool_contract.py
│   ├── test_async_mcp_contract.py
│   ├── test_confidence_signals.py
│   ├── test_overlay_candidates.py
│   ├── test_ptr_classifier.py
│   ├── test_runtime.py
│   ├── test_provision_cache.py
│   ├── test_numeric_metric_resolution.py
│   ├── test_provision_summaries.py
│   ├── test_target_block_selection.py
│   ├── test_tool_failure_dedup.py
│   ├── test_no_data_grounding.py
│   └── test_experiment_harness.py
├── scripts/
│   ├── README.md
│   └── smoke_client.py
├── examples/
│   ├── README.md
│   ├── test_visualization.ipynb
│   ├── saint_petersburg/main.py
│   ├── saint_petersburg/data/            # gitignored
│   └── yuzhno-sakhalinsk/                # gitignored
├── docs/
│   ├── reports/
│   │   ├── test_report_20260618.md
│   │   └── run_quality_report_20260706_spb.md
│   ├── mcp_repository_plan.md    # 🕘 локальный план, gitignored
│   ├── mas_integration_reference.md    # 🕘 Future-справка, gitignored
│   └── mas_registration.md             # 🕘 Future-справка, gitignored
└── outputs/             # runtime-артефакты, gitignored
```

## Контракт инструмента

`analyze_urban_question(question: str, max_iterations: int | None = None)` возвращает **структурный JSON**
(P1.1 — payload терминального `submit_answer` агента, P1.2 — авторитетная `confidence` + самооценка
+ basis, P1.6 — `overlay_candidates` как fallback для `recommendation_blocks`):

```jsonc
{
  "question": "...",
  "analysis_plan": "...",
  "result": "...",
  "reflection": "...",
  "recommendations": [
    { "block_id": 4940, "service_type": "school", "added_capacity": null, "rationale": "..." }
  ],
  "measured_effects": [
    { "service_type": "pitch", "strong_before": 0.732, "strong_after": 0.781,
      "missing_before": 785, "missing_after": 769, "source": "compute_scenario_provision" }
  ],
  "recommendation_blocks": [4940],
  "confidence": 0.55,
  "confidence_self": 0.78,
  "confidence_basis": ["hypotheses=2/2_supported*0.25=+0.25", "data_basis=1.0*0.30=+0.30"],
  "overlay_candidates": [...],
  "overlay_meta": { "hard_passed": 5, "hard_total": 5, "diagnostic_layers": 1, "nondiagnostic_layers": 0 },
  "limitations": ["..."],
  "artifacts": ["maps/provision.png", "scenario.csv"],
  "run_id": "run_20260706_...",
  "run_dir": "outputs/run_20260706_...",
  "status": "ok",            // "ok" | "partial" | "failed"
  "salvaged": false
}
```

Полная спецификация: [docs/tool_contract.md](docs/tool_contract.md). Regex-fallback-поля
(`measured` / `hypotheses` как строковый массив) описаны там же — в fallback-пути с
`salvaged: true` и `limitations += ["SALVAGED_ANSWER"]`.

## Локальный запуск

Рабочее локальное окружение уже создано в репозитории:

| Путь | Назначение | Git |
|---|---|---|
| `.python310/` | portable Python `3.10.11` для проекта | ignored |
| `.venv/` | виртуальное окружение на Python `3.10.11` | ignored |
| `requirements.txt` | зависимости локального MCP и BlocksNetAgent | yes |

```bash
.\.venv\Scripts\python.exe -m pytest tests
.\.venv\Scripts\python.exe scripts\smoke_client.py
.\.venv\Scripts\python.exe -m blocksnet_mcp.server
```

Минимальный `.env` (текущий шаблон — Ollama Cloud; для OpenAI-совместимых endpoint'ов можно
подставить `CHAT_URL` и `MODEL` оттуда):

```env
CHAT_URL=https://ollama.com/v1
API_KEY=your_ollama_cloud_api_key_here
MODEL=minimax-m3:cloud
DATA_DIR=./data
OUTPUT_DIR=./outputs
MAX_ITERATIONS=10
```

Опционально (имеют дефолты в `settings.py`): `DEADLINE_SEC=480` — серверный дедлайн прогона,
`PROGRESS_INTERVAL_SEC=10.0` — интервал `notifications/progress`.

Пример конфигурации MCP-клиента:

```jsonc
{
  "mcpServers": {
    "blocksnet": {
      "command": "P:/AI_asistent/ITMO/blocksnet-mcp/.venv/Scripts/python.exe",
      "args": ["-m", "blocksnet_mcp.server"],
      "cwd": "P:/AI_asistent/ITMO/blocksnet-mcp",
      "env": {
        "CHAT_URL": "https://ollama.com/v1",
        "API_KEY": "your_ollama_cloud_api_key_here",
        "MODEL": "minimax-m3:cloud",
        "DATA_DIR": "./data",
        "OUTPUT_DIR": "./outputs",
        "MAX_ITERATIONS": "10"
      }
    }
  }
}
```

Подробнее: [docs/deployment.md](docs/deployment.md).

## Индексация WIKI-LLM

| Индекс | Назначение |
|---|---|
| [docs/WIKI-LLM.md](docs/WIKI-LLM.md) | Главная карта проекта для LLM-навигации |
| [docs/README.md](docs/README.md) | Человекочитаемый индекс документации |
| [blocksnet_mcp/README.md](blocksnet_mcp/README.md) | Индекс реализованного MCP-слоя |
| [blocksnet_agent/README.md](blocksnet_agent/README.md) | Индекс переносимого ядра агента |
| [data/README.md](data/README.md) (опц.) | Локальный индекс данных |
| [tests/README.md](tests/README.md) | Индекс контрактных тестов |
| [scripts/README.md](scripts/README.md) | Индекс локальных smoke-проверок MCP |
| [examples/README.md](examples/README.md) | Индекс интерактивных блокнотов и локальных примеров |

## Документация

| Документ | О чем |
|---|---|
| [docs/overview_and_concept.md](docs/overview_and_concept.md) | что строится, зачем MCP-обертка целиком, границы локального режима |
| [docs/architecture.md](docs/architecture.md) | структура, модули, поток запроса, транспорт |
| [docs/tool_contract.md](docs/tool_contract.md) | вход и выход `analyze_urban_question` |
| [docs/deployment.md](docs/deployment.md) | локальная установка и подключение MCP-клиента |
| [docs/mcp_repository_plan.md](docs/mcp_repository_plan.md) (опц.) | план переноса ядра агента и реализации MVP (локальный, gitignored) |
| [examples/test_visualization.ipynb](examples/test_visualization.ipynb) | интерактивная визуализация тестов, run logs, артефактов и карт |
| `examples/<local-city-example>/` | локальные городские примеры/датасеты (например, Санкт-Петербург, Южно-Сахалинск); данные и артефакты держать вне Git |
| `docs/mas_integration_reference.md` 🕘 | future-справка по MAS/UrbanDB, локальная и gitignored |
| `docs/mas_registration.md` 🕘 | future-строки реестра Urban services, локальная и gitignored |

## Статус

Локальный MVP реализован: ядро `BlocksNetAgent` перенесено, stdio MCP-сервер добавлен, JSON-сериализация
и контрактные тесты находятся в `tests/`. Окружение собрано на Python `3.10.11`; `pip check` чистый,
`pytest` проходит (контрактные + сериализация + P1.1/P1.2/P1.6 unit-тесты), MCP stdio smoke проходит
через `scripts/smoke_client.py`. Текущий LLM-провайдер — **Ollama Cloud** (`minimax-m3:cloud`);
контракт ответа использует P1.1 `submit_answer`, P1.2 авторитетную `confidence` + `confidence_self`
+ `confidence_basis`, P1.6 `overlay_candidates` как fallback для `recommendation_blocks`. Сводный
отчёт по результатам качества прогонов от 06.07.2026: [docs/reports/run_quality_report_20260706_spb.md](docs/reports/run_quality_report_20260706_spb.md).

Источник истины по текущему объему - этот README, [docs/WIKI-LLM.md](docs/WIKI-LLM.md), код
`blocksnet_mcp/`, контракт [docs/tool_contract.md](docs/tool_contract.md) и архитектура
[docs/architecture.md](docs/architecture.md).