MCP — technology preview
MCP не входит в стабильный Core 0.3. ifc-mcp содержит независимые от транспорта
семантические read-only запросы, а ifc-mcp-server — локальный JSON-RPC/MCP
stdio-адаптер. В ядре нет LLM-клиента, учётных данных и сетевого транспорта.
Доступные инструменты сервера
Семантические этапы 1–2 используют ifc-mcp-server.dto.v3:
open_model— открыть IFC, определить официальную схему и один раз построить переиспользуемые индексы;close_model— идемпотентно закрыть модель и освободить исходные байты, индексы и диагностики;model_info— схема IFC, ревизия, размер, число сущностей, краткая пространственная сводка, назначения единиц и сводка диагностик;model_diagnostics— ограниченная страница диагностик с фильтрами severity/code;search_entities— поиск по IFC-типам и подтипам, имени, GlobalId и пространственному контейнеру;get_spatial_tree— страница пространственных узлов с сохранением родительских связей;get_elements_in_container— элементы контейнера напрямую или рекурсивно;get_entity— семантическая карточка сущности;get_entity_raw— отдельная исходная STEP-запись.
До следующих этапов сохранены прежние get_properties и get_relations, а также
IDS-инструменты. model_summary и find_entities больше не рекламируются;
прежнее raw-поведение get_entity перенесено в get_entity_raw.
Диагностики ограничиваются ещё во время сбора: при полном проходе сохраняется
точный счётчик, а при исчерпании bounded validation work summary явно помечается
как неполная; материализованные details не превышают server limit. Маркер
diagnostics_truncated сохраняется независимо от severity/code filters. Name
читается по позиции из EXPRESS metadata, GlobalId применяется только к
потомкам IfcRoot; перед созданием owned-строки semantic projection проверяет
официальный предел IfcGloballyUniqueId в 22 байта, а oversized malformed
значение остаётся доступно через raw STEP. casefold_exact/contains используют
полный Unicode case folding. get_entity отдельно декодирует только Name, Description и
PredefinedType с query budget/deadline. Неизвестный IFC-тип и malformed Name
возвращают typed errors. Для raw STEP размер source range проверяется до
копирования; encoded lossy/JSON размер оценивается без создания полной строки,
а не-UTF-8 байты остаются доступны через lossy UTF-8 projection с символом
замены. Summary-списки model_info прекращают сбор после контрольного элемента
сверх лимита и используют общий entity budget/deadline; отсутствующий в активной
схеме IfcFacility не запускает model scan. Scanner DiagnosticsLimit всегда
делает diagnostic total нижней границей и сохраняет маркер усечения.
close_model проверяет размер ответа до освобождения модели. Успешное закрытие и
ошибки open_model/close_model входят в корневую JSON Schema DTO v3; lifecycle
ошибки возвращают стабильный diagnostic code без фиктивной ревизии модели.
Полная проверка модели без query indexes строит один компактный type lookup и не
повторяет линейный поиск для каждой IFC-ссылки. Stage 1 удерживает bounded
профиль Express ID/type/GlobalId/reference/Pset-Qto, чтобы сохранённые
get_properties и get_relations не возвращали ложные пустые ответы.
max_index_bytes ограничивает индексы; общий registry budget дополнительно
учитывает capacity source, scanner/type metadata, полный EXPRESS AST, model
caches, диагностики и session allocation. Нехватка памяти для обязательного
индекса или полной retained session прерывает открытие, а rollback/close
освобождают полный charge. Malformed IFC type проверяется до owned-copy и
отображается коротким
<invalid_ifc_type>, сохраняя доступ к raw STEP. Model-bound string prechecks
используют DTO v3 error envelope. max_response_entities ограничивает общий
набор ссылок model_info и запрошенную страницу поиска.
Контракт запросов
open_model принимает schema + path + context, close_model —
schema + model_id + context. Остальные запросы принимают:
{
"schema": "ifc-mcp-server.dto.v3",
"model_ref": {
"model_id": 1,
"expected_revision": 0
},
"arguments": {},
"context": {
"request_id": "request-1",
"budget": {
"max_entities_scanned": 100000,
"max_values_decoded": 100000,
"max_relation_expansions": 100000,
"max_response_bytes": 1048576,
"soft_timeout_ms": 5000
}
}
}
Поиск возвращает не более 1 000 элементов на страницу. Курсор связан с tool,
моделью, ревизией и полным нормализованным запросом. Пространственные фильтры container, storey_id, space_id поддержаны.
Материальные, классификационные и property-фильтры отклоняются до этапа 3,
а не игнорируются.
Лимиты по умолчанию: 512 MiB на модель, 8 открытых моделей, Express ID до 10 000 000, 4 KiB на строковый аргумент, 10 000 сохранённых диагностик/ID и 1 MiB на входной кадр. Ответ дополнительно ограничен бюджетом запроса.
Запуск
cargo build --release -p ifc-mcp-server
./target/release/ifc-mcp-server
Пример конфигурации MCP-клиента:
{
"mcpServers": {
"ifccore": {
"command": "/absolute/path/target/release/ifc-mcp-server",
"args": []
}
}
}
Сервер может читать любой файл, доступный его пользователю ОС. Ограничьте права процесса и рабочий каталог: сетевую песочницу сервер не создаёт. Подробности: MCP preview.
Семантический Stage 3
Добавлены get_entity_relations, get_materials, get_quantities и v3-формы
get_property/get_properties. Legacy-формы и IDS family сохранены.
Значения содержат IFC datatype, единицы, независимые происхождение/владение и
точный association path; одноимённые instance/type значения перечисляются отдельно.
Поиск поддерживает material/classification/property predicates до пагинации,
с cumulative budget и filter_coverage (material → classification → properties).
get_quantities не подменяет Qto геометрией.
Preview поддерживает скалярные attributes, IfcPropertySingleValue, complex
containers и простые Qto. Остальные property/aggregate kinds, неизвестные relation
kinds и неподдержанные единицы завершаются типизированной ошибкой. Подробности,
формы запросов и приёмочные тесты: MCP technology preview.
Viewer, запись IFC и deployment не меняются.
Stage 6: семантические adapters
Первый последовательный блок добавляет get_entity_location,
get_related_entities, find_by_property, find_by_material,
material_summary, quantity_coverage, summarize_entities поверх общих
Stage 1–4 engines. Все они используют model/revision-aware DTO v3 и остаются
read-only. Геометрия, временные Viewer sessions и Stage 5 preview release
не объявляются готовыми наличием этих adapters. Актуальные ограничения и
приёмка: канонический план.
Stage 6: геометрические запросы
Добавлены get_bounding_box, get_geometry_metrics, query_elements_in_box.
Они используют существующий ifc-geometry, а не значения Qto; происхождение
помечено computed_geometry. Координаты ifc_model_world учитывают placements,
но не означают геореференсированную CRS. Единица берётся из project
UnitsInContext; отсутствие, неоднозначность и неподдержанная length unit
дают явную ошибку, а не молчаливое предположение метров.
Профиль ограничен 50 000 записями, 4 MiB исходного диапазона, 1 000 продуктами, 200 000 треугольниками, 64 MiB geometry и 128 развёрнутыми mesh-объектами. Пользователь может только уменьшить эти пределы. До построения pipeline проверяется вся модель; для decode/relation budget применяется консервативная оценка source bytes × число продуктов. Большая модель может быть отклонена, даже если выбран один простой элемент. Это ограничение preview, а не SLA. Синхронная extraction не имеет cooperative cancellation: мягкий deadline проверяется до/после вызова, geometry engine сохраняет собственные hard limits.
AABB query использует общий EntityFilter, затем пересечение мировых AABB; это не точное пересечение solid с областью. Неподдержанный либо частичный Body не становится нулевым bbox. Метрики вычисляются по tessellated mesh; значения для непроверенной топологии недоступны с причиной. Объём нескольких mesh не объявляется объёмом их объединения. Точность зависит от tessellation ядра.
ifc-geometry — уже существующая внутренняя зависимость workspace с лицензией
проекта. Стандартная библиотека не предоставляет IFC tessellation. Новые
внешние пакеты не добавлены; MCP crate получает geometry dependency, stable
facade API и существующий Viewer не меняются. Геометрическое ядро поддерживает
WASM, но этот adapter принимается отдельно от стабильного WASM-релиза.
Приёмка: stage6_geometry (IFC2X3/IFC4/IFC4X3, placements, единицы, budgets,
cursors) и реальный stdio-сценарий синтетической модели двух параллелепипедов.
Локальные Viewer-сессии реализованы отдельным opt-in блоком ниже.
Stage 6: локальные Viewer-сессии — реализовано
create_viewer_session, update_viewer_selection, close_viewer_session
доступны в MCP DTO v3. По умолчанию backend выключен и возвращает
viewer_disabled. Включение разрешено только host при запуске:
ifc-mcp-server --enable-local-viewer
MCP transport остаётся stdio. Дополнительный HTTP listener привязан только
к 127.0.0.1 на случайном порту и отдаёт read-only HTML/mesh/selection.
Viewer не публикует исходные IFC, filesystem paths или операции редактирования.
Нет CDN и hosted upload. Браузер должен работать на том же компьютере, что и
MCP server; loopback URL удалённой ВМ не является публичной ссылкой.
Create принимает либо entity_ids (до 16), либо общий filter, а также
selection, ttl_seconds (1–900, по умолчанию 300) и geometry limits.
Превышение 16 выбранных фильтром сущностей отклоняется, а не усекается.
Все выбранные объекты должны иметь поддержанную геометрию. Ответ:
viewer_session_id, url, model_id, model_revision, ttl_seconds.
Update принимает viewer_session_id и selection; close — только handle.
Все вызовы используют обязательный model_ref и сначала проверяют revision.
URL содержит случайный 256-битный bearer token в fragment. Браузер удаляет его из адресной строки и передаёт в Authorization; Host, Origin, Sec-Fetch-Site, CSP, no-store и no-referrer ограничивают browser boundary. Token даёт доступ к сцене любому локальному клиенту, который им владеет: это capability, не аутентификация пользователя ОС и не multi-tenant sharing. Actor boundary — экземпляр stdio server; чужой process manager не разделяет его session store.
Максимум 4 сессии, 8 MiB сериализованной сцены и 16 MiB суммы JSON payloads. Дополнительно удерживаются типизированные mesh buffers и ограниченные временные копии при сериализации/HTTP-ответе; JSON quota не заявляется как полный RSS. Исходные IFC-копии и временные файлы сессий не создаются. TTL timer очищает сессии без HTTP-трафика; close/close_model отзывают ссылки и освобождают сохранённую сцену. Уже начатый HTTP-ответ может завершиться после отзыва; следующие запросы получают 410. Lifecycle lock исключает создание новой сцены параллельно закрытию модели. Браузер очищает canvas/GPU buffers при отзыве, истечении срока или недоступности endpoint.
Приёмка: unit security/lifecycle tests, реальный MCP stdio open/create/update/
close/close_model и scripts/test-mcp-viewer-session.mjs с Chromium. Браузерный
тест открывает настоящий Rust server и IFC fixture, получает 2 mesh/24 triangles,
меняет подсветку 2 → 3, проверяет орбиту, закрытие и независимый TTL. Mock HTTP
не используется как доказательство сквозной приёмки.
Зависимость server-only getrandom 0.3.4 уже присутствовала в Cargo.lock;
лицензия MIT OR Apache-2.0. Она нужна для системной криптографической энтропии,
которой нет в portable std API. Вызывается только при создании сессии,
не добавляется в transport-free MCP или stable WASM facade; количественный
эффект на размер/сборку не заявляется. Hosted service и write-tools отсутствуют.
Stage 5 preview release не считается завершённым реализацией Stage 6.