dot-lit
transport-lit — MCP による交通グレー文献
(dot-lit から 2026-08-27 に改名。DOT_LIT_* 環境変数と旧データディレクトリは今も認識されます。)
transport-lit は、AI アシスタント(Claude Desktop、Claude Code、任意の MCP クライアント)に、PubMed が索引化せず、Semantic Scholar のカバーが不十分な交通研究レポートのキーワード検索を提供します。これは ROSA-P(U.S. National Transportation Library のリポジトリ。NHTSA の DOT HS レポート、FHWA/FRA/FTA/FAA、UTC および州 DOT の研究; https://rosap.ntl.bts.gov)から始まり、現在は 3 大陸の 6 つの OAI-PMH ソースに加え、TRID からエクスポートしたものもハーベストします:
キー | ソース | レコード数 | メモ |
| ROSA-P — U.S. DOT National Transportation Library | 90,599 | リポジトリ全体 |
| VTI — Swedish National Road and Transport Research Institute (DiVA) | 11,460 | レポート、会議論文、記事; en/sv |
| BASt — German Federal Highway Research Institute (OPUS) | 2,970 | 直接 PDF リンク付き 1,901 件; de/en |
| World Bank Open Knowledge Repository | 976 | 40,332 件のタイトルフィルタ済みサブセット; 測定精度 18/20 |
| IPEA (Brazil) | 207 | 14,400 件のフィルタ済みサブセット; pt; 精度 ~16/20 |
| CEPAL/ECLAC (Latin America) | 1,165 | 52,199 件のフィルタ済みサブセット; es/en; 精度 ~15/20 |
| OpenAlex — 10 の交通トピックで report 型の文献(グローバル) | 11,448 | トピック: Traffic and Road Safety、Urban Transport and Accessibility、Transportation Planning、… |
| CiNii Research (Japan) — 論文、学位論文、IRDB リポジトリ項目 | 118,609 | 無料の NII アプリケーション ID が必要( |
| PubMed — transport/injury サブセット(MeSH ストラテジ + 12 ジャーナル) | 105,028 | 日付スライス式 E-utilities ハーベスト; |
| インポートした TRID エクスポート( | あなたのもの | 後述 |
transport-lit sources はそれらを一覧表示します。transport-lit harvest --source <key>|all はそれらをハーベストします。search_reports の collection フィルタは 1 つを選択します(例: "VTI"、"BASt"、"World Bank"、"CEPAL"、"TRID")。別の OAI-PMH リポジトリの追加は、src/transport_lit/sources.py の 1 エントリで済みます。
これは私自身の個人的な学術・研究用途のために作成したもので、役立つと思う他の誰とでも共有できてうれしく思います。エラー、統合のニーズ、改善、その他のコメントについてのフィードバックを歓迎します。定期的に確認し、可能な限り統合して、それを文書化します。これを支援することに興味がある方、または他のアイデアをお持ちの方は、ぜひお知らせください! — Alex Quistberg(issue を開く)
これは OAI-PMH ソースに対して機能する唯一の方法で行います。リポジトリ全体のメタデータをローカルの SQLite データベースにハーベストし、その上に FTS5 全文索引を構築し、その索引から検索を提供します。オプションの PDF 取得による全文取得を除き、ライブでクエリされるものはありません。再ハーベストは増分的(OAI リクエストの from=)で、低コストです。
ツール一覧
ツール | 返り値 |
| 関連度順のヒット: id、title、authors、year、レポート番号、DOI、ランディング URL、抄録スニペット、 |
| DOI、PMID、レポート番号("DOT HS 813 097")、id、またはランディング URL による完全一致 |
| ハーベストされたすべての生フィールドを含む完全なメタデータレコード |
| PDF を解決し(ROSA-P ランディングページ、BASt/OpenAlex の直接リンク)、テキストを抽出してキャッシュします。 |
| 抽出済みのすべての PDF テキスト内をスニペット付きで検索します |
| タイトルと主題語に基づく、ソース横断の関連レコード |
| ID リストに対する RIS(Zotero/EndNote/Mendeley)または BibTeX |
| レコードが引用している文献(OpenAlex、キャッシュ済み)。引用文献がこの索引内にある場合、エントリは |
| レコードを引用している文献。 |
| 過去 N 日間に索引に追加されたレコード。ソース別の件数付き — 週次ダイジェストの原材料 |
| 件数付きのコレクションと文書タイプ |
| ソースごとのレコード数、最終実行とそのステータス/メモ、年別カバレッジ |
さらに、literature_scan(topic) という 1 つのプロンプトがあり、モデルに引用付きのマルチクエリスキャンを実行させます。すべてのツールには MCP アノテーション(readOnlyHint、idempotentHint)が付いています。get_fulltext だけは PDF を 1 件取得する可能性があるため openWorldHint です。
id は dot:93144、93144、oai:dot.stacks:dot:93144、またはランディング URL を受け付けます。インポートされたレコードは他のプレフィックス(trid:813520、import:…)を使用します。
クエリ構文: 裸の単語は最初に 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 クライアント、任意のモデル
サーバーは標準 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(最後の 2 つは HTTP 経由)用の貼り付け可能なスニペットを出力します。Dockerfile は、ボリューム上に索引を持つ HTTP サーバーイメージを構築します。
オープンモデル。 2026-08-26 に Ollama qwen2.5:3b(3 B パラメータ)を用いて tests/ollama_smoke.py 経由でエンドツーエンドのテストを実施しました:「driver improvement プログラムに関するレポートを見つけ、タイトルを年と id 付きで 3 件挙げてください」という指示に対し、モデルは search_reports({"query": "driver improvement", "limit": 3}) を 1 回呼び出し、3 つのソースから正しいタイトル、年、id、ランディング URL を回答しました。小さなモデルでも機能する設計上の選択: 説明が最初の 1 行にある 10 個のツール、デフォルト値付きのフラットな 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。
設定(環境変数)
Variable | Default | Purpose |
|
| SQLiteデータベース、生のOAIページ( |
| (unset) | あなたのメールアドレス。User-Agentに含められ、リポジトリが連絡できるようにする。設定すること。 |
|
| 送信リクエスト間の最小秒数 |
|
| リクエストごとのタイムアウト(秒) |
| 80 MB |
|
| 600 | このページ数で抽出を停止 |
| (unset) | NIIアプリケーションID。CiNiiのハーベストに必要(support.nii.ac.jp/en/cinii/api/developerで登録) |
| (unset) | 任意。PubMed E-utilitiesのレートを3から10 req/sに引き上げる |
| 組み込み戦略 | PubMed検索戦略を置き換える |
| fastembed / MiniLM-L12 / 1024 | セマンティック検索のバックエンド、モデル、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 backendhttps://pypi.org/project/transport-lit/でGitHubのtrusted publishingを通じて公開されている。タグがrelease.yml(ビルド、GitHubリリース)を実行し、それがpublish.ymlをディスパッチする——trusted publisherとして登録されているワークフローはこれだけである——そこでアップロードは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ハーベスターが何をするか、そしてその理由(すべての動作は2026-08-26にROSA-Pに対して検証済み):
ListRecords&metadataPrefix=oai_dc、1ページ100レコード、resumptionTokenを追跡し、それなしのページが届くまで続行。その時点でのみ実行はcompleteとマークされる。エラーがあるとfailedのままになり、「最終ハーベスト」ポインタは進まないため、harvest_statusが部分的なインデックスを完了と主張することは決してない。ペーシング:
TRANSPORT_LIT_MIN_INTERVAL秒ごとに1リクエスト(デフォルト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ページは
raw/run<N>-p<page>.xml.gzとしてgzip圧縮で保存されるため、ネットワークに触れることなくパーサーを変更してインデックスを再構築できる。PDFとその抽出テキストはpdf/とfulltextテーブルにキャッシュされる。from/untilは各リポジトリが宣言するgranularity(Identifyから読み取られる)に合わせてフォーマットされる。ROSA-P、DiVA、DSpaceは完全なYYYY-MM-DDThh:mm:ssZタイムスタンプを受け付け、OPUS(BASt)はYYYY-MM-DDのみを受け付け、ウィンドウは両側に1日ずつ広げられる。広範なリポジトリ(World Bank、IPEA、CEPAL)はハーベスト時に多言語トランスポート語彙(
sources.TRANSPORT_RE、en/es/pt/de/fr/sv)でフィルタリングされる。タイトルに用語が現れるか、(IPEA、CEPALの場合)件名見出しの中に2つの異なる用語が現れる場合、レコードは保持される。抄録は無視される——開発文献は道路や港湾にさりげなく言及する——またWorld Bankの件名も無視される(レコードあたり100以上の見出し)。これは2026-08-26にランダムな20タイトルサンプルに対して調整された。緩いタイトル+件名+抄録ルールではWorld Bankの15,271レコードが約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をチェックポイントする。transport-lit cite prefetch [--source …]はDOI/PMID/OpenAlexを含むすべてのレコードを一括で(リクエストあたり50件)OpenAlexのワークに解決し、レコードごとの呼び出しなしで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 issueを読む。uv lock --upgrade && uv run pytest。リリースのchangelogセクションに修正を記録。pyproject.tomlとsrc/transport_lit/__init__.pyのversionを更新。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ビューURLからtrid:<accession>というIDを取得し、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.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多言語MiniLM-L12、384次元、8コアで94レコード/秒のデータ並列——コーパス全体で60分)。言語横断チェック:semanticモードの"elderly pedestrian crashes at night"は、上位8件の中にPubMedと英語のCiNiiアイテムに加えて、3件の日本語のCiNiiレポート(夜間 高齢歩行者 死亡事故の分析、1995〜2011)を返す。語彙チェック:"point system for problem drivers license suspension recidivism"は、クエリ語を共有しないROSA-Pの1997年カリフォルニア州車両差し押さえ評価と1986年行政取消レポートを見つける。ハイブリッド遅延≈0.6秒(クエリエンコーディングが支配的)、キーワード≈25ミリ秒。誰も繰り返さないようにここに記録される運用上の教訓:別のプロセス(例:実行中のMCPサーバー)がデータベースを開いている間にSQLiteの-walファイルを決して削除しないこと——まだチェックポイントされていないコミット済みデータが保持されている。
v0.3.0 APIソース。 OpenAlex: 58ページ、11,448件のレポート(10トピック、type:report)、
PDFリンク付きは1,428件。CiNii: 730ページ、20クエリで144,348ヒット、うち118,609件がユニーク。PubMed:
17の日付スライスで105,028件の論文(E-utilitiesはretstartを10,000で上限とするため、スライスは
再帰的に見つけられる)。オープンモデルの確認: Ollama qwen2.5:3b はドライバー改善の
質問に対して、正しいsearch_reports呼び出しを1回行って回答した。
v0.2.0 マルチソース収集。 VTI: 120ページ、11,944件確認、11,460件ユニーク(DiVAは
一部のレコードを複数のセットで提供する)、再開0回。BASt: 30ページ、2,987件確認、2,970件ユニーク。
直接PDFリンク付きは1,901件。日単位の増分パスを実行(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件の差は、同じレコードが2つのページに出現するためであり、
これはROSA-Pがレコードを安定した順序で返さないために起こる(ハーベスタはこれをログに記録する:
「datestamp ordering violated on page 2」)。30分後に別のディレクトリに対して実行した2回目の独立した完全
パスも、まったく同じ数値 — 908ページ、90,706件確認、90,603件ユニーク — を返し、2つのIDセットは
同一である(どちらかのパスにのみ存在するレコードは0件)。103件の重複は、リポジトリが同じレコードを
2つのページで提供していることであり、レコードがスキップされているわけではない。
年代別カバレッジ(年が存在するのは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 |
| 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の1ページのTraffic Tech要約が最初にランクされ(短い文書がBM25で有利)、次にガイドが続く。 |
Oregon DMV Driver Improvement Program evaluation (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、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)後で2つ目のソースを追加する(例: NHTSA crashstats)
ストアはソース非依存である: records.idは接頭辞付き文字列(現在はdot:93144)、
harvest_runs.sourceはどのハーベスタがランを書いたかを記録し、FTSインデックスは
行の出所を気にしない。ソースを追加するには:
src/transport_lit/sources/<name>.pyを書き、harvest(store, *, mode, progress)を公開する。これはdc.parse_recordが生成するのと同じ形のdictを生成し(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接頭辞でカウント)。transport-lit harvestに--sourceオプションを追加し、ソースが独自のファセットを持つ場合は、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 critical-reasonsレポート、application/pdf、約0.5 MB)。これは
ドキュメント取得エンドポイントであり、検索や一覧のAPIではない。したがって、コネクタには
クロールではなく列挙戦略(例: ROSA-Pのreport_numbersにすでにあるDOT HS番号)が
必要になる。
米国以外: 評価した候補ソース(2026-08-26)
ライブで確認したのは、(a) 所蔵がデータセットではなく文献であるかどうか、(b) このハーベスタに適合する機械アクセスがあるかどうか。件数は、その日にエンドポイントが 報告した値である。
ソース | 所蔵 | マシンアクセス | 判定 |
VTI(スウェーデン)経由DiVA | 7,474件のレコード、セット | OAI-PMH、 | ハーベスト — そのまま利用可 |
BASt(ドイツ)OPUS | 2,987件のレコード;連邦道路研究所の報告書 | OAI-PMH、 | ハーベスト — そのまま利用可 |
World Bank Open Knowledge Repository | 40,332件のレコード;"transport safety" で1,787件ヒット;OAIセット | OAI-PMH(DSpace 7)+ DSpace REST | すべてハーベストして主題で選別;またはRESTクエリ |
WHO IRIS | 276,681件のレコード;"road traffic" で3,334件ヒット;セットなし | OAI-PMH + DSpace REST検索 | 主題によるRESTクエリ(OAI全体の走査は2,800ページ) |
CEPALリポジトリ(ラテンアメリカ) | 52,199件のレコード;主題セットなし | OAI-PMH + DSpace REST | ハーベストして主題でフィルタリング |
MTTチリ Biblioteca Digital de Transportes | 5,820件の |
| GraphQL経由でハーベスト可能;事前にMTTと利用規約を確認 |
OpenAlex | "road safety" に一致するタイプが report の文献2,604件;"pedestrian safety" の全タイプの文献16,639件 | 無料REST API、カーソルページネーション | 最良のグローバルな アグリゲーター;米国以外の灰色文献とDOIのソースとして使用 |
GOV.UK(DfT) | "road safety research" のDfTアイテム4,998件 | 無料コンテンツAPI | ハーベスト可能;文書タイプのフィルタリングが必要 |
スペイン、Centro de Documentación del Transporte | AbsysNet内の66,000件の書誌レコード(45,000件のモノグラフ) | OPACのみ;サイトは非ブラウザクライアントをブロック(HTTP 403) | 省庁がOAI/Z39.50を公開しない限り対象外 |
TRIMIS(EU) | EU資金による交通プロジェクトと成果 | サイトは稼働中;文書化されたAPIなし(オープンデータの一括ダンプは存在) | サイトではなくオープンデータダンプを評価 |
IDB Publications、CAF Scioteca | 開発銀行の交通報告書 | DSpaceだがボットブロックあり(403 / チャレンジページ) | アクセスが許可されない限り対象外 |
SWOV(オランダ) | 交通安全研究所の図書館 | すべてのパスでボット検出ページ | 対象外 |
ITF/OECD | 国際交通フォーラムの報告書 | 非ブラウザクライアントにはHTTP 403;APIなし | 対象外(OECD iLibrary APIはライセンス制) |
Transport Data Commons | データセット(32機関、120か国以上)、PortalJS | APIなし( | 文献ではない |
ITDP Rapid Transit Database | データセット(都市別BRT/LRT/メトロのkm);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 件、 | 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」レポート検索は主にデータセット/コードを返す — 有用にするにはアイテムタイプ + 機関フィルタリングが必要 |
日本 | IRDB ( | すべてオープン、キー不要 | IRDB はグレー文献のルート (大学からの学位論文、技術レポート); NILIM/PWRI の省庁レポートはウェブのみ |
インド | Shodhganga OAI は DSpace パスに見つからず; CSIR-CRRI サイトは静的 HTML; IRC/MoRTH はウェブのみ | 見つからず | インドのジャーナル成果の最良のカバレッジは OpenAlex/OpenAIRE; 収穫可能なグレー文献ソースは特定されず |
中国 | MOT/RIOH レポートのオープンリポジトリなし; RIOH サイトは静的; CNKI はライセンス制 | 見つからず | OpenAlex は CN 機関から「traffic safety」で 15,416 件の作品を返す (ジャーナル文献) — それが現実的なルート |
ラテンアメリカ | IPEA (BR) | IPEA/CEPAL OAI はオープン; MTT GraphQL はオープン; IDB/CAF はボット遮断; LA Referencia OAI は推測 URL で見つからず | SciELO OAI エンドポイントはレガシーパスに見つからず (そもそもジャーナル) |
completeListSize を持つ 3 つの 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 合意)
VTI + BASt(完了、v0.2.0) — 2.World Bank OKR、IPEA、CEPAL(完了、v0.2.0) —IRDB 日本 — 4. グローバルなバックストップとしての OpenAlex
type:report— 5. PubMed 交通サブセット (下記参照)。VTI の注記: DiVA のoai_dcは全文リンクを持たない; そのソースをswepub_mods/mets_kbに切り替えると、get_fulltextにFULLTEXT01.pdfURL が渡される。
PubMed: 全体ではなく交通/傷害サブセット
PubMed の E-utilities (esearch/efetch、無料、キーなしで 3 req/s) は、固定ストラテジーからローカルサブセットを維持でき、同じ週次/月次サイクルで mindate/maxdate を使って更新できる。OR で結合された 2 つの相補的フィルター:
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 との比較
PubMed、Semantic Scholar、OpenAlex、arXiv の MCP サーバーは、ライブクエリを 1 つの API にプロキシする。transport-lit は 3 つの点で異なる: アグリゲーターが持たないグレー文献 (政府機関レポート、州 DOT 評価、ITRD 寄稿機関) を索引化し、収穫後にローカルインデックス上でオフライン実行し (クエリ時にレート制限なし、キー不要)、1 つの 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 評価と NJ 再犯研究がある); Lynn の 1982 年バージニア 24 か月レポートは、2003 年の免許取得後ドライバー教育の Cochrane レビュー (pubmed:12917984、インデックス内) に引用されている; 2020 年のソウル高齢歩行者論文には 57 件の参照があり、19 件がインデックス内にある。OpenAlex は NTL の 10.21949/… DOI を解決する (ROSA-P の 15,493 レコードが 1 つを保持); DOI のないレコード — ROSA-P の 90,599 件中 73,000 件 — はタイトルマッチに依存し、正規化された完全一致タイトル、プレフィックス関係 (版または副題の末尾)、または ≥ 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 はインデックスの 3 分の 1 を占め、要約を持つレコードよりも短いクエリに近い何千もの短い英語タイトル (「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 (デフォルト)、keyword、または semantic; すべての結果の mode_used は何が実行されたかを示し、ベクトルが存在しない場合はキーワードに劣化する。harvest_status() はバックエンド、モデル、次元、カバレッジを報告する。
バックエンドは2026-08-26に10コアのApple Siliconラップトップ上で測定され、256件の実レコード(タイトル+要旨)を使用しました:fastembed MiniLM-L12 ≈ CPUで30 records/s(CoreMLプロバイダーはそれ以上速くありません);Ollama qwen3-embedding:0.6b ≈ 20/s(1024-d)、qwen3-embedding:8b ≈ 1.4/s(4096-d、1024に切り詰め)。したがって、342k件のレコードに対する最初のフルパスは、デフォルトモデルでは一度きりの約3時間です。毎週の増分は数秒です。--source を使用すると、より重いモデルで1つのソースを埋め込めます。なお、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の規約による)は含まれません。ユーザーはこれらを自分でハーベストします。リリースには、スナップショットがビルドされた場合にそれが同梱されます。
Maintenance
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
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
Search, fetch (with provenance), scan, and convert AI instruction files for agents.
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 gradedqualityDmaintenanceEnables 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.
- FlicenseNot gradedqualityDmaintenanceEnables 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.
- FlicenseAqualityDmaintenanceProvides LLMs with direct access to official vendor PDF documentation for electronics components (TI, ST, ADI) via a local SQLite full-text index and PDF retrieval tools.61
- AlicenseNot gradedqualityCmaintenanceBuilds 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.1MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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