dot-lit
transport-lit — серая литература по транспорту через MCP
(Переименовано из dot-lit 2026-08-27; переменные окружения DOT_LIT_* и старая директория данных по-прежнему распознаются.)
transport-lit предоставляет ИИ-ассистенту (Claude Desktop, Claude Code, любому MCP-клиенту) поиск по ключевым словам в отчётах о транспортных исследованиях, которые PubMed не индексирует, а Semantic Scholar покрывает плохо. Всё началось с ROSA-P — репозитория Национальной транспортной библиотеки США (отчёты NHTSA DOT HS, исследования FHWA/FRA/FTA/FAA, UTC и транспортных департаментов штатов; https://rosap.ntl.bts.gov), а теперь собирает данные из шести источников OAI-PMH на трёх континентах, плюс всё, что вы экспортируете из TRID:
ключ | источник | записей | примечания |
| ROSA-P — Национальная транспортная библиотека DOT США | 90,599 | полный репозиторий |
| VTI — Шведский национальный дорожно-транспортный исследовательский институт (DiVA) | 11,460 | отчёты, материалы конференций, статьи; en/sv |
| BASt — Немецкий федеральный дорожный исследовательский институт (OPUS) | 2,970 | 1 901 с прямыми ссылками на PDF; de/en |
| World Bank Open Knowledge Repository | 976 | подмножество из 40 332, отфильтрованное по заголовкам; измеренная точность 18/20 |
| IPEA (Бразилия) | 207 | отфильтрованное подмножество из 14 400; pt; точность ~16/20 |
| CEPAL/ECLAC (Латинская Америка) | 1,165 | отфильтрованное подмножество из 52 199; es/en; точность ~15/20 |
| OpenAlex — работы типа report по 10 транспортным темам (глобально) | 11,448 | темы: Безопасность дорожного движения, Городской транспорт и доступность, Транспортное планирование, … |
| CiNii Research (Япония) — статьи, диссертации, материалы репозитория IRDB | 118,609 | требуется бесплатный идентификатор приложения NII ( |
| PubMed — подмножество транспорт/травмы (стратегия MeSH + 12 журналов) | 105,028 | сбор E-utilities с разбивкой по датам; |
| Экспорт TRID, который вы импортируете ( | ваши | см. ниже |
transport-lit sources выводит их список; transport-lit harvest --source <key>|all собирает их; фильтр collection в search_reports выбирает один (например, "VTI", "BASt", "World Bank", "CEPAL", "TRID"). Добавление ещё одного репозитория OAI-PMH — это одна запись в src/transport_lit/sources.py.
Я создал это для личного академического и исследовательского использования и рад поделиться с теми, кому это полезно. Приветствую отзывы об ошибках, потребностях в интеграции, улучшениях и других комментариях. Я буду регулярно их проверять и по возможности интегрировать, документируя это. Если вы заинтересованы в поддержке или у вас есть другие идеи — приветствую! — Алекс Квистберг (открыть issue)
Это работает единственным способом, подходящим для источника OAI-PMH: он собирает метаданные всего репозитория в локальную базу данных SQLite, строит полнотекстовый индекс FTS5 и обслуживает поиск из этого индекса. В реальном времени ничего не запрашивается, кроме необязательной загрузки PDF для полного текста. Повторные сборы инкрементальны (from= в запросе OAI) и дёшевы.
Инструменты
Инструмент | Что возвращает |
| Ранжированные результаты: id, заголовок, авторы, год, номера отчётов, DOI, URL страницы, фрагмент аннотации, |
| Точное совпадение по DOI, PMID, номеру отчёта ("DOT HS 813 097"), id или URL страницы |
| Полная запись метаданных, включая все исходные поля, как они были собраны |
| Находит PDF (страница ROSA-P, прямые ссылки BASt/OpenAlex), извлекает и кэширует текст; страница с |
| Ищет внутри всего уже извлечённого текста PDF, с фрагментами |
| Связанные записи из разных источников по заголовку и предметным терминам |
| RIS (Zotero/EndNote/Mendeley) или BibTeX для списка id |
| Работы, на которые ссылается запись (OpenAlex, кэшируется); записи содержат |
| Работы, цитирующие запись; |
| Записи, добавленные в индекс за последние N дней, с количеством по источникам — сырьё для еженедельного дайджеста |
| Коллекции и типы документов с количеством |
| Количество записей по источникам, последний запуск и его статус/примечания, покрытие по годам |
Плюс один промпт, literature_scan(topic), который проводит модель через многоэтапный поиск с цитированием. Каждый инструмент несёт аннотации MCP (readOnlyHint, idempotentHint; только get_fulltext имеет openWorldHint, так как может загрузить один PDF).
id принимает dot:93144, 93144, oai:dot.stacks:dot:93144 или URL страницы. Импортированные записи используют другие префиксы (trid:813520, import:…).
Синтаксис запроса: отдельные слова сначала объединяются по И; если меньше limit результатов соответствуют всем терминам, оставшиеся слоты заполняются совпадениями по любому термину (match_mode = all_terms / any_terms). Заключайте фразы в кавычки ("driver improvement"), используйте завершающую * для префикса. Ранжирование — BM25, при этом заголовок, номер отчёта и автор имеют больший вес, чем аннотация.
Related MCP server: litedocs-mcp
Установка
Требуется Python 3.12+ и uv.
git clone https://github.com/aquistbe/transport-lit && cd transport-lit
uv tool install . # installs `transport-lit` (CLI) and `transport-lit-mcp` (server) on PATH
export TRANSPORT_LIT_CONTACT=you@example.org # identifies your harvester to ROSA-P (put it in your shell profile)
transport-lit probe # live check: Identify / ListMetadataFormats / ListSets
transport-lit harvest # full harvest the first time (~15 min), incremental afterwards
transport-lit status # counts, last run, coverage by year
transport-lit search driver improvement program evaluationДля разработки используйте uv sync и добавляйте префикс uv run к командам (например, uv run pytest).
Любой MCP-клиент, любая модель
Сервер говорит на стандартном MCP через stdio (по умолчанию) и Streamable HTTP / SSE (transport-lit-mcp --transport streamable-http --port 8765, конечная точка /mcp). transport-lit mcp-config [client] выводит готовый к вставке фрагмент для: Claude Desktop, Claude Code, Cursor, VS Code (режим агента Copilot), Zed, Continue, LM Studio, Goose, Open WebUI и LibreChat (последние два через HTTP). Dockerfile собирает образ HTTP-сервера с индексом на томе.
Открытые модели. Протестировано сквозным образом 2026-08-26 с Ollama qwen2.5:3b (3 млрд параметров) через tests/ollama_smoke.py: на запрос "найди отчёты о программах улучшения водителей; перечисли 3 заголовка с годами и id" модель один раз вызвала search_reports({"query": "driver improvement", "limit": 3}) и ответила правильными заголовками, годами, id и URL страниц из трёх источников. Дизайн-решения, которые позволяют работать маленьким моделям: десять инструментов с описаниями, начинающимися с одной строки, плоские JSON-аргументы со значениями по умолчанию, компактные объекты результатов (без сырых метаданных в результатах поиска) и строка instructions на сервере, которая называет источники и фильтры. Запустите смоук-тест с любой моделью, поддерживающей инструменты: OLLAMA_MODEL=llama3.1 uv run python tests/ollama_smoke.py "…".
Регистрация в Claude Desktop
transport-lit install-claude-desktop # prints the JSON to add
transport-lit install-claude-desktop --write # merges it into claude_desktop_config.json (keeps a .bak)Запись, которую он создаёт, выглядит просто:
{ "mcpServers": { "transport-lit": { "command": "/Users/you/.local/bin/transport-lit-mcp", "args": [],
"env": { "TRANSPORT_LIT_DATA_DIR": "/Users/you/.local/share/transport-lit",
"TRANSPORT_LIT_CONTACT": "you@example.org" } } } }После этого перезапустите Claude Desktop. Для Claude Code: claude mcp add transport-lit -- transport-lit-mcp.
Конфигурация (переменные окружения)
Переменная | По умолчанию | Назначение |
|
| База данных SQLite, необработанные страницы OAI ( |
| (unset) | Ваш e-mail, помещается в User-Agent, чтобы репозиторий мог с вами связаться. Установите его. |
|
| Минимальное количество секунд между исходящими запросами |
|
| Тайм-аут на запрос (с) |
| 80 MB | Отклонять PDF-файлы большего размера в |
| 600 | Остановить извлечение после этого количества страниц |
| (unset) | Идентификатор приложения NII; требуется для сбора CiNii (регистрация на support.nii.ac.jp/en/cinii/api/developer) |
| (unset) | Необязательно; повышает лимит PubMed E-utilities с 3 до 10 запросов/с |
| built-in strategy | Заменить стратегию поиска PubMed |
| fastembed / MiniLM-L12 / 1024 | Бэкенд семантического поиска, модель, усечение Ollama |
|
| Конечная точка Ollama для бэкенда |
Переменные также могут находиться в ~/.config/transport-lit/env в виде строк KEY=VALUE (реальные переменные окружения имеют приоритет); именно там должны находиться идентификатор приложения NII или ключ NCBI, чтобы задания launchd, MCP-сервер и ручные запуски все их видели. Никакие учетные данные не требуются; все конечные точки являются общедоступными.
Установка из PyPI (без клонирования)
uv tool install transport-lit # CLI + MCP server on PATH
uvx --from transport-lit transport-lit-mcp # or run the server ad hoc
uv tool install "transport-lit[semantic]" # with the bundled embedding backendОпубликовано на https://pypi.org/project/transport-lit/ через доверенную публикацию GitHub: тег запускает release.yml (сборка, релиз GitHub), который затем отправляет publish.yml — единственный рабочий процесс, зарегистрированный как доверенный издатель, — где загрузка ожидает одобрения сопровождающего в окружении pypi. PyPI отклоняет токены из переиспользуемых рабочих процессов и сопоставляет файл рабочего процесса верхнего уровня, поэтому публикация является отдельным отправленным рабочим процессом, а не заданием внутри релиза. server.json — это манифест для MCP Registry (registry.modelcontextprotocol.io), который нужно отправить после того, как пакет PyPI будет существовать.
Зафиксированные версии
Релизы — это git-теги vMAJOR.MINOR.PATCH (семантическое версионирование: patch = исправления, minor = новые инструменты/источники, major = критическое изменение поверхности инструментов или схемы базы данных). Каждый тег запускает рабочий процесс release, который выполняет тесты, собирает wheel + sdist и прикрепляет их к GitHub Release. Зависимости Python зафиксированы в коммите uv.lock; CI устанавливает с помощью uv sync --frozen, поэтому релиз всегда работает с теми версиями, с которыми он был протестирован. Чтобы установить конкретную версию:
uv tool install "transport-lit==0.3.0" # a pinned PyPI release
uv tool install git+https://github.com/aquistbe/transport-lit@v0.3.0 # or the matching git tag
uv tool upgrade transport-lit # move to the latest releaseСбор данных
transport-lit harvest # ROSA-P; auto: incremental if a complete full harvest exists, else full
transport-lit harvest --source all # every configured source (vti, bast, wbokr, ipea, cepal, rosap)
transport-lit harvest --mode full # walk the whole repository again
transport-lit harvest --mode incremental # from = start of last complete run − 1 h, until = now
transport-lit harvest --from 2026-08-01T00:00:00Z # explicit window (full timestamp required)
transport-lit harvest --max-pages 3 # testing only; the run is recorded as failed/partial
transport-lit reindex # re-parse the cached raw pages (no network) after a parser changeЧто делает сборщик и почему (все поведение проверено на ROSA-P 2026-08-26):
ListRecords&metadataPrefix=oai_dc, 100 записей на страницу, следуяresumptionToken, пока не придет страница без него. Только тогда запуск помечается какcomplete; любая ошибка оставляет егоfailedи не продвигает указатель «последний сбор», поэтомуharvest_statusникогда не утверждает, что частичный индекс завершен.Темп: один запрос за
TRANSPORT_LIT_MIN_INTERVALсекунд (по умолчанию 1 с). Токены истекают примерно через 60 с после выдачи, поэтому повторные попытки используют короткую задержку (2/4/6 с).badResumptionToken, ошибки транспорта, усеченный XML или пустой конверт, пока токен активен → список переиздается. ROSA-P не возвращает записи в стабильном порядке дат (проверяется на каждой странице), поэтому восстановление перезапускает список с начала; upsert делает это идемпотентным. Если бы порядок был монотонным, сборщик вместо этого возобновил бы работу с наименьшей даты, увиденной черезuntil=. До 8 восстановлений за запуск, затемfailed.noRecordsMatch: ROSA-P не отправляет код ошибки; пустой выборочный сбор возвращается как конверт OAI-PMH без элемента<ListRecords>. Это сопоставляется с «нечего делать» только тогда, когда не было токена; в середине списка это рассматривается как усечение.Проверки тихого усечения:
cursorтокена сравнивается с локальным счетчиком на каждой странице; полный сбор, который возвращает на >5 % меньше записей, чем предыдущий полный сбор, помечается в примечаниях к запуску. Оба появляются вharvest_status().last_harvest.notes.Удаления: репозиторий сообщает
deletedRecord=no, поэтому локально ничего не удаляется; запись, исчезнувшая из ROSA-P, остается в индексе до полного повторного сбора в новыйTRANSPORT_LIT_DATA_DIR.Кэширование: каждая страница OAI сохраняется в сжатом виде в
raw/run<N>-p<page>.xml.gz, поэтому парсер можно изменить и перестроить индекс без обращения к сети; PDF-файлы и их извлеченный текст кэшируются вpdf/и в таблицеfulltext.from/untilформатируются в соответствии с объявленнойgranularityкаждого репозитория (читается изIdentify): ROSA-P, DiVA и DSpace принимают полные временные меткиYYYY-MM-DDThh:mm:ssZ, OPUS (BASt) принимает толькоYYYY-MM-DD, и окно расширяется на день с каждой стороны.Широкие репозитории (World Bank, IPEA, CEPAL) фильтруются во время сбора с помощью многоязычного транспортного словаря (
sources.TRANSPORT_RE, en/es/pt/de/fr/sv): запись сохраняется, если термин встречается в названии, или (IPEA, CEPAL) если два различных термина встречаются среди предметных рубрик. Аннотации игнорируются — литература по развитию упоминает дороги и порты вскользь — а предметные рубрики World Bank также игнорируются (более 100 рубрик на запись). Это было настроено 2026-08-26 на случайных выборках из 20 названий: свободное правило «название+рубрики+аннотация» сохраняло 15 271 запись World Bank с точностью примерно 35–50 %; окончательное правило сохраняет 976 при 18/20, IPEA 207 при ~16/20, CEPAL 1 165 при ~15/20. Полнота — это цена; ослабьтеmin_subject_hitsвsources.pyи запуститеtransport-lit reindex --source <key>(без сети), если хотите другой компромисс. В примечаниях к запуску фиксируется сохранено против пропущено.transport-lit doctor [--repair]проверяет целостность SQLite, оба индекса FTS, зависшие запуски в состоянииrunning, невозможные временные метки и размер WAL, и исправляет то, что безопасно; хранилище также выполняет контрольную точку WAL при закрытии.transport-lit cite prefetch [--source …]массово разрешает каждую запись с DOI/PMID/OpenAlex до ее работы OpenAlex (50 за запрос), чтобыcited_by_countбыл известен для них без вызова на каждую запись.
transport-lit reindex --source <key> повторно разбирает кэшированные страницы и удаляет записи, которые текущий парсер/фильтр больше не сохраняет, поэтому изменения фильтра никогда не требуют повторного сбора.
Ежемесячная пересборка и еженедельные обновления (график обслуживания)
Корпус меняется медленно, поэтому ритм такой: еженедельный инкрементальный сбор и ежемесячная полная пересборка. harvest --fresh выполняет полный сбор во временное хранилище, а затем атомарно заменяет записи dot: в живом индексе — единственный способ, которым записи, которые ROSA-P перестает обслуживать, когда-либо исчезают (его конечная точка OAI-PMH не отслеживает удаления). Импортированные источники (экспорт TRID) не затрагиваются, а неудачная пересборка ничего не меняет.
transport-lit install-schedule # shows the two launchd agents
transport-lit install-schedule --write # installs them: Mon 06:00 `--source all` incremental, 1st 05:00 `--source all --fresh`Журналы попадают в $TRANSPORT_LIT_DATA_DIR/logs/. В Linux используйте строки cron, которые выводит команда.
Ежемесячный контрольный список обслуживания (выполняется вместе с пересборкой): прочитать новые проблемы GitHub; uv lock --upgrade && uv run pytest; отметить исправления в разделе журнала изменений релиза; увеличить version в pyproject.toml и src/transport_lit/__init__.py; git tag vX.Y.Z && git push --tags.
TRID: импортируйте то, что экспортируете
TRID (https://trid.trb.org) — самая полная библиография по транспорту и естественное дополнение к ROSA-P, но у него нет API, в его FAQ сказано, что TRB «не предоставляет доступ к внутренним системам TRID и не снимает ограничения на экспорт/загрузку», а его robots.txt запрещает AI-краулеры. Что каждый пользователь может делать, так это искать и экспортировать. Итак:
Выполните поиск в TRID, выберите Export → RIS (CSV и XML также предлагаются).
transport-lit import ~/Downloads/trid-driver-improvement.ris --collection "TRID: driver improvement"
Записи получают идентификаторы trid:<accession> из URL просмотра TRID, попадают в коллекцию TRID (search_reports(..., collection="TRID")), и повторный импорт того же файла идемпотентен. Импортер является универсальным RIS, поэтому экспорт Zotero/EndNote/Scopus работает так же с --source <prefix>. get_fulltext для импортированной записи следует только по прямой ссылке .pdf; в противном случае используйте landing_url.
Что предлагает конечная точка OAI-PMH ROSA-P
https://rosap.ntl.bts.gov/fedora/oai — репозиторий «DOT Stacks» (платформа CDC Stacks), протокол 2.0, самая ранняя дата 2008-07-02, без отслеживания удалений, без наборов OAI (ListSets пуст), и oai_dc — единственный формат метаданных. Однако это квалифицированный Dublin Core в маскировке: такие элементы, как dc:contributor.author, dc:description.abstract, dc:relation.isPartOf, dc:identifier.uri (DOI и номера отчетов, например DOT HS 813 827), dc:coverage.spatial, dc:title.alternative и dc:description.tableOfContents, присутствуют. Парсер (dc.py) сохраняет каждое необработанное поле и выводит из них типизированные столбцы. dc:relation.isPartOf (разделенный точкой с запятой) — это то, что используют list_collections / фильтр collection.
Ссылки на PDF отсутствуют в метаданных; get_fulltext читает citation_pdf_url с целевой страницы и возвращается к соглашению о потоке данных /view/dot/{n}/dot_{n}_DS1.pdf.
Проверка (2026-08-26)
Семантический поиск v0.4.0. 342 462 вектора (fastembed multilingual MiniLM-L12, 384-d, параллельно по данным со скоростью 94 записи/с на 8 ядрах — 60 минут для корпуса). Проверка на кросс-язычность: "elderly pedestrian crashes at night" в режиме semantic возвращает среди первых 8 три отчета CiNii на японском языке (夜間 高齢歩行者 死亡事故 analyses, 1995–2011) рядом с PubMed и англоязычными элементами CiNii; проверка словаря: "point system for problem drivers license suspension recidivism" находит оценку изъятия транспортных средств в Калифорнии 1997 года и отчет об административном отзыве 1986 года от ROSA-P, которые не имеют общих слов запроса. Гибридная задержка ≈ 0,6 с (доминирует кодирование запроса), ключевые слова ≈ 25 мс. Операционный урок записан здесь, чтобы никто его не повторил: никогда не удаляйте файл SQLite -wal, пока другой процесс (например, работающий MCP-сервер) держит базу данных открытой — он содержит зафиксированные данные, еще не сохраненные в контрольной точке.
v0.3.0. Источники API. OpenAlex: 58 страниц, 11,448 отчётов (10 тем, type:report),
1,428 с PDF-ссылками. CiNii: 730 страниц, 144,348 совпадений по 20 запросам, 118,609 уникальных. PubMed:
105,028 статей в 17 временных срезах (E-utilities ограничивает retstart значением 10,000, поэтому срезы
находятся рекурсивно). Проверка открытой модели: Ollama qwen2.5:3b ответила на вопрос об улучшении водительских навыков
одним правильным вызовом search_reports.
v0.2.0. Многоисточниковый сбор. VTI: 120 страниц, 11,944 просмотрено, 11,460 уникальных (DiVA отдаёт
некоторые записи в нескольких наборах), 0 возобновлений. BASt: 30 страниц, 2,987 просмотрено, 2,970 уникальных;
1,901 с прямыми PDF-ссылками; проверен инкрементальный путь с дневной гранулярностью (24 записи).
World Bank: 404 страницы / 40,332 просмотрено; IPEA: 144 / 14,400; CEPAL: 522 / 52,199 — все завершились на
странице без токена с 0 возобновлений; отфильтрованные количества выше. Точечные поиски: Fußgänger Unfall (BASt) → реконструкция ДТП и статистика аварий на сельских дорогах; acidentes de trânsito mortalidade (IPEA) → «Mortalidade por acidentes de transporte terrestre e
desigualdades interestaduais no Brasil»; seguridad vial peatones (CEPAL) → управление
безопасностью дорожного движения и оценки кампаний; pedestrian safety (VTI) → исследования обучения детей-пешеходов
1990-х годов.
v0.1.0 (первый сбор ROSA-P)
Полнота сбора. Прогон 1 (full) прошёл 908 страниц / 90,706 записей за 15 минут
(00:03:59–00:19:11 UTC) с 0 возобновлений, 0 несовпадений курсора и завершился на странице из 6
записей без токена возобновления — это определение полного списка в OAI-PMH. В хранилище 90,603
уникальные записи; разрыв в 103 записи — это одна и та же запись, появляющаяся на двух
страницах, что происходит из-за того, что ROSA-P не возвращает записи в стабильном порядке (сборщик
логирует это: «datestamp ordering violated on page 2»). Второй независимый полный
проход, через 30 минут в отдельный каталог, вернул ровно те же числа —
908 страниц, 90,706 просмотрено, 90,603 уникальных — и оба набора ID идентичны (0 записей,
уникальных для любого из проходов). 103 повтора — это репозиторий, отдающий одну и ту же запись на
двух страницах, а не пропущенные записи.
Покрытие по десятилетиям (год указан для 74,448 = 82 %; у остальных 16,155 нет даты
ни в одном поле метаданных; year_source показывает, откуда взят год: из dc:date (48,658), из
строки описания, содержащей только год (22,205), или из заголовка (3,585)):
десятилетие | записей | десятилетие | записей |
1900-е–1930-е | 3,243 | 1980-е | 5,408 |
1940-е | 2,618 | 1990-е | 8,936 |
1950-е | 2,627 | 2000-е | 11,466 |
1960-е | 2,947 | 2010-е | 18,690 |
1970-е | 5,057 | 2020-е | 13,456 |
Поиск известных элементов (transport-lit search …, ранг 1, если не указано иное):
Цель | Запрос | Результат |
NHTSA Countermeasures That Work |
| dot:1789 (2005), dot:1827 (3-е изд. 2008), dot:40255 (1-е изд. 2006), dot:1778 (2-е изд. 2007); 11-е изд. 2023 — dot:72947 (DOT HS 813 490), 10-е изд. — dot:57466. Одна голая фраза ставит одностраничные сводки Traffic Tech по CTW на первое место (короткие документы выигрывают по BM25), затем идут руководства. |
Оценка Oregon DMV Driver Improvement Program (Strathman et al., 2007) |
| dot:21848 «Evaluation of the Oregon DMV driver improvement program», Strathman, Kimpel, Leistner; отчёт № SPR 634. В метаданных ROSA-P без даты. |
Отчёты Вирджинии об улучшении водительских навыков (Lynn, 1982) |
| dot:18959 (12-месячный отчёт), dot:18905 (краткосрочные эффекты), dot:18969 (24-месячный итоговый отчёт), все — Cheryl Lynn, Virginia Highway & Transportation Research Council. В метаданных ROSA-P без даты. |
Реальный запрос driver improvement program evaluation negligent operator (первые 6 из 10):
dot:18905 — An evaluation of the short-term effects of the Virginia driver improvement program (Lynn) — all_terms
dot:29326 — Review of NJ point system (Carnegie, Ozbay, Mudigonda, 2013; FHWA NJ-2013-004) — all_terms
dot:18959 — …Virginia driver improvement program on negligent driving: 12-month report (Lynn)
dot:18969 — …Virginia driver improvement program on negligent driving: 24-month report (Lynn)
dot:17678 — Study of recidivism rates among drivers administratively sanctioned by the New Jersey MVC (Carnegie et al., 2009)
dot:17677 — Study of the effects of plea bargaining motor vehicle offenses (Carnegie et al., 2009)
Извлечение полного текста было проверено на dot:93144 (DOT HS 813 827, PDF 3,7 МБ, получен через
citation_pdf_url). Модульные тесты: uv run pytest (парсер для обоих профилей метаданных, запасной
вариант года, поиск/фильтры FTS, идемпотентность upsert, токенизатор запросов, нормализация ID).
Структура
src/transport_lit/
config.py paths, User-Agent, pacing, limits (env-overridable)
oai.py rate-limited OAI-PMH client; typed errors; raw-page cache
dc.py oai_dc record -> typed dict (authors, year, DOI, report numbers, collections …)
store.py SQLite schema, FTS5 index + triggers, search, stats, harvest-run bookkeeping
harvest.py full / incremental harvest with completeness + truncation handling
fulltext.py PDF resolution, download (size-capped), pypdf extraction, cache
server.py MCP tools (FastMCP / MCPServer)
importers.py RIS import (TRID exports and any other reference-manager export)
cli.py transport-lit probe | harvest [--fresh] | import | reindex | status | search | get | fulltext
| install-claude-desktop | install-schedule
.github/workflows/ ci.yml (tests on push/PR), release.yml (wheel + GitHub Release on tag)
tests/ unit tests (parser, store, query tokenizer)Добавление второго источника позже (например, NHTSA crashstats)
Хранилище не зависит от источника: records.id — строка с префиксом (сегодня dot:93144),
harvest_runs.source фиксирует, какой сборщик записал прогон, а индексу FTS всё равно,
откуда пришла строка. Чтобы добавить источник:
Напишите
src/transport_lit/sources/<name>.py, предоставляющийharvest(store, *, mode, progress), который возвращает словари в той же форме, что иdc.parse_record(id,title,authors,year,abstract,report_numbers,doi,landing_url,collections,raw, …), и вызываетstore.upsert_records(). Используйте новый префикс ID (nhtsa:812115) и передайте собственное имяsourceвstore.start_run(), чтобыharvest_statusмог сообщать о нём отдельно.Переиспользуйте
oai.RateLimiterиconfig.USER_AGENTдля этикета; сохраняйте сырые ответы вraw/<source>/для воспроизводимости.Добавьте в
harvest.status()блок для каждого источника (подсчёт по префиксуid).Добавьте опцию
--sourceвtransport-lit harvestи, если у источника есть собственный фасет, соответствующий фильтр вsearch_reports.Дедуплицируйте относительно ROSA-P по DOI / номеру отчёта (
records.doi,records.report_numbers), а не по названию — отчёты NHTSA часто присутствуют в обоих местах.
Проверенные факты об источнике NHTSA crashstats, чтобы никто не перепроверял их заново:
https://crashstats.nhtsa.dot.gov/Api/Public/Publication/{id} возвращает PDF напрямую
(812115 → отчёт NMVCCS о критических причинах, application/pdf, ~0,5 МБ). Это
эндпоинт получения документа, а не API поиска или перечисления, поэтому коннектору понадобится
стратегия перечисления (например, номера DOT HS, уже присутствующие в ROSA-P
report_numbers), а не обход сайта.
За пределами США: оценённые кандидатные источники (2026-08-26)
Проверено вживую: (a) являются ли фонды литературой, а не наборами данных, и (b) есть ли машинный доступ, подходящий для этого сборщика. Количества — это то, что сообщили эндпоинты в тот день.
Источник | Фонды | Машинный доступ | Вывод |
VTI (Швеция) через DiVA | 7 474 записи, набор | OAI-PMH, | Сбор — без доработок |
BASt (Германия) OPUS | 2 987 записей; отчёты федерального исследовательского института автомобильных дорог | OAI-PMH, | Сбор — без доработок |
World Bank Open Knowledge Repository | 40 332 записи; 1 787 результатов по запросу «transport safety»; набор OAI | OAI-PMH (DSpace 7) + DSpace REST | Собирать всё, отбирать по тематике; или REST-запрос |
WHO IRIS | 276 681 запись; 3 334 результата по запросу «road traffic»; нет наборов | OAI-PMH + DSpace REST search | REST-запрос по тематике (полный обход OAI — 2 800 страниц) |
CEPAL repository (Латинская Америка) | 52 199 записей; нет тематических наборов | OAI-PMH + DSpace REST | Собирать и фильтровать по тематике |
MTT Chile Biblioteca Digital de Transportes | 5 820 строк | Открытый Hasura GraphQL по адресу | Можно собирать через GraphQL; сначала уточните условия использования в MTT |
OpenAlex | 2 604 работы с типом report по запросу «road safety»; 16 639 работ любого типа по запросу «pedestrian safety» | Бесплатный REST API, пагинация по курсору | Лучший глобальный агрегатор; использовать как источник серой литературы не из США и DOI |
GOV.UK (DfT) | 4 998 материалов DfT по запросу «road safety research» | Бесплатный API контента | Можно собирать; требуется фильтрация по типу документа |
Испания, Centro de Documentación del Transporte | 66 000 библиографических записей (45 000 монографий) в AbsysNet | Только OPAC; сайт блокирует небраузерные клиенты (HTTP 403) | Вне области охвата, если только министерство не предоставит OAI/Z39.50 |
TRIMIS (ЕС) | Транспортные проекты и результаты, финансируемые ЕС | Сайт работает; нет документированного API (существуют массовые выгрузки открытых данных) | Оценивать выгрузку открытых данных, а не сайт |
IDB Publications, CAF Scioteca | Транспортные отчёты банков развития | DSpace, но блокировка ботов (403 / страница проверки) | Вне области охвата, если не будет предоставлен доступ |
SWOV (Нидерланды) | Библиотека института безопасности дорожного движения | Страница обнаружения ботов на каждом пути | Вне области охвата |
ITF/OECD | Отчёты Международного транспортного форума | HTTP 403 для небраузерных клиентов; нет API | Вне области охвата (API OECD iLibrary лицензирован) |
Transport Data Commons | Наборы данных (32 учреждения, 120+ стран), PortalJS | API не найден ( | Не литература |
ITDP Rapid Transit Database | Набор данных (км BRT/LRT/метро по городам); загрузка Google Sheet | Только загрузка | Не литература |
AASHTO TERI database | Формулировки потребностей в исследованиях, а не готовые отчёты | Нет | Не литература |
nismod/Africa-transport-database (GitHub) | ГИС-набор данных по транспортной инфраструктуре Африки | Git clone | Не литература |
TRID | 1,5 млн библиографических записей, международный охват | Нет; экспорт/доступ к бэкенду запрещён политикой | Вне области охвата |
По регионам (проверки в тот же день; «open» означает подтверждённый неаутентифицированный машинный доступ):
Регион | Что существует | Доступ | Примечания |
Европа | VTI (SE), BASt (DE) — выше; HAL (FR): 74 952 записи в коллекции Université Gustave Eiffel/IFSTTAR, 117 результатов типа | HAL REST (открыт), OpenAIRE REST (открыт), Cellar SPARQL (открыт), CORDIS JSON (открыт); DTU Orbit OAI 500, TU Delft OAI не найден, TØI 403 | ITRD (ITF/OECD) объединён с TRID, поэтому контент ITF доступен только через TRID |
Австралия / НЗ | Figshare OAI-PMH + REST (Monash/MUARC и другие австралийские университеты публикуют там отчёты); страницы исследовательских отчётов NZTA (HTML, 200); Austroads (403 для не-браузеров); APO — обсерватория серой литературы (403 для не-браузеров); Trove API (нужен ключ) | Figshare открыт; Trove — по ключу; APO/Austroads блокируют ботов | Поиск Figshare по отчётам «road safety» возвращает в основном наборы данных/код — нужна фильтрация по типу элемента и учреждению, чтобы это было полезно |
Япония | IRDB ( | Всё открыто, ключ не нужен | IRDB — путь к серой литературе (диссертации, технические отчёты университетов); отчёты министерств NILIM/PWRI доступны только в вебе |
Индия | OAI Shodhganga не найден по путям DSpace; сайт CSIR-CRRI — статический HTML; IRC/MoRTH только в вебе | Ничего не найдено | Лучшее покрытие — OpenAlex/OpenAIRE для индийских журнальных публикаций; пригодного для сборки источника серой литературы не выявлено |
Китай | Открытого репозитория отчётов MOT/RIOH нет; сайт RIOH статический; CNKI лицензируется | Ничего не найдено | OpenAlex возвращает 15 416 работ китайских учреждений по запросу «traffic safety» (журнальная литература) — это реалистичный путь |
Латинская Америка | IPEA (BR) | OAI IPEA/CEPAL открыт; GraphQL MTT открыт; IDB/CAF блокируют ботов; OAI LA Referencia не найден по предполагаемым URL | Конечные точки OAI SciELO не найдены по прежним путям (в любом случае это журналы) |
Три репозитория OAI-PMH с completeListSize (VTI, BASt, World Bank OKR) подходят существующему сборщику с префиксом источника и индивидуальным metadataPrefix; сайты на DSpace 7 также принимают from/until и возвращают корректный noRecordsMatch, так что особенности ROSA-P в oai.py уже являются более сложным случаем.
TRID вне области действия
TRID (https://trid.trb.org) не имеет публичного API, конечной точки OAI-PMH и массового экспорта. В его FAQ сказано, что «TRB не предоставляет доступа к внутренним системам TRID и не снимает ограничений на экспорт/загрузку для частных лиц или организаций», а также что база данных не может использоваться для обучения LLM. Поэтому здесь он намеренно не сканируется.
Порядок v2 (согласовано 2026-08-26)
VTI + BASt(готово, v0.2.0) — 2.World Bank OKR, IPEA, CEPAL(готово, v0.2.0) —IRDB Japan — 4. OpenAlex
type:reportкак глобальный запасной вариант — 5. подмножество PubMed по транспорту (см. ниже). Примечание по VTI:oai_dcDiVA не содержит ссылки на полный текст; переключение этого источника наswepub_mods/mets_kbдало быget_fulltextURLFULLTEXT01.pdf.
PubMed: транспортное/травматологическое подмножество, а не весь PubMed
E-utilities PubMed (esearch/efetch, бесплатно, 3 запроса/с без ключа) могут поддерживать локальное подмножество по фиксированной стратегии, обновляемое с помощью mindate/maxdate с той же еженедельной/ежемесячной периодичностью. Два взаимодополняющих фильтра, объединённых через OR:
Стратегия MeSH —
"Accidents, Traffic"[MeSH] OR "Pedestrians"[MeSH] OR "Bicycling"[MeSH] OR "Automobile Driving"[MeSH] OR "Motorcycles"[MeSH] OR "Wounds and Injuries"[MeSH] AND ("Transportation"[MeSH] OR "Built Environment"[MeSH] OR "City Planning"[MeSH])— охватывает работы по транспорту в общих и клинических журналах.Список журналов — Accident Analysis & Prevention, Traffic Injury Prevention, Journal of Safety Research, Injury Prevention, Injury Epidemiology, Journal of Transport & Health, Safety Science, Transportation Research Part F, Transport Reviews, BMC Public Health (только с транспортной тематикой) и т. д. — охватывает работы по транспорту, индексированные без терминов MeSH.
SafetyLit (safetylit.org, еженедельный бюллетень литературы по травматизму, аффилированный с WHO) ведёт именно такой список журналов и вручную классифицирует статьи по темам, что делает его лучшей основой для журнального фильтра; при проверке 2026-08-26 его сайт был недоступен (соединение отклонялось для каждого имени хоста), поэтому его текущий статус не подтверждён.
Еженедельный дайджест (бюллетень в стиле SafetyLit)
transport-lit digest --days 7 [--abstracts] выводит Markdown-бюллетень всего, что попало в индекс за последнюю неделю, с группировкой по источникам и количеством записей. Он управляется полем first_seen_at, которое устанавливается при первом появлении записи и сохраняется при полных пересборках, так что ежемесячная пересборка не делает весь индекс «новым». Инструмент whats_new предоставляет те же данные модели, которая затем может писать сводки — тот редакторский шаг, который SafetyLit делал вручную.
Сравнение с другими литературными MCP
MCP-серверы PubMed, Semantic Scholar, OpenAlex и arXiv проксируют живые запросы к одному API. transport-lit отличается в трёх отношениях: он индексирует серую литературу, которой нет у агрегаторов (отчёты ведомств, оценки DOT штатов, институты, вносящие вклад в ITRD), работает офлайн на локальном индексе после сборки (без ограничений скорости во время запроса, без ключа) и является многоисточниковым с единой схемой идентификаторов, так что модель может искать сразу по всему и экспортировать цитирования. Что есть у тех серверов, чего пока нет у этого: графы цитирования (кто кого цитирует), разрешение неоднозначности авторов и семантический (эмбеддинговый) поиск — см. ниже.
Граф цитирования (v0.5)
get_references / get_citations (CLI: transport-lit cite refs|cites <id> [--in-index]) прикрепляют граф цитирования OpenAlex к индексу. Запись сопоставляется с работой OpenAlex по её OpenAlex id, DOI, PMID или — для многих недатированных отчётов ведомств без DOI — по точному нормализованному названию с годом в пределах ±1 (поле match в результате указывает, какой способ сработал). Рёбра загружаются при первом запросе и кэшируются в таблицах citations/works; списки цитирующих обновляются через 90 дней, ссылки не меняются никогда. Цитируемые работы, которые сами есть в индексе, возвращаются со своим record_id, а в результатах поиска после этого появляется cited_by_count.
Проверено 2026-08-27: оценка DIP Oregon DMV (dot:21848, без DOI и даты в ROSA-P) была сопоставлена по названию и содержит 6 цитирующих работ, среди них оценка DIP Айовы и исследование рецидивизма в Нью-Джерси; 24-месячный отчёт Линна 1982 года по Вирджинии цитируется в обзоре Cochrane 2003 года по обучению водителей после получения прав (pubmed:12917984, есть в индексе); статья 2020 года о пожилых пешеходах в Сеуле содержит 57 ссылок, 19 из них в индексе. OpenAlex разрешает DOI NTL вида 10.21949/… (15 493 записи ROSA-P содержат такой DOI); записи без какого-либо DOI — 73 000 из 90 599 записей ROSA-P — зависят от сопоставления по названию, которое принимает точное нормализованное название, отношение префикса (хвосты издания или подзаголовка) или пересечение токенов ≥ 0,8, всегда с годом в пределах ±1. Серая литература, которую никто не цитировал в индексируемых изданиях, по-прежнему будет показывать ноль; это свойство данных о цитировании, а не индекса. OpenCitations и Semantic Scholar можно добавить как запасные варианты в те же таблицы.
Семантический поиск (v0.4)
Ключевой поиск — это FTS5/BM25. Добавление векторов превращает search_reports в гибридный поиск (BM25 и косинусная близость объединяются по взаимному рангу), который находит записи по смыслу и на разных языках — английский запрос находит шведские, немецкие, испанские, португальские или японские записи. Всё работает локально; без аккаунта и GPU.
uv tool install "transport-lit[semantic]" # adds fastembed (ONNX runtime), ~60 MB
transport-lit embed # default backend: fastembed, multilingual MiniLM-L12 (384-d, 220 MB model, one-time download)
transport-lit embed --backend ollama --model qwen3-embedding:8b # opt-in: any Ollama embedding model, truncated to 1024-d
transport-lit search "programa de mejoramiento de conductores" --mode semanticСемантические результаты диверсифицируются по источникам: ни один источник не может занимать более половины запрошенных результатов, если только source/collection не сужает поиск (TRANSPORT_LIT_SEMANTIC_PER_SOURCE). Измеренная причина: CiNii составляет треть индекса и содержит тысячи коротких английских названий («Pedestrian safety problems and countermeasures»), которые находятся ближе к короткому запросу, чем любая запись с аннотацией; разрыв косинусной близости между записями с аннотацией и без неё составляет всего ~0,01, так что это состав корпуса, а не артефакт длины, и ограничение — честное решение. mode="semantic" — это специальный режим; hybrid остаётся по умолчанию.
Гибридное слияние взвешивает список ключевых слов как 1,0, а семантический список как 0,7 (TRANSPORT_LIT_SEMANTIC_WEIGHT), и кандидат только из семантического поиска должен пройти порог косинусной близости 0,5 (TRANSPORT_LIT_SEMANTIC_MIN); это сохраняет точность точных запросов, тогда как mode="semantic" остаётся режимом полноты / кросс-языкового поиска.
embed обрабатывает только записи, у которых ещё нет вектора, поэтому после первого прохода еженедельная сборка добавляет секунды. Векторы хранятся в $TRANSPORT_LIT_DATA_DIR/vectors/<backend-model>/ в виде memory-mapped матрицы float16 (342k × 384 ≈ 260 МБ); поиск — это чанкованное скалярное произведение, без расширений. Активный набор векторов записывается в индекс, поэтому search_reports(mode=…) использует тот бэкенд, который его создал: hybrid (по умолчанию), keyword или semantic; mode_used в каждом результате сообщает, что выполнялось, и поиск деградирует до keyword, когда векторов нет. harvest_status() сообщает бэкенд, модель, размерность и покрытие.
Бэкенды измерены 2026-08-26 на 10-ядерном ноутбуке Apple Silicon, 256 реальных записей (заголовок + аннотация): fastembed MiniLM-L12 ≈ 30 записей/с на CPU (провайдер CoreML не быстрее); Ollama qwen3-embedding:0.6b ≈ 20/с (1024-d), qwen3-embedding:8b ≈ 1.4/с (4096-d, обрезано до 1024). Так что первый полный проход по 342k записям — это разовые ~3 часа с моделью по умолчанию; еженедельное приращение — секунды. Используйте --source, чтобы создать эмбеддинги для одного источника с более тяжёлой моделью. Обратите внимание: модель MiniLM читает не более 128 токенов (заголовок плюс первые ~90 слов аннотации); Qwen читает полное окно в 1 500 символов и получает префикс инструкции поиска модели при запросах. Большинству пользователей следует установить снимок (ниже) и вообще не запускать полный проход.
Снимки: пропустите сбор
uv tool install "transport-lit[semantic]"
transport-lit snapshot install https://github.com/aquistbe/transport-lit/releases/download/v0.4.0/transport-lit-2026-08.tar.gz
transport-lit mcp-config claude-desktop # or install-claude-desktop --writeЭто полная и доступная для поиска установка за несколько минут: 224k записей (всё, кроме CiNii и TRID) с векторами. transport-lit snapshot build <file.tar.gz> упаковывает индекс SQLite плюс активные векторы; snapshot install <url-or-file> распаковывает его в новый TRANSPORT_LIT_DATA_DIR, после чего еженедельные инкрементальные сборы поддерживают его актуальным (снимок содержит учётные данные сбора, так что harvest --source all знает, откуда продолжить). Снимки исключают CiNii (условия его API требуют регистрации и ничего не говорят о распространении) и импорты TRID (условия TRB); пользователи собирают их сами. В релизах есть снимок, если он был собран.
Available Tools
12 toolsexport_citationsARead-onlyIdempotent
Export records as RIS (Zotero/EndNote/Mendeley) or BibTeX. Pass transport-lit ids.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | ||
| format | No | ris |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context by naming the exact output encodings and the required ID source ('transport-lit ids'). It does not discuss rate limits or edge cases, but the annotations lower the burden here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler. It immediately states the operation, the output formats, and the key input requirement. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool, the description is mostly complete: annotations cover safety and idempotence, the output schema covers return shape, and the description covers formats and ID source. The main missing piece is guidance for choosing this over sibling citation/retrieval tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does by clarifying that ids should be 'transport-lit ids' and that format accepts RIS or BibTeX. This adds real meaning beyond the bare schema, though it could be more explicit about ID syntax or format case-sensitivity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Export records as RIS (Zotero/EndNote/Mendeley) or BibTeX.' This clearly distinguishes it from sibling retrieval tools like get_citations or get_references. The format list makes the deliverable concrete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage guidance is 'Pass transport-lit ids,' which is an operational requirement rather than a when-to-use statement. It does not mention when to choose export_citations over alternatives such as get_citations, nor does it state exclusions or prerequisites. No alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_similarBRead-onlyIdempotent
Records similar to a given one (by title and subject terms), across all sources.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive). The description adds useful context by specifying how similarity is determined ('by title and subject terms') and that it searches 'across all sources,' which implies no user, workspace, or source filtering. No contradictions with annotations, but no additional detail beyond that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler. The core action and key modifiers are front-loaded, and every word adds information. It is appropriately concise without sacrificing necessary meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. The tool is simple and annotations cover its safety profile. However, the description leaves parameter semantics entirely unaddressed and does not provide enough context for an agent to confidently call it correctly, especially regarding what 'limit' does.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not compensate. It never mentions the 'id' parameter or the 'limit' parameter, nor does it explain what they mean. An agent must infer that 'a given one' refers to the required id and cannot know what limit controls. This is a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific function: finding records similar to a given one, with explicit criteria ('by title and subject terms') and scope ('across all sources'). It is not a tautology and gives a clear sense of what the tool does. However, it does not explicitly distinguish itself from sibling tools such as search_reports or lookup, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: when you have a record id and want similar records, use this tool. It does not provide any explicit when-not-to-use guidance or point to alternatives among the sibling tools. This is enough to infer context but lacks direct routing to alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_citationsARead-onlyIdempotent
Works that cite a record, via OpenAlex, cached locally (refreshed after 90 days).
only_in_index=True returns just citing works that are in this index — 'what has
built on this report'. cited_by_count_openalex is OpenAlex's total.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| limit | No | ||
| refresh | No | ||
| only_in_index | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool read-only, idempotent, open-world, and non-destructive, so the description does not need to restate that. It adds valuable behavioral context: local caching with a 90-day refresh cycle, a distinction between index-only citing works and OpenAlex totals, and the meaning of cited_by_count_openalex. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tightly written sentences with the core behavior front-loaded and parameter notes kept compact. Every sentence earns its place, and there is no redundant restatement of the tool name or schema. The structure is ideal for a read-only cached query.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations and the presence of an output schema, the description covers the essential contextual elements: data source, caching behavior, the only_in_index filter, and a key output field. The refresh parameter's explicit behavior is not stated, but the 90-day refresh note makes it reasonably inferable. Overall, an agent has enough context to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden of parameter semantics. It does this well for only_in_index, explaining both the filter behavior and its conceptual significance. However, it does not explain id, the explicit effect of refresh=True, or limit, leaving a partial gap in parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool returns works that cite a record, sourced via OpenAlex and cached locally. It makes the inbound-citation direction clear, which implicitly distinguishes it from the sibling get_references, though it does not explicitly name that sibling. The verb and resource are specific enough for an agent to understand the core function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only_in_index option provides a clear conditional scoping rule with an interpretive gloss ('what has built on this report'), and the 90-day refresh note sets expectations about data freshness. However, there is no explicit guidance on when to use this tool versus siblings like get_references or export_citations, and no exclusions are stated. Usage context is implied rather than fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fulltextARead-onlyIdempotent
Resolve the report's PDF on ROSA-P, extract its text and return it (cached
locally after the first call). Page through long documents with offset.
Text is marked with [[page N]] separators. Scanned PDFs return status 'no_text'.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| offset | No | ||
| refresh | No | ||
| max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, idempotent, openWorld), the description discloses caching behavior, page separator format, and scanned-PDF status 'no_text'. This adds substantive behavioral detail that an agent would not otherwise know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three focused sentences with the core action front-loaded, followed by cache behavior, pagination, page markers, and a failure mode. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main call path, paging, cache behavior, and scanned-PDF status, and the output schema exists so return values need no explanation. However, the behavior of 'refresh' and 'max_chars' is not explained, so the description is not fully complete for all parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains 'offset' for paging, but does not clarify 'refresh' or 'max_chars'; 'id' is only implied by 'the report's PDF'. The description adds some meaning but leaves several parameter semantics undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Resolve', 'extract') and a specific resource ('the report's PDF on ROSA-P'), clearly distinguishing this from siblings like search_fulltext or get_report. The exact scope of the tool is immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational context: paging long documents with offset, local caching, and special handling for scanned PDFs. It does not explicitly mention alternatives or exclusions ('use search_fulltext instead'), but the use case is clear enough for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_referencesBRead-onlyIdempotent
Works a record cites (its reference list), via OpenAlex, cached locally. Each entry
carries record_id when the cited work is itself in this index. match says how
the record was matched to OpenAlex (openalex, doi, pmid, or title).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| limit | No | ||
| refresh | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds meaningful context beyond those: it explains the OpenAlex source, local caching, presence of record_id for in-index works, and the match field's allowed values. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with little filler; it packs source, caching, record_id, and match semantics efficiently. The grammar issue in the first sentence hurts clarity slightly, but the description is appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema plus annotations cover return values and safety, and the description explains the most important output nuance. However, it omits refresh/limit behavior and does not explicitly distinguish this reference-list tool from the get_citations sibling, leaving meaningful gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden for the three parameters, but it does not explain id, limit, or refresh. The cache mention loosely relates to refresh and 'a record' implies id, but the semantics of refresh and limit are left undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the resource as a record's reference list and adds useful source context (OpenAlex, cached locally). It is clear enough, though the opening phrase 'Works a record cites' is ungrammatical and lacks an explicit verb; the tool name helps compensate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool: when you need the works cited by a record. It does not explicitly contrast it with siblings like get_citations, nor does it state when not to use it, leaving some routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_reportARead-onlyIdempotent
Full metadata record for one report. Accepts 'dot:93144', '93144', the OAI identifier, or the ROSA-P landing URL. Includes every raw Dublin Core field.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation read-only, idempotent, and non-destructive, and the description adds useful context about accepted identifier formats and the raw Dublin Core content. However, it does not disclose any other behavioral traits such as not-found behavior or normalization, though the output schema covers the return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences front-load the core purpose and then immediately give the parameter formats and content guarantee. There is no repetition of schema or annotation information and no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only tool with an output schema, the description is nearly complete: it explains what the tool returns and what the parameter can be. The only missing piece is explicit guidance about when to choose this tool over its siblings, but the low complexity and rich annotations keep this from being a major gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description fully compensates by specifying the accepted forms of the single 'id' parameter: dot-prefixed, bare numeric, OAI identifier, or ROSA-P landing URL. This is essential information an agent would otherwise lack, and it directly clarifies the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the resource as a metadata record for one report and states it includes every raw Dublin Core field, which clearly conveys what the tool returns. It implicitly distinguishes itself from siblings like search_reports and get_fulltext, but it never explicitly names an alternative or explains how it differs from them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when a specific report identifier is available and full metadata is needed, but it offers no explicit when-to-use vs alternative guidance. Sibling names such as search_reports, lookup, and get_fulltext signal neighboring use cases, but the description does not route between them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
harvest_statusARead-onlyIdempotent
Record counts per source, last harvest time/status and notes, coverage by year. If a source's last run is not 'complete' its part of the index may be partial.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior. The description adds a meaningful behavioral detail beyond annotations: if the last run status is not 'complete,' the source's index portion may be partial, which warns agents about interpreting the data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first front-loads every reported dimension and the second adds the essential interpretation caveat. Every clause contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read-only tool with an output schema, the description is complete. It tells the agent what information is available and warns about partial-index implications, leaving no obvious call-time decision unclear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter meaning for the description to add; the 100% schema coverage is vacuously satisfied. The description's focus on returned content is appropriate and needs no parameter elaboration.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates what the tool exposes (per-source record counts, last harvest time/status, notes, and yearly coverage) and adds a precise partial-index caveat, so the resource is clear. It lacks an explicit 'get/retrieve' verb and does not differentiate from siblings, but the listed fields are specific enough to identify the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The content makes the intended context clear: any need to inspect harvest runs, per-source counts, status, or coverage by year. It does not name alternatives or give when-not-to-use guidance, but the straightforward read-only status-report scope leaves little ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_collectionsARead-onlyIdempotent
Collections (ROSA-P relation.isPartOf values) with record counts, plus document
types. ROSA-P's OAI-PMH endpoint exposes no OAI sets, so these are derived from the
harvested metadata and are what the collection filter matches against.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful provenance behavior: values are derived from harvested metadata rather than OAI sets, which is non-obvious and affects interpretation of the returned data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with no filler. The core output is stated first, and the provenance/usage note earns its place by clarifying why these collections exist and how they are used.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only listing with an output schema present, the description fully covers purpose, data provenance, and the filtering use case. Nothing an agent needs to call or interpret this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema leaves nothing undocumented and the described meaning of the return values is the main semantic contribution. No parameter-specific guidance is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete resource (ROSA-P relation.isPartOf collection values), the returned information (record counts and document types), and the source of the data. This is specific enough to distinguish it from any sibling tool without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains that the endpoint exposes no OAI sets and that these derived values are what the collection filter matches against, which tells an agent when this lookup is relevant. It does not explicitly list alternatives or exclusion conditions, but no sibling appears to be a direct collection-listing alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookupARead-onlyIdempotent
Exact lookup by DOI, PMID, report number (e.g. "DOT HS 813 097"), transport-lit id, or landing URL. Use this instead of search when you already have an identifier.
| Name | Required | Description | Default |
|---|---|---|---|
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool read-only, idempotent, and non-destructive, so the description does not need to repeat those properties. It adds the behavioral trait of exact matching and enumerates identifier formats, but it does not disclose not-found behavior or side effects. An output schema exists, so return-value details are not required, but the behavioral disclosure is adequate rather than rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The operation and accepted identifier types are front-loaded, and the routing rule is appended efficiently. Every clause adds information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter lookup with rich annotations and an output schema, the description covers the essential selection and invocation information. It is slightly incomplete only in not clarifying boundaries against get_report/get_fulltext and in not stating what happens when a supplied identifier is not found.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines an 'identifier' string with no description (0% coverage), so the description carries the full burden of explaining the parameter. It compensates exceptionally well by enumerating accepted forms: DOI, PMID, report number with a concrete example, transport-lit id, or landing URL. This gives an agent the concrete vocabulary needed to populate the parameter correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete operation and resource: 'Exact lookup by DOI, PMID, report number (e.g. "DOT HS 813 097"), transport-lit id, or landing URL.' This clearly identifies what the tool does and the identifier forms it accepts. It also distinguishes itself from the search siblings with 'Use this instead of search when you already have an identifier,' though it does not differentiate from get_report or get_fulltext, which may also operate on identifiers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states the condition to use this tool: 'Use this instead of search when you already have an identifier,' which is useful routing guidance. However, it gives no guidance on when lookup should be preferred over report- or fulltext-retrieval siblings, so the alternative-selection advice is partially incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_fulltextARead-onlyIdempotent
Search inside the PDF text that get_fulltext has already extracted and cached (only documents someone fetched before). Returns snippets with [term] markers.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful behavioral context beyond annotations: search is limited to previously fetched/cached documents, and results are returned as snippets with [term] markers. It does not discuss edge cases like empty caches or query syntax, but it adds meaningful non-obvious behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The core action and unique cached-only constraint are front-loaded, and every clause adds useful information. It is concise without sacrificing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low parameter count, rich annotations, and presence of an output schema, the description covers the essential invocation context: the cached-document prerequisite and the snippet output format. It is slightly light on query syntax expectations, but for a simple one-required-parameter search tool, the overall picture is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden of explaining parameters, but it only implies that 'query' is a term to search for via '[term] markers.' It never explicitly explains the query parameter semantics, matching behavior, or the meaning/effect of the 'limit' parameter. This leaves the agent reliant on parameter names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action ('Search inside the PDF text'), a clear resource (text already extracted and cached by get_fulltext), and the output shape (snippets with [term] markers). It also distinguishes itself from get_fulltext and other siblings by noting it operates only on cached content, not raw PDFs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly conveys when to use the tool: only after get_fulltext has fetched and cached a document, and only for documents someone previously fetched. It does not explicitly name alternative tools or exclusions (e.g., using search_reports for metadata searches), so it stops short of full when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_reportsARead-onlyIdempotent
Search titles, abstracts, subjects, authors and report numbers across all sources.
Args:
query: Keywords. Quote phrases ("driver improvement"); trailing * = prefix;
column prefixes work: title:pedestrian, authors:lynn, report_numbers:"813 097".
year_min / year_max: Inclusive publication-year filter.
collection: Substring filter on collection name (see list_collections), e.g. "NHTSA",
"VTI", "BASt", "World Bank", "CEPAL", "TRID", "PubMed".
doc_type: Substring filter on document type, e.g. "Tech Report", "Dataset".
source: Comma-separated id prefixes to restrict to, e.g. "dot,vti" (dot = ROSA-P,
vti, bast, wbokr, ipea, cepal, openalex, cinii, pubmed, trid).
limit: Max hits (1-100). offset: for paging.
mode: "hybrid" (default: keyword BM25 fused with semantic vectors when an embedding
index exists), "keyword", or "semantic" (meaning-based, cross-language). Semantic
results are capped at 50% from any one source unless `source`/`collection` is
set; use `source` to search one corpus by meaning. ``mode_used`` says what ran.
Returns ranked hits; ``match_mode`` says whether all query terms matched (all_terms),
the hit came from the any-term fallback, or from the semantic index.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | hybrid | |
| limit | No | ||
| query | Yes | ||
| offset | No | ||
| source | No | ||
| doc_type | No | ||
| year_max | No | ||
| year_min | No | ||
| collection | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only/idempotent annotations, the description discloses important runtime behavior: hybrid mode fuses BM25 with semantic vectors, semantic results are capped at 50% from one source, mode_used reports which mode actually ran, and match_mode distinguishes all_terms, any-term fallback, and semantic matches. This is rich, non-obvious behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured as a clear Args list with the purpose front-loaded. It is dense but not wordy, and every sentence adds necessary information such as syntax rules, examples, source mappings, and mode behavior. The length is justified by 9 parameters and no schema-level descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of this search tool, the description covers all parameters, syntax variants, behavioral caveats, and output signals like match_mode and mode_used. An output schema exists, so return-value documentation is not required in the description. Nothing needed to invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description documents every parameter in detail: query syntax with examples, inclusive year filters, substring semantics for collection/doc_type, comma-separated source prefixes with corpus mappings, limit bounds, offset for paging, and mode semantics. It fully compensates for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb ('Search'), a clear resource ('titles, abstracts, subjects, authors and report numbers'), and scope ('across all sources'). It distinguishes this from siblings like search_fulltext, which presumably searches full text, and from lookup/find_similar, which are different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives extensive usage guidance: query syntax, quoting, prefix wildcards, column prefixes, date filtering, collection/source filtering, mode selection, and paging. It does not explicitly name alternatives or state when not to use this tool, but the context is clear enough for an agent to decide when search_reports is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whats_newARead-onlyIdempotent
Records that entered the index in the last N days (from the weekly incremental harvests), newest first, with counts by source. The raw material for a digest.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | ||
| limit | No | ||
| source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior, so the safety profile is covered. The description adds meaningful behavior beyond that: ordering by newest first, aggregation by source, and provenance from weekly incremental harvests. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences deliver the core behavior, ordering, grouping, data provenance, and intended use case with no filler. Each clause adds information an agent needs to select and invoke the tool correctly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, read-only query tool with no required parameters and an output schema present, the description covers the essential semantics: time window, ordering, grouping, and source. It could be more explicit about when to choose this over sibling tools and about the limit parameter, but these are moderate gaps rather than severe ones.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It explains the 'days' parameter via 'last N days' and the 'source' parameter via 'counts by source', but it does not clarify the 'limit' parameter semantics beyond its schema default. Partial compensation, not complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource (records in the index) and the temporal scope (last N days), and adds distinctive details like 'newest first' and 'counts by source' that separate it from generic lookup or search siblings. It lacks an explicit action verb like 'list' or 'retrieve', but the intended behavior is clear enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'raw material for a digest' implies when to use this tool, and 'from the weekly incremental harvests' situates it in a specific data flow. However, it does not explicitly state when not to use it or name alternative tools such as search_reports or get_fulltext for other needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.5.1- First observed
export_citations - First observed
find_similar - First observed
get_citations - First observed
get_fulltext - First observed
get_references - First observed
get_report - First observed
harvest_status - First observed
list_collections - First observed
lookup - First observed
search_fulltext - First observed
search_reports - First observed
whats_new
TDQS
Scored across 12 tools
Most tools have clearly distinct roles: search, metadata retrieval, fulltext extraction, citation lookup, and export. The only real ambiguity is between get_report and lookup, which both accept identifiers and landing URLs, though get_report is specifically for full Dublin Core metadata on ROSA-P records.
The majority of tools follow a verb_noun pattern (get_report, search_reports, export_citations, get_citations). Minor deviations include lookup, harvest_status, and whats_new, which are noun-like or less conventional but still readable and not confusing.
Twelve tools is a well-scoped set for a literature discovery and citation-analysis server. Each tool covers a distinct part of the workflow without redundancy or bloat.
The surface covers search, retrieval, fulltext access, citation graph exploration, export, collection browsing, and harvest status. For a read-only repository, there are no obvious dead ends or missing core operations.
Maintenance
Related MCP Connectors
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
License-checked research archive and technical-spec search for AI agents. Pay per call via x402.
Search US grants + federal contracts (Grants.gov + SAM.gov) from any LLM.
Search your knowledge bases from any AI assistant using hybrid RAG.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables agents to search a local, fully offline personal document library (Markdown/txt/PDF/docx) via SQLite FTS5 trigram search with subject-terminology expansion, returning every hit with its domain, document title, section path, and page or offset provenance. It also exposes domain statistics, incremental ingestion, and document deprecation as tools, alongside a read-only, runtime-persona-scoped ask/coverage mode.-
- AlicenseAqualityCmaintenanceEnables AI agents to search a local folder of Markdown, AsciiDoc, and text files through a SQLite FTS5 keyword index, returning the most relevant sections with file paths, line ranges, and heading breadcrumbs instead of grepping through a repo. It also exposes tools to list indexed documents and refresh the index incrementally, all offline with no dependencies, network calls, or embeddings.3MIT
- FlicenseNot gradedqualityAmaintenanceEnables AI agents and MCP-compatible hosts to search, ask, and retrieve section-level citations from scattered local notes, docs, PDFs, Word files, web pages, org files, and chat logs using hybrid vector and BM25 retrieval.-
- AlicenseNot gradedqualityAmaintenanceEnables agents to run full-text search inside Word, PowerPoint, Excel, PDF, and plain-text files by extracting their contents into a single local SQLite FTS5 index. Exposes tools to search documents with ranked highlighted snippets and human-readable locators, list indexed files, and incrementally build or refresh the index.MIT