Skip to main content
Glama

SEAF MCP Server

MCP-сервер для доступа к SEAF ArchTool REST API через протокол Model Context Protocol.

Быстрый старт

docker build -t seaf-mcp:latest .

Подробная инструкция по установке, запуску локального портала SEAF и подключению MCP-клиентов (OpenCode, Claude Desktop, Cursor): INSTALL.md.

Related MCP server: RSpace MCP Server

Доступные tools

Высокоуровневые (рекомендуются агенту):

Tool

Назначение

list_sections

Разделы seaf.company.* с числом объектов и описанием

list_entities

Объекты раздела с фильтрами (eq/ne/contains/missing/exists); фильтрация и пагинация на портале

describe_section

Атрибуты раздела (с частотой), поля-связи (исходящие/входящие), примеры ID

inspect_sections

1-5 разделов за вызов: структура + до 3 образцов на раздел (образцы ограничены)

find_entities

Поиск по подстроке в ID/title/description

get_entity

Объект по ID

get_relations

Связи объекта: outgoing и incoming, сгруппированные по полю

metamodel_guide

Справочник метамодели (также MCP-ресурс seaf://metamodel-guide)

get_dataset

Именованный датасет seaf.company.ds.* целиком (например seaf.company.ds.people)

query_dataset

JSONata поверх датасета: origin — ID или {алиас: id}, source — выражение (включая служебные seaf.ds.*)

describe_query_result

Описание результата JSONata-запроса: тип, count, поля с покрытием по выборке 100, до 3 примеров

seaf_jsonata_query

Произвольный JSONata (POST)

find_jsonata_examples

Проверенные примеры JSONata: keyword-поиск по вопросу/группе/разделам

find_relation_paths

Многошаговые пути связей между разделами (BFS по карте $rels, до 10 маршрутов ≤5 шагов)

Плюс raw: get_health, get_seaf_core_api_core_storage_problems, get_seaf_core_api_core_storage_versions. Остальные endpoints каталога помечены "hidden": true.

Какой tool выбрать (пересекающиеся пары):

  • describe_section — один раздел без образцов; inspect_sections — 1-5 разделов с образцами (перед запросом со связями).

  • seaf_jsonata_query — JSONata по манифесту модели; query_dataset — JSONata по датасету (другой корневой $).

  • find_entities — примерное название → ID; list_entities — точные фильтры по полям в известном разделе.

Каждое описание tool построено как «Когда вызывать → что вернёт → Дальше».

Связи берутся из формальной схемы: при первом вызове сервер читает $manifestschema() и строит карту поле → раздел по $ref: #/$rels/... (с учётом allOf/$defs), затем кэширует её. Пользовательский ввод подставляется в JSONata только как JSON-литерал.

Справочник метамодели — src/seaf_mcp/data/metamodel_guide.md. Cookbook проверенных запросов — src/seaf_mcp/data/jsonata_cookbook.json (интеграционный тест выполняет каждую нешаблонную запись на портале, так что примеры не устаревают); пополняется по JSONL-журналу (SEAF_JSONATA_LOG_FILE + SEAF_JSONATA_LOG_INCLUDE_QUERY=true).

Исключенные endpoints

  • PUT/DELETE/PATCH и POST без readOnly=true — записывающие операции

  • Wildcard paths (/:hash/*)

  • SSE endpoints (/chat/message)

Правила

  • Схемы аргументов строгие (additionalProperties: false): неизвестные/недостающие параметры возвращаются агенту как ошибка.

  • Path-параметры URL-кодируются полностью (/ → %2F), т.е. JSONata-запрос можно передавать как есть.

  • При старте сервер падает, если в каталоге есть дублирующиеся имена tools или один параметр объявлен в нескольких местах (path/query/body).

Формат ответов

Request:
GET /seaf-core/api/core/storage/versions

Status:
200

Response:
{
  "archHash": "...",
  "coreVersion": "2026.31.0",
  "enableChecker": true
}

Длинные ответы обрезаются по MAX_RESPONSE_CHARS (лимит — на весь текст ответа, включая заголовки и примечание): [truncated: showing N of M chars — <подсказка>]. Для массивов примечание сообщает исходное число элементов и советует фильтр/проекцию или индексный фильтр [[a..b]]; для объектов — число ключей и первые из них.

Пустой успешный результат (undefined, null, [], {}) помечается явно: The request succeeded, but the result is empty (...) — false и 0 пустыми не считаются.

Ошибки API:

API request failed

Tool: get_seaf_core_api_core_storage_versions
Status: 404
Message:
Not found

Сетевые ошибки (нет соединения, таймаут) возвращаются как Tool execution failed с подсказкой.

Preflight: известные дорогие/ошибочные конструкции отклоняются до запроса к порталу (голый $, ~> $count($), позиционный диапазон x[a..b], slice x[a:b], $lookup("строка", …), $take/$slice/$group/$values без объявления). Строки, комментарии, backtick-имена и regex-литералы при проверке игнорируются; индексный фильтр x[[a..b]] разрешён.

Ошибки JSONata (коды S0xxx/T0xxx) сопровождаются подсказкой по исправлению — только в tools, где выражение пишет агент (seaf_jsonata_query, query_dataset): неподдерживаемый синтаксис (позиционный диапазон, slice, ~, ?.), отсутствующие функции ($take/$slice/$group/$values с полифиллами), баг $ в цепочке ~> и т.д. Стек и дамп контекста из тела ошибки срезаются.

Структура проекта

seaf-mcp/
├── src/seaf_mcp/
│   ├── __main__.py            # python -m seaf_mcp
│   ├── server.py              # MCP сервер
│   ├── config.py              # Конфигурация из env vars
│   ├── endpoint_catalog.py    # Загрузка endpoints.json
│   ├── tool_factory.py        # Фильтрация, генерация tools, валидация аргументов
│   ├── seaf_tools.py          # Высокоуровневые tools (разделы, поиск, связи)
│   ├── rest_client.py         # Async HTTP клиент
│   ├── response_formatter.py  # Форматирование и обрезка ответов
│   ├── data/
│   │   └── metamodel_guide.md # Справочник метамодели SEAF
│   └── errors.py
├── tests/
├── endpoints.json
├── requirements.txt / requirements-dev.txt
└── Dockerfile

Особенности SEAF API (проверено на 2026.31.0)

  • GET .../jsonata/:query с произвольным выражением → 403 Access denied; используйте seaf_jsonata_query (POST).

  • Запрос без внешних скобок SEAF трактует как ID предопределённого запроса (Cannot read properties of undefined). seaf_jsonata_query оборачивает выражение в (...) автоматически (поле каталога jsonataParams).

  • POST не поддерживает params — подставляйте значения прямо в выражение.

  • Весь манифест ($) ≈ 4 MB — будет обрезан по MAX_RESPONSE_CHARS.

  • Датасеты (get_dataset): POST release-data-profile, только seaf.company.ds.* (служебные seaf.ds.* — десятки МБ). Неизвестный ID → HTTP 200 с null.

Интеграционные тесты:

  • локальный портал (example manifest): SEAF_IT_URL=http://localhost:8080 .venv/bin/pytest tests/test_integration_portal.py

  • любой развёрнутый портал: SEAF_CORP_IT_URL=https://seaf-portal.example.com .venv/bin/pytest tests/test_integration_corp.py

Дальше

  • Авторизация при обращении к API

  • Импорт каталога endpoints из OpenAPI, если спецификация появится

Разработка

python3 -m venv .venv
.venv/bin/pip install -r requirements-dev.txt
.venv/bin/pytest

# Локальный запуск
API_BASE_URL=https://seaf-portal.example.com ENDPOINT_CATALOG_PATH=endpoints.json \
  PYTHONPATH=src .venv/bin/python -m seaf_mcp

Available Tools

17 tools
describe_query_resultОписание результата запросаA
Read-onlyIdempotent

Когда вызывать: ПЕРЕД seaf_jsonata_query, когда не уверены в форме результата запроса. Возвращает тип (array/object/scalar/missing), count по всему результату, поля с покрытием present_in k/n по первым 100 элементам и до 3 примеров (≤1500 символов каждый); схема строится по выборке — это разведка, а не полная схема. Терминальные агрегаты ($count, $sum) — скаляр в value. Дальше: seaf_jsonata_query с уточнённым запросом.

Inputs: query (required), query_goal.

describe_sectionСтруктура разделаA
Read-onlyIdempotent

Когда вызывать: нужна структура ОДНОГО раздела без образцов — атрибуты с частотой, исходящие/входящие поля-связи, примеры ID. Для образцов данных и нескольких разделов сразу используйте inspect_sections. Дальше: list_entities (выборка по фильтрам) или describe_query_result (разведка перед JSONata).

Inputs: section (required).

find_entitiesПоиск объектовA
Read-onlyIdempotent

Когда вызывать: известно только примерное название объекта (система, сервис, человек) — поиск по подстроке в ID/title/description всех разделов (или одного). Возвращает total и items {section, id, title}. Когда раздел и условия по полям известны точно, эффективнее list_entities. Дальше: get_entity или get_relations по найденному id.

Inputs: text (required), limit, section.

find_jsonata_examplesПримеры JSONataA
Read-onlyIdempotent

Когда вызывать: перед написанием JSONata — взять проверенный пример похожего запроса (keyword-поиск по вопросу, группе, разделам и тексту выражения; русские словоформы совпадают по префиксу). Возвращает до limit (по умолчанию 5) примеров {id, question, sections, expression, explanation}; записи с template=true требуют подстановки реального ID. При настроенном SEAF_METAMODEL_PATH после проверенных примеров идут фрагменты YAML метамодели с пометкой файла. Дальше: seaf_jsonata_query с адаптированным выражением.

Inputs: queries (required), limit.

find_relation_pathsПути связей разделовA
Read-onlyIdempotent

Когда вызывать: нужно понять, через какие поля и разделы связаны два раздела (например, people и products), прежде чем писать JOIN. Возвращает до 10 кратчайших маршрутов (до 5 шагов): каждый шаг — from_section, field, to_section, direction (out/in); данные сущностей не возвращаются, JOIN не выполняется. via_sections ограничивает промежуточные разделы. Дальше: find_jsonata_examples (группа relations) или seaf_jsonata_query.

Inputs: end_section (required), start_section (required), via_sections.

get_datasetДатасет целикомA
Read-onlyIdempotent

Когда вызывать: нужен именованный датасет представлений ЦЕЛИКОМ (только seaf.company.ds., например seaf.company.ds.people: записи людей с полями title/ФИО, role, department и техническими id/link_to_card). Возвращает объект объектов (ключ — ID записи). Для выборок по датасету и служебных seaf.ds. — query_dataset. Дальше: query_dataset с фильтром.

Inputs: dataset_id (required), params.

get_entityОбъект по IDA
Read-onlyIdempotent

Когда вызывать: известен точный ID объекта (например example.app_system.hotel_booking). Возвращает раздел и все атрибуты объекта. ID неизвестен — сначала find_entities. Дальше: get_relations для связей объекта.

Inputs: id (required).

get_healthПроверка порталаA
Read-onlyIdempotent

Когда вызывать: проверить доступность портала (health-check). Возвращает {"message": "app is alive"}. Дальше: list_sections.

Endpoint: GET /health

Inputs: no named parameters.

get_relationsСвязи объектаA
Read-onlyIdempotent

Когда вызывать: нужны связи объекта — outgoing (на что он ссылается) и incoming (кто ссылается на него: подсистемы — incoming is_part_of, компоненты — incoming realizes_system, таблицы — incoming system). Возвращает группы по полю с count, до limit элементов и title. У крупных объектов сужайте direction/field. Дальше: get_entity на связанном id.

Inputs: id (required), field, limit, direction.

get_seaf_core_api_core_storage_problemsПроблемы манифестаA
Read-onlyIdempotent

Когда вызывать: увидеть ошибки валидации, найденные при загрузке манифеста. Дальше: зависит от найденных проблем.

Endpoint: GET /seaf-core/api/core/storage/problems/

Inputs: no named parameters.

get_seaf_core_api_core_storage_versionsВерсия порталаA
Read-onlyIdempotent

Когда вызывать: узнать версию ядра портала и хэш манифеста. Дальше: list_sections.

Endpoint: GET /seaf-core/api/core/storage/versions

Inputs: no named parameters.

inspect_sectionsОбзор разделовA
Read-onlyIdempotent

Когда вызывать: нужны структура И образцы сразу 1-5 разделов, например перед запросом со связями между типами. Возвращает по каждому разделу count, атрибуты, поля-связи и до sample_limit (1-3, по умолчанию 2) ограниченных образцов; раздел целиком не выгружается. Для одного раздела без образцов достаточно describe_section. Дальше: seaf_jsonata_query со связывающим запросом. При включённом API_MIN_INTERVAL_SECONDS время ответа растёт пропорционально числу разделов.

Inputs: sections (required), sample_limit.

list_entitiesОбъекты разделаA
Read-onlyIdempotent

Когда вызывать: нужны объекты раздела с точными фильтрами по полям (eq/ne/contains/missing/exists) и пагинацией — выполняется на портале. Пример: системы без стейкхолдеров — where=[{field:'stakeholders',op:'missing'}]. Поля через точку (stakeholders.name); для массивов eq/contains срабатывает на любой элемент; булевы — 'true'/'false'. Не знаете раздел — list_sections; ищете по примерному названию — find_entities. Возвращает {section,total,offset,items}. Дальше: get_entity по id из items.

Inputs: section (required), limit, where, fields, +1 more.

list_sectionsРазделы моделиA
Read-onlyIdempotent

Когда вызывать: в начале работы или когда неизвестно, в каком разделе искать данные. Возвращает разделы seaf.company.* с числом объектов и описанием. Дальше: inspect_sections (структура и образцы нескольких разделов) или describe_section (один раздел без образцов).

Inputs: no named parameters.

metamodel_guideСправочник SEAFA
Read-onlyIdempotent

Когда вызывать: нужны понятия метамодели SEAF, смысл отношений и проверенные приёмы JSONata (чек-лист, паттерны, ловушки). Возвращает текст справочника. Дальше: list_sections.

Inputs: no named parameters.

query_datasetЗапрос к датасетуA
Read-onlyIdempotent

Когда вызывать: нужна выборка JSONata поверх именованного датасета (корневой $ — данные датасета; для манифеста модели — seaf_jsonata_query). origin — ID датасета или {алиас: dataset_id} (тогда $ — мапа, датасет как $."алиас"); source оборачивается в (...) автоматически. Возвращает результат выражения; доступны любые датасеты, включая seaf.ds.* — сужайте выборку: ответ считается на портале целиком. Дальше: seaf_jsonata_query, если данных нет в датасете.

Inputs: origin (required), source (required), params.

seaf_jsonata_queryЗапрос JSONataA
Read-onlyIdempotent

Когда вызывать: нужен произвольный JSONata по манифесту модели (корневой $ — манифест); для датасетов — query_dataset, для разведки формы результата — describe_query_result. Возвращает результат выражения; ошибки JSONata (S0xxx/T0xxx) приходят с подсказкой по исправлению. Дальше: get_entity/list_entities для типовых выборок без JSONata.

Endpoint: POST /seaf-core/api/core/storage/jsonata

Inputs: query (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 17 tools

    Disambiguation4/5

    The discovery cluster (list_sections / describe_section / inspect_sections) and the lookup cluster (get_entity / find_entities / list_entities) overlap conceptually, but the descriptions explicitly state when to prefer each and cross-reference alternatives. The JSONata family (query_dataset / seaf_jsonata_query / describe_query_result / find_jsonata_examples) is likewise differentiated by scope (dataset vs manifest vs result-shape vs examples). A few boundaries remain soft, but an agent can pick correctly.

    Naming Consistency3/5

    Most tools follow a clean verb_noun snake_case pattern (list_sections, get_entity, find_entities, describe_query_result). However, two tools are auto-derived raw endpoint names (get_seaf_core_api_core_storage_versions, get_seaf_core_api_core_storage_problems) that break the convention badly, and seaf_jsonata_query adds an inconsistent domain prefix.

    Tool Count4/5

    17 tools is on the heavier side but each maps to a distinct step in the discovery→inspect→query workflow, so they mostly earn their place. It could be trimmed (e.g. merging versions/problems into a diagnostics tool), but it is not bloated for the domain.

    Completeness4/5

    The surface covers health, section/structure discovery, entity lookup and relation traversal, metamodel guidance, JSONata examples, dataset access, query execution and result introspection — a full read-oriented lifecycle. Gaps are minor: no explicit dataset enumeration, and no write operations if mutation is in scope, but the read/query workflow has no dead ends.

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      B
      quality
      D
      maintenance
      A Model Context Protocol server that provides AI agents with read-only access to Rossum API resources (queues, schemas, hooks, workspaces) for analysis purposes.
      6
      2
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to perform corpus analysis tasks such as discovery, search, and data access via the Model Context Protocol.
      12
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables AI agents to query Fangorn subgraph schemas and conformant data from published data sources via the Model Context Protocol.
      13
      2
      ISC