Skip to main content
Glama

transport-lit — 基于 MCP 的交通灰色文献

(于 2026-08-27 由 dot-lit 更名而来;DOT_LIT_* 环境变量和旧数据目录仍会被识别。)

transport-lit 为 AI 助手(Claude Desktop、Claude Code、任意 MCP 客户端)提供对交通研究报告的关键词搜索,这些报告是 PubMed 未收录、Semantic Scholar 覆盖不佳的。它始于 ROSA-P——美国国家交通图书馆的仓库(NHTSA DOT HS 报告、FHWA/FRA/FTA/FAA、UTC 和州 DOT 研究;https://rosap.ntl.bts.gov),现在采集三大洲的六个 OAI-PMH 来源,以及你从 TRID 导出的任何内容:

来源

记录数

备注

dot

ROSA-P — U.S. DOT National Transportation Library

90,599

完整仓库

vti

VTI — Swedish National Road and Transport Research Institute (DiVA)

11,460

报告、会议论文、文章;en/sv

bast

BASt — German Federal Highway Research Institute (OPUS)

2,970

1,901 条带有直接 PDF 链接;de/en

wbokr

World Bank Open Knowledge Repository

976

按标题筛选自 40,332 条的子集;实测精确率 18/20

ipea

IPEA(巴西)

207

筛选自 14,400 条的子集;pt;精确率 ~16/20

cepal

CEPAL/ECLAC(拉丁美洲)

1,165

筛选自 52,199 条的子集;es/en;精确率 ~15/20

openalex

OpenAlex — 类型为 report 的文献,涵盖 10 个交通主题(全球)

11,448

主题:交通与道路安全、城市交通与可达性、交通规划、…

cinii

CiNii Research(日本)— 文章、学位论文、IRDB 仓库条目

118,609

需要一个免费的 NII 应用 ID(TRANSPORT_LIT_CINII_APPID);20 个 ja/en 查询,每个上限 10k;CJK 查询使用子串匹配

pubmed

PubMed — 交通/伤害子集(MeSH 策略 + 12 种期刊)

105,028

按日期切片的 E-utilities 采集;TRANSPORT_LIT_PUBMED_TERM 覆盖该策略

trid

你通过 transport-lit import 导入的 TRID 导出内容

yours

见下文

transport-lit sources 列出它们;transport-lit harvest --source <key>|all 采集它们;search_reports 中的 collection 过滤器选择一个(例如 "VTI""BASt""World Bank""CEPAL""TRID")。添加另一个 OAI-PMH 仓库只需在 src/transport_lit/sources.py 中增加一条记录。

我创建这个项目是为了我个人的学术和研究用途, 也很乐意与任何觉得它有用的人分享。我欢迎关于错误、集成需求、改进和其他评论的反馈。 我会定期查看这些反馈,并尽可能整合,同时记录这些整合。 如果你有兴趣帮助支持这个项目,或者对它还有其他想法,我也欢迎! — Alex Quistberg (提交 issue

它采用对 OAI-PMH 源唯一可行的方法:将整个 仓库的元数据采集到本地 SQLite 数据库,在此基础上构建 FTS5 全文索引, 并基于该索引提供搜索。除可选的 PDF 全文抓取外,不会实时查询任何内容。重新采集是增量的(OAI 请求中的 from=),且成本很低。

工具接口

工具

返回内容

search_reports(query, year_min?, year_max?, collection?, doc_type?, source?, limit?, offset?)

排序后的命中结果:id、标题、作者、年份、报告编号、DOI、落地 URL、摘要片段、match_mode。列前缀可用(title:pedestrianauthors:lynn

lookup(identifier)

按 DOI、PMID、报告编号("DOT HS 813 097")、id 或落地 URL 精确匹配

get_report(id)

完整元数据记录,包括采集到的每个原始字段

get_fulltext(id, max_chars?, offset?, refresh?)

解析 PDF(ROSA-P 落地页、BASt/OpenAlex 直接链接),提取并缓存文本;支持 offset 分页

search_fulltext(query, limit?)

在已提取的所有 PDF 文本中搜索,并返回片段

find_similar(id, limit?)

按标题和主题词跨来源查找相关记录

export_citations(ids, format?)

为 id 列表生成 RIS(Zotero/EndNote/Mendeley)或 BibTeX

get_references(id, limit?, refresh?)

该记录引用的文献(OpenAlex,已缓存);当被引文献在本索引中时,条目带有 record_id

get_citations(id, limit?, only_in_index?, refresh?)

引用该记录的文献;only_in_index=True 表示“本索引中有哪些文献基于它”;OpenAlex 的总 cited_by_count

whats_new(days?, source?, limit?)

最近 N 天进入索引的记录,按来源统计数量——每周摘要的原始素材

list_collections()

集合和文档类型及其数量

harvest_status()

每个来源的记录数、上次运行及其状态/备注、按年份的覆盖情况

另外还有一个提示词 literature_scan(topic),它引导模型进行带引用的多查询扫描。每个工具都带有 MCP 注解(readOnlyHintidempotentHint;只有 get_fulltextopenWorldHint,因为它可能抓取一个 PDF)。

id 接受 dot:9314493144oai:dot.stacks:dot:93144 或落地 URL。导入的记录使用其他前缀(trid:813520import:…)。

查询语法:裸词先按 AND 组合;如果匹配所有词的命中数少于 limit,剩余位置将由任意词匹配填充(match_mode = all_terms / any_terms)。用引号表示短语("driver improvement"),用尾随 * 表示前缀。排序采用 BM25,标题、报告编号和作者的权重高于摘要。

Related MCP server: Personal Research Assistant 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 客户端、任意模型

服务器通过 stdio(默认)和 Streamable HTTP / SSE 提供标准 MCP 服务(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 B 参数)通过 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

配置(环境变量)

变量

默认值

用途

TRANSPORT_LIT_DATA_DIR

~/.local/share/transport-lit

SQLite 数据库、原始 OAI 页面(raw/)、PDF 缓存(pdf/

TRANSPORT_LIT_CONTACT

(未设置)

你的电子邮箱,放在 User-Agent 中以便仓库维护者联系你。请设置它。

TRANSPORT_LIT_MIN_INTERVAL

1.0

出站请求之间的最小间隔秒数

TRANSPORT_LIT_HTTP_TIMEOUT

90

每个请求的超时时间(秒)

TRANSPORT_LIT_MAX_PDF_BYTES

80 MB

拒绝 get_fulltext 中更大的 PDF

TRANSPORT_LIT_MAX_PDF_PAGES

600

提取超过此页数后停止

TRANSPORT_LIT_CINII_APPID

(未设置)

NII 应用程序 ID;采集 CiNii 必需(在 support.nii.ac.jp/en/cinii/api/developer 注册)

NCBI_API_KEY

(未设置)

可选;将 PubMed E-utilities 速率从 3 提升到 10 req/s

TRANSPORT_LIT_PUBMED_TERM

内置策略

替换 PubMed 搜索策略

TRANSPORT_LIT_EMBED_BACKEND / TRANSPORT_LIT_EMBED_MODEL / TRANSPORT_LIT_EMBED_DIM

fastembed / MiniLM-L12 / 1024

语义搜索后端、模型、Ollama 截断

OLLAMA_HOST

http://localhost:11434

ollama 后端的 Ollama 端点

变量也可以放在 ~/.config/transport-lit/env 中,以 KEY=VALUE 行的形式(真实的环境变量优先);NII 应用程序 ID 或 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

通过 GitHub 的 trusted publishing 发布在 https://pypi.org/project/transport-lit/:打标签会运行 release.yml(构建、GitHub release),然后它再派发 publish.yml——即注册为 trusted publisher 的那个工作流——上传在 pypi 环境上等待维护者批准。PyPI 会拒绝来自可复用工作流的令牌,并且匹配的是顶层工作流文件,这就是为什么发布是一个单独派发的工作流,而不是 release 内部的一个 job。server.json 是 MCP Registry(registry.modelcontextprotocol.io)的清单,在 PyPI 包存在之后提交。

固定版本

发布版本是 git 标签 vMAJOR.MINOR.PATCH(语义化版本:patch = 修复,minor = 新工具/新来源,major = 对工具表面或数据库 schema 的破坏性变更)。每个标签都会触发 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

采集器做什么以及为什么(所有行为已于 2026-08-26 对照 ROSA-P 验证):

  • ListRecords&metadataPrefix=oai_dc,每页 100 条记录,跟随 resumptionToken 直到某一页没有它为止。只有到那时运行才会被标记为 complete;任何错误都会使其保持 failed 并且不会推进“上次采集”指针,因此 harvest_status 永远不会声称部分索引是完整的。

  • 节奏控制:TRANSPORT_LIT_MIN_INTERVAL 秒一个请求(默认 1 秒)。令牌在发出后约 60 秒过期,因此重试使用短退避(2/4/6 秒)。

  • badResumptionToken、传输错误、截断的 XML,或令牌仍有效时收到空信封 → 重新发起列表请求。ROSA-P 按稳定的 datestamp 顺序返回记录(每页都检查过),因此恢复会从顶部重新开始列表;upsert 使其幂等。如果排序是单调的,采集器就会改为通过 until= 从看到的最小 datestamp 继续。每次运行最多 8 次恢复,之后标记为 failed

  • noRecordsMatch ROSA-P 不发送该错误码;空的选择性采集会以没有 <ListRecords> 元素的 OAI-PMH 信封形式返回。只有在没有令牌在起作用时才将其映射为“无事可做”;在列表中途则视为截断。

  • 静默截断检查: 每页都将令牌的 cursor 与本地计数进行比较;完整采集返回的记录比上一次完整采集少 >5% 时,会在运行说明中标记。两者都会出现在 harvest_status().last_harvest.notes 中。

  • 删除: 仓库报告 deletedRecord=no,因此本地永远不会删除任何内容;从 ROSA-P 消失的记录会留在索引中,直到对全新的 TRANSPORT_LIT_DATA_DIR 进行完整重新采集。

  • 缓存: 每个 OAI 页面都以 gzip 形式存储在 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。召回率是代价;如果你想要另一种权衡,就放宽 sources.py 中的 min_subject_hits 并运行 transport-lit reindex --source <key>(无需网络)。运行说明会记录保留与跳过的数量。

  • transport-lit doctor [--repair] 检查 SQLite 完整性、两个 FTS 索引、卡在 running 状态的运行、不可能的时间戳和 WAL 大小,并修复可安全修复的部分;存储还会在关闭时对 WAL 做 checkpoint。transport-lit cite prefetch [--source …] 批量(每请求 50 条)将每条带 DOI/PMID/OpenAlex 的记录解析为其 OpenAlex work,从而无需逐条调用即可知道它们的 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 issues;uv lock --upgrade && uv run pytest;在 release 的 changelog 部分记录修复;在 pyproject.tomlsrc/transport_lit/__init__.py 中提升 versiongit tag vX.Y.Z && git push --tags

TRID:导入你导出的内容

TRID(https://trid.trb.org)是最完整的交通文献目录,也是 ROSA-P 的自然补充,但它没有 API,其 FAQ 说 TRB“不授予对 TRID 后端系统的访问权限,也不解除导出/下载限制”,并且其 robots.txt 禁止 AI 爬虫。每个用户可以做的是搜索和导出。所以:

  1. 在 TRID 中运行你的搜索,选择 Export → RIS(也提供 CSV 和 XML)。

  2. transport-lit import ~/Downloads/trid-driver-improvement.ris --collection "TRID: driver improvement"

记录从 TRID 视图 URL 获得 id trid:<accession>,进入 TRID 集合(search_reports(..., collection="TRID")),重新导入同一文件是幂等的。导入器是通用的 RIS,因此 Zotero/EndNote/Scopus 导出用 --source <prefix> 也能以相同方式工作。对导入记录调用 get_fulltext 只跟随直接的 .pdf 链接;否则请使用 landing_url

ROSA-P 的 OAI-PMH 端点提供什么

https://rosap.ntl.bts.gov/fedora/oai — 仓库“DOT Stacks”(CDC Stacks 平台),协议 2.0,最早 datestamp 2008-07-02,无删除跟踪,无 OAI 集合(ListSets 为空),并且 oai_dc 是唯一的元数据格式。不过它实际上是限定的 Dublin Core:dc:contributor.authordc:description.abstractdc:relation.isPartOfdc:identifier.uri(DOI 报告编号,例如 DOT HS 813 827)、dc:coverage.spatialdc:title.alternativedc:description.tableOfContents 等元素都存在。解析器(dc.py)保留每个原始字段并从中派生类型化列。dc:relation.isPartOf(分号分隔)正是 list_collections / collection 过滤器所使用的。

PDF 链接不在元数据中;get_fulltext 从落地页读取 citation_pdf_url,并回退到 datastream 约定 /view/dot/{n}/dot_{n}_DS1.pdf

验证(2026-08-26)

v0.4.0 语义搜索。 342,462 个向量(fastembed 多语言 MiniLM-L12,384 维,8 核上数据并行 94 条记录/秒——整个语料库 60 分钟)。跨语言检查:semantic 模式下的 "elderly pedestrian crashes at night" 在其前 8 个结果中,除了 PubMed 和英文 CiNii 条目外,还返回了三份日文 CiNii 报告(夜間 高齢歩行者 死亡事故 分析,1995–2011);词汇检查:"point system for problem drivers license suspension recidivism" 找到了 ROSA-P 的 1997 年加州车辆扣押评估和 1986 年行政吊销报告,它们与查询词没有任何重叠。混合延迟 ≈ 0.6 秒(查询编码占主导),关键词 ≈ 25 毫秒。这里记录一个操作教训以免有人重蹈覆辙:当另一个进程(例如正在运行的 MCP 服务器)打开着数据库时,绝不要删除 SQLite 的 -wal 文件——它保存着尚未 checkpoint 的已提交数据。

v0.3.0 API 数据源。 OpenAlex:58 页,11,448 份报告(10 个主题,type:report),1,428 份带有 PDF 链接。CiNii:730 页,20 个查询共 144,348 次命中,118,609 条唯一记录。PubMed:17 个日期切片中的 105,028 篇文章(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)在 15 分钟内遍历了 908 页 / 90,706 条记录(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 集合完全相同(任一遍都没有独有的记录)。这 103 次重复是存储库在两个页面上提供同一条记录,而不是记录被跳过。

按年代统计的覆盖率(74,448 条记录有年份,占 82 %;其余 16,155 条在任何元数据字段中都没有日期;year_source 表示年份来自 dc:date(48,658)、纯年份描述行(22,205)还是标题(3,585)):

年代

记录

年代

记录

1900s–1930s

3,243

1980s

5,408

1940s

2,618

1990s

8,936

1950s

2,627

2000s

11,466

1960s

2,947

2010s

18,690

1970s

5,057

2020s

13,456

已知条目检索transport-lit search …,除非另有说明,否则排名第 1):

目标

查询

结果

NHTSA 行之有效的对策

"countermeasures that work" guide highway safety offices

dot:1789 (2005), dot:1827(第 3 版,2008),dot:40255(第 1 版,2006),dot:1778(第 2 版,2007);2023 年第 11 版是 dot:72947(DOT HS 813 490),第 10 版是 dot:57466。仅使用该短语本身,CTW 的一页 Traffic Tech 摘要排名第一(短文档在 BM25 上占优),然后是各指南。

俄勒冈州 DMV 驾驶员改善计划评估(Strathman 等,2007)

oregon driver improvement program strathman

dot:21848 "俄勒冈州 DMV 驾驶员改善计划评估",Strathman、Kimpel、Leistner;报告编号 SPR 634。在 ROSA-P 元数据中无日期。

弗吉尼亚驾驶员改善报告(Lynn,1982)

virginia driver improvement lynn

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 条):

  1. dot:18905 — 弗吉尼亚驾驶员改善计划短期效果评估(Lynn)— all_terms

  2. dot:29326 — 新泽西记分制度回顾(Carnegie、Ozbay、Mudigonda,2013;FHWA NJ-2013-004)— all_terms

  3. dot:18959 — ……弗吉尼亚驾驶员改善计划对疏忽驾驶的影响:12 个月报告(Lynn)

  4. dot:18969 — ……弗吉尼亚驾驶员改善计划对疏忽驾驶的影响:24 个月报告(Lynn)

  5. dot:17678 — 新泽西 MVC 行政处罚驾驶员再犯率研究(Carnegie 等,2009)

  6. dot:17677 — 辩诉交易对机动车违法行为影响的研究(Carnegie 等,2009)

全文提取在 dot:93144(DOT HS 813 827,3.7 MB PDF,通过 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 索引不关心行的来源。要添加一个数据源:

  1. 编写 src/transport_lit/sources/<name>.py,暴露 harvest(store, *, mode, progress),它生成与 dc.parse_record 产生的相同形状的字典(idtitleauthorsyearabstractreport_numbersdoilanding_urlcollectionsraw、……),并调用 store.upsert_records()。使用新的 id 前缀(nhtsa:812115),并将你自己的 source 名称传递给 store.start_run(),以便 harvest_status 可以单独报告它。

  2. 复用 oai.RateLimiterconfig.USER_AGENT 以保持礼节;将原始响应存储在 raw/<source>/ 下以保证可重现性。

  3. harvest.status() 提供一个按数据源划分的块(按 id 前缀计数)。

  4. transport-lit harvest 添加一个 --source 选项,并且如果数据源有自己的分面,则在 search_reports 上添加相应的过滤器。

  5. 按 DOI / 报告编号(records.doirecords.report_numbers)与 ROSA-P 去重,而不是按标题——NHTSA 报告通常同时出现在两个地方。

NHTSA crashstats 数据源的已验证事实,以免有人重新推导:https://crashstats.nhtsa.dot.gov/Api/Public/Publication/{id} 直接返回 PDF(812115 → NMVCCS 关键原因报告,application/pdf,约 0.5 MB)。它是一个文档检索端点,而不是搜索或列表 API,因此连接器将需要一种枚举策略(例如 ROSA-P report_numbers 中已有的 DOT HS 编号),而不是爬取。

美国以外:已评估的候选数据源(2026-08-26)

进行了实时探测,以了解 (a) 馆藏是 文献 而非数据集,以及 (b) 是否存在适合此采集器的机器访问。计数是端点当天报告的数字。

来源

馆藏

机器访问

结论

VTI (Sweden) via DiVA vti.diva-portal.org/dice/oai

7,474 条记录,集合 all-vti;道路安全研究机构

OAI-PMH、completeListSizeoai_dc + swepub_mods + MARC21

收割——即插即用

BASt (Germany) OPUS bast.opus.hbz-nrw.de/oai

2,987 条记录;联邦公路研究所报告

OAI-PMH、completeListSizeoai_dc + xMetaDissPlus

收割——即插即用

World Bank Open Knowledge Repository openknowledge.worldbank.org/server/oai/request

40,332 条记录;"transport safety" 有 1,787 条命中;OAI 集合 transport 仅包含 100 条

OAI-PMH (DSpace 7) + DSpace REST discover/search

收割全部,按主题保留;或使用 REST 查询

WHO IRIS iris.who.int/oai/request

276,681 条记录;"road traffic" 有 3,334 条命中;无集合

OAI-PMH + DSpace REST 搜索

按主题进行 REST 查询(完整 OAI 遍历需 2,800 页)

CEPAL repository(拉丁美洲) repositorio.cepal.org/server/oai/request

52,199 条记录;无主题集合

OAI-PMH + DSpace REST

收割并按主题筛选

MTT Chile Biblioteca Digital de Transportes biblioteca.mtt.gob.cl

5,820 行 program_report 数据,包含名称、描述、类别、文件

开放的 Hasura GraphQL,位于 api.biblioteca.mtt.gob.cl/v1/graphql(已启用 introspection,未认证可读)

可通过 GraphQL 收割;先与 MTT 确认使用条款

OpenAlex api.openalex.org

2,604 篇类型为 report 的作品匹配 "road safety";16,639 篇任意类型的作品匹配 "pedestrian safety"

免费 REST API,游标分页

最佳全球 聚合器;用作非美国灰色文献和 DOI 的来源

GOV.UK (DfT) gov.uk/api/search.json

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 (EU) trimis.ec.europa.eu

欧盟资助的交通项目与成果

站点可访问;无文档化 API(存在批量开放数据转储)

评估开放数据转储,而非站点

IDB Publications, CAF Scioteca

开发银行的交通报告

DSpace,但被机器人拦截(403 / 验证页)

超出范围,除非获得访问权限

SWOV (荷兰)

道路安全研究所图书馆

每个路径都有机器人检测页面

超出范围

ITF/OECD

国际交通论坛报告

对非浏览器客户端返回 HTTP 403;无 API

超出范围(OECD iLibrary API 需授权)

Transport Data Commons portal.transport-data.org

数据集(32 个机构,120+ 个国家),PortalJS

未找到 API(/api/3 返回 404)

非文献

ITDP Rapid Transit Database

数据集(各城市 BRT/LRT/地铁公里数);Google Sheet 下载

仅可下载

非文献

AASHTO TERI database

研究需求陈述,而非已完成报告

非文献

nismod/Africa-transport-database (GitHub)

非洲交通基础设施的 GIS 数据集

Git clone

非文献

TRID

150 万条书目记录,国际范围

无;政策拒绝导出/后端访问

超出范围

按地区(当日探测;"open" 表示已确认未认证机器访问):

地区

现有内容

访问方式

备注

欧洲

VTI (SE)、BASt (DE) — 如上;HAL (FR):Université Gustave Eiffel/IFSTTAR 收藏中有 74,952 个条目,117 条 REPORT 类型的 "sécurité routière" 命中;OpenAIRE:82,053 篇 "road safety" 出版物(所有类型,欧洲范围聚合器);EU Publications Office Cellar SPARQL 和 CORDIS 搜索 JSON 均可回答

HAL REST(开放)、OpenAIRE REST(开放)、Cellar SPARQL(开放)、CORDIS JSON(开放);DTU Orbit OAI 500、TU Delft OAI 未找到、TØI 403

ITF/OECD 的 ITRD 已并入 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" 报告主要返回数据集/代码——需要按条目类型 + 机构过滤才有用

日本

IRDBirdb.nii.ac.jp/oai,机构知识库的国家聚合器;JPCOAR 2.0 + oai_dc,9 个集合);CiNii Research OpenSearch:交通安全 16,547 条命中;J-STAGE WebAPI:"traffic safety" 9,786 条(期刊,包括 IATSS Research)

全部开放,无需密钥

IRDB 是灰色文献途径(大学论文、技术报告);NILIM/PWRI 部委报告仅限网页

印度

Shodhganga OAI 在 DSpace 路径上未找到;CSIR-CRRI 网站是静态 HTML;IRC/MoRTH 仅限网页

未找到

对印度期刊成果的最佳覆盖来自 OpenAlex/OpenAIRE;未发现可收割的灰色文献来源

中国

没有开放的 MOT/RIOH 报告仓库;RIOH 网站是静态的;CNKI 需要授权

未找到

OpenAlex 返回 15,416 篇来自 CN 机构的 "traffic safety" 作品(期刊文献)——这才是现实的途径

拉丁美洲

IPEA (BR) repositorio.ipea.gov.br/server/oai/request:14,400 条记录,8,021 条 "transporte" 的 REST 命中;CEPAL — 如上;MTT Chile GraphQL — 如上;IMT Mexico 技术出版物是 HTML/PDF 列表

IPEA/CEPAL OAI 开放;MTT GraphQL 开放;IDB/CAF 阻止机器人访问;LA Referencia OAI 在猜测的 URL 上未找到

SciELO OAI 端点在旧路径上未找到(反正都是期刊)

具有 completeListSize 的三个 OAI-PMH 仓库(VTI、BASt、World Bank OKR)适合现有收割器,带有源前缀和每个源的 metadataPrefix;DSpace 7 站点也容忍 from/until 并返回正确的 noRecordsMatch,因此 oai.py 中的 ROSA-P 怪癖已经是更难的情况。

TRID 不在范围内

TRID(https://trid.trb.org)没有公共 API、没有 OAI-PMH 端点,也没有批量导出。其 FAQ 声明:"TRB 不授予对 TRID 后端系统的访问权限,也不会为个人或组织解除导出/下载限制",并且该数据库不得用于训练 LLM。这里特意不对其进行爬取。

v2 顺序(2026-08-26 商定)

  1. VTI + BASt(已完成,v0.2.0)— 2. World Bank OKR, IPEA, CEPAL(已完成,v0.2.0)—

  2. IRDB 日本 — 4. OpenAlex type:report 作为全球兜底 — 5. 一个 PubMed 交通 子集(见下文)。VTI 说明:DiVA 的 oai_dc 不携带全文链接;将 该源切换到 swepub_mods/mets_kb 将为 get_fulltext 提供 FULLTEXT01.pdf URL。

PubMed:一个交通/伤害子集,而非全部 PubMed

PubMed 的 E-utilities(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,世界卫生组织下属的每周伤害文献公报)维护的正是这样一个期刊列表,并按主题人工分类文章,这使其成为期刊过滤器的最佳种子;其网站在 2026-08-26 检查时无法访问(每个主机名都连接被拒),因此其当前状态未确认。

每周摘要(SafetyLit 风格公报)

transport-lit digest --days 7 [--abstracts] 打印一份 Markdown 公报,列出上周进入索引的所有内容,按来源分组并带有计数。它由 first_seen_at 驱动,该字段在首次看到记录时设置,并在全新重建时保留,因此每月重建不会让整个索引看起来都是新的。whats_new 工具向模型暴露相同的数据,模型随后可以撰写摘要——这正是 SafetyLit 手工完成的编辑步骤。

与其他文献 MCP 的比较

PubMed、Semantic Scholar、OpenAlex 和 arXiv MCP 服务器将实时查询代理到一个 API。transport-lit 在三个方面有所不同:它索引聚合器缺乏的灰色文献(机构报告、州 DOT 评估、ITRD 贡献机构),它在收割后在本地索引上离线运行(查询时无速率限制、无需密钥),并且它是多来源的,采用单一 id 方案,因此模型可以一次搜索所有内容并导出引文。那些服务器拥有而本服务器尚缺的:引文图(谁引用了谁)、作者消歧,以及语义(嵌入)搜索——见下文。

引文图(v0.5)

get_references / get_citations(CLI:transport-lit cite refs|cites <id> [--in-index])将 OpenAlex 的引文图附加到索引。记录通过其 OpenAlex id、DOI、PMID,或者——对于许多无日期、无 DOI 的机构报告——通过年份在 ±1 以内的精确规范化标题来匹配 OpenAlex 作品(结果中的 match 说明是哪种方式)。边在首次请求时获取,并缓存在 citations/works 表中;引用列表在 90 天后刷新,参考文献永不改变。本身在索引中的被引作品会返回其 record_id,搜索命中一旦已知就携带 cited_by_count

2026-08-27 验证:俄勒冈州 DMV DIP 评估(dot:21848,无 DOI,ROSA-P 中无日期)通过标题解析,并列出 6 篇引用作品,其中包括爱荷华州的 DIP 评估和新泽西州再犯研究;Lynn 1982 年弗吉尼亚 24 个月报告被 2003 年 Cochrane 对驾照后驾驶员教育的综述引用(pubmed:12917984,在索引中);一篇 2020 年首尔老年行人论文有 57 条参考文献,其中 19 条在索引中。OpenAlex 解析 NTL 的 10.21949/… DOI(15,493 条 ROSA-P 记录带有 DOI);没有任何 DOI 的记录——ROSA-P 90,599 条中的 73,000 条——依赖标题匹配,该匹配接受精确规范化标题、前缀关系(版本或副标题尾部),或 ≥ 0.8 的 token 重叠,且年份始终在 ±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>/ 中,作为内存映射的 float16 矩阵(342k × 384 ≈ 260 MB);搜索是分块点积,无需扩展。活动向量集记录在索引中,因此 search_reports(mode=…) 使用生成它的任何后端:hybrid(默认)、keywordsemantic;每个结果中的 mode_used 说明实际运行的是哪种,并且在不存在向量时降级为 keyword。harvest_status() 报告后端、模型、维度和覆盖率。

后端于 2026-08-26 在一台 10 核 Apple Silicon 笔记本电脑上测量,256 条真实记录(标题 + 摘要):fastembed MiniLM-L12 在 CPU 上约 30 条/秒(CoreML 提供程序并不更快);Ollama qwen3-embedding:0.6b 约 20 条/秒(1024 维),qwen3-embedding:8b 约 1.4 条/秒(4096 维,截断到 1024)。因此,使用默认模型对 342k 条记录进行首次完整遍历是一次性约 3 小时;每周增量只需几秒钟。使用 --source 用更重的模型嵌入单个来源。请注意,MiniLM 模型最多读取 128 个 token(标题加上摘要的前约 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 的条款);用户需自行采集这些来源。发布版本在构建了快照时会附带一个快照。

A
license - permissive license
A
quality
A
maintenance

Maintenance

0dRelease cycle
6Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to search and query PDF documents through a local RAG system with vector embeddings. Provides semantic document search capabilities while keeping all data stored locally without external dependencies.
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search and conversational querying across a personal research library of PDFs, DOCX, and other documents using a vector database. It provides tools for document summarization, finding related papers, and high-accuracy retrieval for AI clients like Claude Desktop.
  • A
    license
    Not graded
    quality
    C
    maintenance
    Builds searchable SQLite databases from PDFs, preserving inline image locations for AI agents to discover and caption visual content. Supports full-text search over text, image placeholders, and saved captions.
    1
    MIT

View all related MCP servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aquistbe/transport-lit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server