dot-lit
This server provides offline, multi-source transportation grey-literature search and analysis over a locally harvested SQLite/FTS5 index.
search_reports: ranked keyword/hybrid/semantic search across all sources with filters (year range, collection, doc type, source prefix), BM25 ranking, phrase/prefix/column-prefix queries, and any-term fallback.
lookup: exact match by DOI, PMID, report number, transport-lit ID, OAI identifier, or landing URL.
get_report: fetch the full metadata record for one report, including every raw Dublin Core field.
get_fulltext: resolve, download, extract, and cache PDF text; page through results with offset.
search_fulltext: search inside previously extracted/cached PDF text with snippet highlighting.
find_similar: find related records across sources by title and subject terms.
export_citations: export records as RIS or BibTeX for citation managers.
get_references / get_citations: retrieve OpenAlex citation graph data, cached locally, and identify cited/citing works that are also in the index.
whats_new: list records added in the last N days, grouped by source, useful for digests.
list_collections: show collection names and document types with counts.
harvest_status: report per-source record counts, last harvest status/notes, and year coverage.
Provides search and retrieval of transportation-related research reports from PubMed, including metadata and full-text extraction, via the server's harvest of the PubMed transport/injury subset.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dot-litsearch for reports on pedestrian safety from the last 5 years"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
transport-lit — transportation grey literature over MCP
(Renamed from dot-lit on 2026-08-27; DOT_LIT_* environment variables and the old data directory are still recognised.)
transport-lit gives an AI assistant (Claude Desktop, Claude Code, any MCP client) keyword
search over the transportation research reports that PubMed does not index and Semantic
Scholar covers poorly. It started with ROSA-P, the U.S. National Transportation
Library's repository (NHTSA DOT HS reports, FHWA/FRA/FTA/FAA, UTC and state DOT
research; https://rosap.ntl.bts.gov), and now harvests six OAI-PMH sources on three
continents plus whatever you export from TRID:
key | source | records | notes |
| ROSA-P — U.S. DOT National Transportation Library | 90,599 | full repository |
| VTI — Swedish National Road and Transport Research Institute (DiVA) | 11,460 | reports, conference papers, articles; en/sv |
| BASt — German Federal Highway Research Institute (OPUS) | 2,970 | 1,901 with direct PDF links; de/en |
| World Bank Open Knowledge Repository | 976 | title-filtered subset of 40,332; measured precision 18/20 |
| IPEA (Brazil) | 207 | filtered subset of 14,400; pt; precision ~16/20 |
| CEPAL/ECLAC (Latin America) | 1,165 | filtered subset of 52,199; es/en; precision ~15/20 |
| OpenAlex — works typed report in 10 transport topics (global) | 11,448 | topics: Traffic and Road Safety, Urban Transport and Accessibility, Transportation Planning, … |
| CiNii Research (Japan) — articles, theses, IRDB repository items | 118,609 | needs a free NII application ID ( |
| PubMed — transport/injury subset (MeSH strategy + 12 journals) | 105,028 | date-sliced E-utilities harvest; |
| TRID exports you import ( | yours | see below |
transport-lit sources lists them; transport-lit harvest --source <key>|all harvests them; the
collection filter in search_reports selects one (e.g. "VTI", "BASt", "World Bank",
"CEPAL", "TRID"). Adding another OAI-PMH repository is one entry in
src/transport_lit/sources.py.
I created this for my own personal academic and research use and am happy to share it with anyone else who finds it useful. I welcome feedback on errors, integration needs, improvements and other commentaries. I will check those regularly and will integrate them as much as possible and document that. If you are interested in helping to support this or have other ideas for it, I welcome them! — Alex Quistberg (open an issue)
It does this the only way that works for an OAI-PMH source: it harvests the whole
repository's metadata into a local SQLite database, builds an FTS5 full-text index
over it, and serves search from that index. Nothing is queried live except an optional PDF
fetch for full text. Re-harvests are incremental (from= on the OAI request) and cheap.
Tool surface
Tool | What it returns |
| Ranked hits: id, title, authors, year, report numbers, DOI, landing URL, abstract snippet, |
| Exact match by DOI, PMID, report number ("DOT HS 813 097"), id or landing URL |
| Full metadata record, including every raw field as harvested |
| Resolves the PDF (ROSA-P landing page, BASt/OpenAlex direct links), extracts and caches the text; page with |
| Searches inside all PDF text already extracted, with snippets |
| Related records across sources, by title and subject terms |
| RIS (Zotero/EndNote/Mendeley) or BibTeX for a list of ids |
| Works the record cites (OpenAlex, cached); entries carry |
| Works citing the record; |
| Records that entered the index in the last N days, with counts by source — the raw material for a weekly digest |
| Collections and document types with counts |
| Record counts per source, last run and its status/notes, coverage by year |
Plus one prompt, literature_scan(topic), that walks a model through a multi-query scan with
citations. Every tool carries MCP annotations (readOnlyHint, idempotentHint; only
get_fulltext is openWorldHint because it may fetch one PDF).
id accepts dot:93144, 93144, oai:dot.stacks:dot:93144, or the landing URL. Imported
records use other prefixes (trid:813520, import:…).
Query syntax: bare words are ANDed first; if fewer than limit hits match every term the
remaining slots are filled with any-term matches (match_mode = all_terms /
any_terms). Quote phrases ("driver improvement"), use a trailing * for a prefix.
Ranking is BM25 with title, report number and author weighted above abstract.
Related MCP server: Personal Research Assistant MCP
Setup
Requires Python 3.12+ and 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 evaluationFor development use uv sync and prefix commands with uv run (e.g. uv run pytest).
Any MCP client, any model
The server speaks standard MCP over stdio (default) and Streamable HTTP / SSE
(transport-lit-mcp --transport streamable-http --port 8765, endpoint /mcp). transport-lit mcp-config [client] prints a ready-to-paste snippet for: Claude Desktop, Claude Code,
Cursor, VS Code (Copilot agent mode), Zed, Continue, LM Studio, Goose, Open WebUI and
LibreChat (the last two over HTTP). A Dockerfile builds an HTTP server image with the
index on a volume.
Open models. Tested end to end on 2026-08-26 with Ollama qwen2.5:3b (3 B parameters)
via tests/ollama_smoke.py: given "find reports about driver improvement programs; list 3
titles with years and ids", the model called search_reports({"query": "driver improvement", "limit": 3}) once and answered with correct titles, years, ids and landing URLs from three
sources. Design choices that make small models work: ten tools with one-line-first
descriptions, flat JSON arguments with defaults, compact hit objects (no raw metadata in
search results), and a server instructions string that names the sources and filters. Run
the smoke test with any tool-capable model: OLLAMA_MODEL=llama3.1 uv run python tests/ollama_smoke.py "…".
Register in 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)The entry it writes is simply:
{ "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" } } } }Restart Claude Desktop afterwards. For Claude Code: claude mcp add transport-lit -- transport-lit-mcp.
Configuration (environment variables)
Variable | Default | Purpose |
|
| SQLite DB, raw OAI pages ( |
| (unset) | Your e-mail, placed in the User-Agent so the repository can contact you. Set it. |
|
| Minimum seconds between outbound requests |
|
| Per-request timeout (s) |
| 80 MB | Refuse larger PDFs in |
| 600 | Stop extraction after this many pages |
| (unset) | NII application ID; required to harvest CiNii (register at support.nii.ac.jp/en/cinii/api/developer) |
| (unset) | Optional; raises PubMed E-utilities rate from 3 to 10 req/s |
| built-in strategy | Replace the PubMed search strategy |
| fastembed / MiniLM-L12 / 1024 | Semantic search backend, model, Ollama truncation |
|
| Ollama endpoint for the |
Variables can also live in ~/.config/transport-lit/env as KEY=VALUE lines (real
environment variables win); that is where a NII application ID or NCBI key belongs, so the
launchd jobs, the MCP server and manual runs all see it. No credentials are required; all
endpoints are public.
Install from PyPI (no clone)
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 backendPublished at https://pypi.org/project/transport-lit/ through GitHub's trusted publishing:
a tag runs release.yml (build, GitHub release), which then dispatches publish.yml — the
one workflow registered as a trusted publisher — where the upload waits for the maintainer's
approval on the pypi environment. PyPI rejects tokens from reusable workflows and matches
the top-level workflow file, which is why publishing is a separate dispatched workflow
rather than a job inside the release. server.json is the manifest for the
MCP Registry (registry.modelcontextprotocol.io), to submit after the PyPI package exists.
Pinned versions
Releases are git tags vMAJOR.MINOR.PATCH (semantic versioning: patch = fixes, minor = new
tools/sources, major = a breaking change to the tool surface or database schema). Each tag
triggers the release workflow, which runs the tests, builds a wheel + sdist and attaches
them to a GitHub Release. Python dependencies are pinned by the committed uv.lock; CI
installs with uv sync --frozen, so a release always runs against the exact versions it was
tested with. To install a specific version:
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 releaseHarvesting
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 changeWhat the harvester does and why (all behaviour verified against ROSA-P on 2026-08-26):
ListRecords&metadataPrefix=oai_dc, 100 records per page, followingresumptionTokenuntil a page arrives without one. Only then is the run markedcomplete; any error leaves itfailedand does not advance the "last harvest" pointer, soharvest_statusnever claims a partial index is complete.Pacing: one request per
TRANSPORT_LIT_MIN_INTERVALseconds (default 1 s). Tokens expire about 60 s after issue, so retries use short backoff (2/4/6 s).badResumptionToken, transport errors, truncated XML, or an empty envelope while a token is live → the list is re-issued. ROSA-P does not return records in a stable datestamp order (checked on every page), so recovery restarts the list from the top; upserts make that idempotent. If ordering had been monotone the harvester would instead resume from the smallest datestamp seen viauntil=. Up to 8 recoveries per run, thenfailed.noRecordsMatch: ROSA-P does not send the error code; an empty selective harvest comes back as an OAI-PMH envelope with no<ListRecords>element. That is mapped to "nothing to do" only when no token was in play; mid-list it is treated as truncation.Silent truncation checks: the token's
cursoris compared with the local count on every page; a full harvest that returns >5 % fewer records than the previous full harvest is flagged in the run notes. Both appear inharvest_status().last_harvest.notes.Deletions: the repository reports
deletedRecord=no, so nothing is ever removed locally; a record that vanishes from ROSA-P stays in the index until a full re-harvest into a freshTRANSPORT_LIT_DATA_DIR.Caching: every OAI page is stored gzipped under
raw/run<N>-p<page>.xml.gz, so the parser can be changed and the index rebuilt without touching the network; PDFs and their extracted text are cached underpdf/and in thefulltexttable.from/untilare formatted to each repository's declaredgranularity(read fromIdentify): ROSA-P, DiVA and DSpace take fullYYYY-MM-DDThh:mm:ssZtimestamps, OPUS (BASt) takes onlyYYYY-MM-DDand the window is widened a day each side.Broad repositories (World Bank, IPEA, CEPAL) are filtered at harvest time by a multilingual transport vocabulary (
sources.TRANSPORT_RE, en/es/pt/de/fr/sv): a record is kept if a term appears in the title, or (IPEA, CEPAL) if two distinct terms appear among the subject headings. Abstracts are ignored — development literature mentions roads and ports in passing — and World Bank subjects are ignored too (100+ headings per record). This was tuned on 2026-08-26 against random 20-title samples: the loose title+subjects+abstract rule kept 15,271 World Bank records at roughly 35–50 % precision; the final rule keeps 976 at 18/20, IPEA 207 at ~16/20, CEPAL 1,165 at ~15/20. Recall is the price; loosenmin_subject_hitsinsources.pyand runtransport-lit reindex --source <key>(no network) if you want the other trade. The run notes record kept vs skipped.transport-lit doctor [--repair]checks SQLite integrity, both FTS indexes, runs stuck inrunning, impossible timestamps and WAL size, and repairs what is safe; the store also checkpoints the WAL on close.transport-lit cite prefetch [--source …]resolves every DOI/PMID/OpenAlex-bearing record to its OpenAlex work in bulk (50 per request) socited_by_countis known for them without a per-record call.
transport-lit reindex --source <key> re-parses the cached pages and prunes records the
current parser/filter no longer keeps, so filter changes never need a re-harvest.
Monthly rebuild and weekly updates (maintenance schedule)
The corpus changes slowly, so the cadence is: weekly incremental harvest and a monthly
fresh rebuild. harvest --fresh full-harvests into a temporary store and then atomically
replaces the dot: records in the live index — the only way records ROSA-P stops serving
ever disappear (its OAI-PMH endpoint does not track deletions). Imported sources (TRID
exports) are untouched, and a failed rebuild changes nothing.
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`Logs land in $TRANSPORT_LIT_DATA_DIR/logs/. On Linux use the cron lines the command prints.
Monthly maintenance checklist (done with the rebuild): read new GitHub issues; uv lock --upgrade && uv run pytest; note fixes in the changelog section of the release; bump
version in pyproject.toml and src/transport_lit/__init__.py; git tag vX.Y.Z && git push --tags.
TRID: import what you export
TRID (https://trid.trb.org) is the most complete transportation bibliography and the
natural complement to ROSA-P, but it has no API, its FAQ says TRB "does not grant access to
TRID backend systems or lift export/download restrictions", and its robots.txt disallows
AI crawlers. What every user may do is search and export. So:
Run your search in TRID, choose Export → RIS (CSV and XML are also offered).
transport-lit import ~/Downloads/trid-driver-improvement.ris --collection "TRID: driver improvement"
Records get ids trid:<accession> from the TRID view URL, land in the TRID collection
(search_reports(..., collection="TRID")), and re-importing the same file is idempotent.
The importer is generic RIS, so Zotero/EndNote/Scopus exports work the same way with
--source <prefix>. get_fulltext on an imported record only follows a direct .pdf
link; otherwise use landing_url.
What ROSA-P's OAI-PMH endpoint offers
https://rosap.ntl.bts.gov/fedora/oai — repository "DOT Stacks" (the CDC Stacks platform),
protocol 2.0, earliest datestamp 2008-07-02, no deletion tracking, no OAI sets
(ListSets is empty), and oai_dc is the only metadata format. It is a qualified
Dublin Core in disguise, though: elements such as dc:contributor.author,
dc:description.abstract, dc:relation.isPartOf, dc:identifier.uri (DOI and report
numbers, e.g. DOT HS 813 827), dc:coverage.spatial, dc:title.alternative and
dc:description.tableOfContents are all present. The parser (dc.py) keeps every raw
field and derives the typed columns from them. dc:relation.isPartOf (semicolon-separated)
is what list_collections / the collection filter use.
PDF links are not in the metadata; get_fulltext reads citation_pdf_url from the landing
page and falls back to the datastream convention /view/dot/{n}/dot_{n}_DS1.pdf.
Verification (2026-08-26)
v0.4.0 semantic search. 342,462 vectors (fastembed multilingual MiniLM-L12, 384-d,
data-parallel at 94 records/s on 8 cores — 60 min for the corpus). Cross-language check:
"elderly pedestrian crashes at night" in semantic mode returns, among its top 8, three
Japanese-language CiNii reports (夜間 高齢歩行者 死亡事故 analyses, 1995–2011) beside PubMed
and English CiNii items; vocabulary check: "point system for problem drivers license suspension recidivism" finds ROSA-P's 1997 California vehicle-impoundment evaluation and
1986 administrative-revocation report, which share no query words. Hybrid latency ≈ 0.6 s
(query encoding dominates), keyword ≈ 25 ms. Operational lesson recorded here so nobody
repeats it: never delete a SQLite -wal file while another process (e.g. a running MCP
server) has the database open — it holds committed data not yet checkpointed.
v0.3.0 API sources. OpenAlex: 58 pages, 11,448 reports (10 topics, type:report),
1,428 with PDF links. CiNii: 730 pages, 144,348 hits over 20 queries, 118,609 unique. PubMed:
105,028 articles in 17 date slices (E-utilities caps retstart at 10,000, so slices are
found recursively). Open-model check: Ollama qwen2.5:3b answered a driver-improvement
question with one correct search_reports call.
v0.2.0 multi-source harvest. VTI: 120 pages, 11,944 seen, 11,460 unique (DiVA serves
some records in several sets), 0 resumptions. BASt: 30 pages, 2,987 seen, 2,970 unique;
1,901 with direct PDF links; day-granularity incremental path exercised (24 records).
World Bank: 404 pages / 40,332 seen; IPEA: 144 / 14,400; CEPAL: 522 / 52,199 — all ended on
a token-less page with 0 resumptions; filtered counts above. Spot searches: Fußgänger Unfall (BASt) → crash reconstruction and rural-road crash statistics; acidentes de trânsito mortalidade (IPEA) → "Mortalidade por acidentes de transporte terrestre e
desigualdades interestaduais no Brasil"; seguridad vial peatones (CEPAL) → road-safety
governance and campaign evaluations; pedestrian safety (VTI) → 1990s child-pedestrian
training studies.
v0.1.0 (first ROSA-P harvest)
Harvest completeness. Run 1 (full) walked 908 pages / 90,706 records in 15 min
(00:03:59–00:19:11 UTC) with 0 resumptions, 0 cursor mismatches, and ended on a page of 6
records with no resumption token — the OAI-PMH definition of a complete list. 90,603
unique records are in the store; the 103-record gap is the same record appearing on two
pages, which happens because ROSA-P does not return records in a stable order (the
harvester logs this: "datestamp ordering violated on page 2"). A second independent full
pass, 30 minutes later into a separate directory, returned exactly the same numbers —
908 pages, 90,706 seen, 90,603 unique — and the two ID sets are identical (0 records
unique to either pass). The 103 repeats are the repository serving the same record on
two pages, not records being skipped.
Coverage by decade (year present for 74,448 = 82 %; the remaining 16,155 have no date
in any metadata field; year_source says whether a year came from dc:date (48,658), a
bare-year description line (22,205) or the title (3,585)):
decade | records | decade | records |
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 |
Known-item retrieval (transport-lit search …, rank 1 unless noted):
Target | Query | Result |
NHTSA Countermeasures That Work |
| dot:1789 (2005), dot:1827 (3rd ed. 2008), dot:40255 (1st ed. 2006), dot:1778 (2nd ed. 2007); 11th ed. 2023 is dot:72947 (DOT HS 813 490), 10th ed. dot:57466. The bare phrase alone ranks the one-page Traffic Tech summaries of CTW first (short documents win on BM25), then the guides. |
Oregon DMV Driver Improvement Program evaluation (Strathman et al., 2007) |
| dot:21848 "Evaluation of the Oregon DMV driver improvement program", Strathman, Kimpel, Leistner; report no. SPR 634. Undated in ROSA-P metadata. |
Virginia driver improvement reports (Lynn, 1982) |
| dot:18959 (12-month report), dot:18905 (short-term effects), dot:18969 (24-month final report), all Cheryl Lynn, Virginia Highway & Transportation Research Council. Undated in ROSA-P metadata. |
Real query driver improvement program evaluation negligent operator (top 6 of 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)
Full-text extraction was checked on dot:93144 (DOT HS 813 827, 3.7 MB PDF, resolved via
citation_pdf_url). Unit tests: uv run pytest (parser for both metadata profiles, year
fallback, FTS search/filters, upsert idempotence, query tokenizer, id normalisation).
Layout
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)Adding a second source later (e.g. NHTSA crashstats)
The store is source-agnostic: records.id is a prefixed string (dot:93144 today),
harvest_runs.source records which harvester wrote a run, and the FTS index does not care
where a row came from. To add a source:
Write
src/transport_lit/sources/<name>.pyexposingharvest(store, *, mode, progress)that yields dicts in the same shapedc.parse_recordproduces (id,title,authors,year,abstract,report_numbers,doi,landing_url,collections,raw, …) and callsstore.upsert_records(). Use a new id prefix (nhtsa:812115) and pass your ownsourcename tostore.start_run()soharvest_statuscan report it separately.Reuse
oai.RateLimiterandconfig.USER_AGENTfor etiquette; store raw responses underraw/<source>/for reproducibility.Give
harvest.status()a per-source block (count byidprefix).Add a
--sourceoption totransport-lit harvestand, if the source has its own facet, a corresponding filter onsearch_reports.Dedupe against ROSA-P by DOI / report number (
records.doi,records.report_numbers) rather than by title — NHTSA reports are often present in both places.
Verified facts for the NHTSA crashstats source, so nobody re-derives them:
https://crashstats.nhtsa.dot.gov/Api/Public/Publication/{id} returns the PDF directly
(812115 → NMVCCS critical-reasons report, application/pdf, ~0.5 MB). It is a
document-retrieval endpoint, not a search or listing API, so a connector will need an
enumeration strategy (e.g. the DOT HS numbers already present in ROSA-P
report_numbers) rather than a crawl.
Beyond the U.S.: candidate sources assessed (2026-08-26)
Probed live for (a) whether the holdings are literature rather than datasets and (b) whether there is machine access that fits this harvester. Counts are what the endpoints reported that day.
Source | Holdings | Machine access | Verdict |
VTI (Sweden) via DiVA | 7,474 records, set | OAI-PMH, | Harvest — drop-in |
BASt (Germany) OPUS | 2,987 records; federal highway research institute reports | OAI-PMH, | Harvest — drop-in |
World Bank Open Knowledge Repository | 40,332 records; 1,787 hits for "transport safety"; OAI set | OAI-PMH (DSpace 7) + DSpace REST | Harvest all, keep by subject; or REST query |
WHO IRIS | 276,681 records; 3,334 hits for "road traffic"; no sets | OAI-PMH + DSpace REST search | REST query by subject (full OAI walk is 2,800 pages) |
CEPAL repository (Latin America) | 52,199 records; no subject sets | OAI-PMH + DSpace REST | Harvest and filter by subject |
MTT Chile Biblioteca Digital de Transportes | 5,820 | Open Hasura GraphQL at | Harvestable via GraphQL; confirm terms of use with MTT first |
OpenAlex | 2,604 works typed report matching "road safety"; 16,639 works of any type for "pedestrian safety" | Free REST API, cursor pagination | Best global aggregator; use as a source for non-U.S. grey lit and DOIs |
GOV.UK (DfT) | 4,998 DfT items for "road safety research" | Free content API | Harvestable; needs document-type filtering |
Spain, Centro de Documentación del Transporte | 66,000 bibliographic records (45,000 monographs) in AbsysNet | OPAC only; site blocks non-browser clients (HTTP 403) | Out of scope unless the ministry exposes OAI/Z39.50 |
TRIMIS (EU) | EU-funded transport projects and results | Site up; no documented API (bulk open-data dumps exist) | Evaluate the open-data dump, not the site |
IDB Publications, CAF Scioteca | Development-bank transport reports | DSpace, but bot-blocked (403 / challenge page) | Out of scope unless access is granted |
SWOV (Netherlands) | Road-safety institute library | Bot-detection page on every path | Out of scope |
ITF/OECD | International Transport Forum reports | HTTP 403 to non-browser clients; no API | Out of scope (OECD iLibrary API is licensed) |
Transport Data Commons | Datasets (32 institutions, 120+ countries), PortalJS | No API found ( | Not literature |
ITDP Rapid Transit Database | Dataset (BRT/LRT/metro km per city); Google Sheet download | Download only | Not literature |
AASHTO TERI database | Research-needs statements, not completed reports | None | Not literature |
nismod/Africa-transport-database (GitHub) | GIS dataset of African transport infrastructure | Git clone | Not literature |
TRID | 1.5 M bibliographic records, international | None; export/backend access refused by policy | Out of scope |
By region (same-day probes; "open" means unauthenticated machine access confirmed):
Region | What exists | Access | Notes |
Europe | VTI (SE), BASt (DE) — above; HAL (FR): 74,952 items in the Université Gustave Eiffel/IFSTTAR collection, 117 | HAL REST (open), OpenAIRE REST (open), Cellar SPARQL (open), CORDIS JSON (open); DTU Orbit OAI 500, TU Delft OAI not found, TØI 403 | ITF/OECD's ITRD merged into TRID, so ITF content is reachable only through TRID |
Australia / NZ | Figshare OAI-PMH + REST (Monash/MUARC and other AU universities publish reports there); NZTA research report pages (HTML, 200); Austroads (403 to non-browsers); APO grey-literature observatory (403 to non-browsers); Trove API (needs key) | Figshare open; Trove key-gated; APO/Austroads bot-blocked | Figshare search for "road safety" reports returns mostly datasets/code — needs item-type + institution filtering to be useful |
Japan | IRDB ( | All open, no key | IRDB is the grey-lit route (theses, technical reports from universities); NILIM/PWRI ministry reports are web-only |
India | Shodhganga OAI not found at DSpace paths; CSIR-CRRI site is static HTML; IRC/MoRTH web-only | None found | Best coverage is OpenAlex/OpenAIRE for Indian journal output; no harvestable grey-lit source identified |
China | No open repository of MOT/RIOH reports; RIOH site is static; CNKI is licensed | None found | OpenAlex returns 15,416 works from CN institutions for "traffic safety" (journal literature) — that is the realistic route |
Latin America | IPEA (BR) | IPEA/CEPAL OAI open; MTT GraphQL open; IDB/CAF bot-blocked; LA Referencia OAI not found at guessed URLs | SciELO OAI endpoints not found at legacy paths (journals anyway) |
The three OAI-PMH repositories with completeListSize (VTI, BASt, World Bank OKR) fit the
existing harvester with a source prefix and a per-source metadataPrefix; DSpace 7 sites
also tolerate from/until and return proper noRecordsMatch, so the ROSA-P quirks in
oai.py are already the harder case.
TRID is out of scope
TRID (https://trid.trb.org) has no public API, no OAI-PMH endpoint and no bulk export. Its FAQ states that "TRB does not grant access to TRID backend systems or lift export/download restrictions for individuals or organizations" and that the database may not be used to train LLMs. It is deliberately not scraped here.
v2 order (agreed 2026-08-26)
VTI + BASt(done, v0.2.0) — 2.World Bank OKR, IPEA, CEPAL(done, v0.2.0) —IRDB Japan — 4. OpenAlex
type:reportas global backstop — 5. a PubMed transport subset (see below). VTI note: DiVA'soai_dccarries no full-text link; switching that source toswepub_mods/mets_kbwould giveget_fulltexttheFULLTEXT01.pdfURL.
PubMed: a transport/injury subset, not all of PubMed
PubMed's E-utilities (esearch/efetch, free, 3 req/s without a key) can maintain a
local subset from a fixed strategy, refreshed with mindate/maxdate on the same
weekly/monthly cadence. Two complementary filters, OR-ed together:
MeSH strategy —
"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])— catches transport papers in general and clinical journals.Journal list — 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 (transport-tagged only), etc. — catches transport papers indexed without the MeSH terms.
SafetyLit (safetylit.org, the WHO-affiliated weekly injury-literature bulletin) maintains exactly such a journal list and hand-classifies articles by topic, which would make it the best seed for the journal filter; its site was unreachable (connection refused on every host name) when checked on 2026-08-26, so its current status is unconfirmed.
Weekly digest (a SafetyLit-style bulletin)
transport-lit digest --days 7 [--abstracts] prints a Markdown bulletin of everything that entered
the index in the last week, grouped by source, with counts. It is driven by first_seen_at,
which is set the first time a record is seen and preserved across fresh rebuilds, so a
monthly rebuild does not make the whole index look new. The whats_new tool exposes the
same data to a model, which can then write the summaries — the editorial step SafetyLit did
by hand.
Compared with other literature MCPs
PubMed, Semantic Scholar, OpenAlex and arXiv MCP servers proxy live queries to one API.
transport-lit differs in three ways: it indexes grey literature the aggregators lack (agency
reports, state DOT evaluations, ITRD-contributing institutes), it runs offline on a local
index after harvesting (no rate limits at query time, no key), and it is multi-source
with one id scheme, so a model can search everything at once and export citations. What
those servers have that this one still lacks: citation graphs (who cites whom), author
disambiguation, and semantic (embedding) search — see below.
Citation graph (v0.5)
get_references / get_citations (CLI: transport-lit cite refs|cites <id> [--in-index]) attach
OpenAlex's citation graph to the index. A record is matched to an OpenAlex work by its
OpenAlex id, DOI, PMID, or — for the many undated, DOI-less agency reports — an exact
normalised title with the year within ±1 (match in the result says which). Edges are
fetched on first request and cached in the citations/works tables; citing lists are
refreshed after 90 days, references never change. Cited works that are themselves in the
index come back with their record_id, and search hits carry cited_by_count once known.
Verified 2026-08-27: the Oregon DMV DIP evaluation (dot:21848, no DOI, no date in ROSA-P)
resolved by title and lists 6 citing works, among them Iowa's DIP evaluation and the NJ
recidivism study; Lynn's 1982 Virginia 24-month report is cited by the 2003 Cochrane
review of post-licence driver education (pubmed:12917984, in the index); a 2020 Seoul
elderly-pedestrian paper has 57 references, 19 in the index. OpenAlex's coverage of NTL's
10.21949/… DOIs is thin: a bulk pass resolved 4,257 of the 15,493 ROSA-P records that
carry one, and a random sample of the remainder found 1 in 50 known to OpenAlex. So most
ROSA-P reports — DOI or not — depend on the title match, which accepts an exact normalised title, a
prefix relation (edition or subtitle tails), or ≥ 0.8 token overlap, always with the year
within ±1; when several OpenAlex entries fit (it holds duplicates of many reports), the
most-cited one is taken as canonical. Grey literature that nobody has cited in indexed venues will still show zero;
that is a property of the citation data, not of the index. OpenCitations and Semantic
Scholar could be added as fallbacks in the same tables.
Semantic search (v0.4)
Keyword search is FTS5/BM25. Adding vectors turns search_reports into a hybrid search
(BM25 and cosine fused by reciprocal rank) that finds records by meaning and across
languages — an English query reaching Swedish, German, Spanish, Portuguese or Japanese
records. Everything runs locally; no account, no 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 semanticSemantic results are diversified by source: no single source may fill more than half
of the requested results unless source/collection narrows the search
(TRANSPORT_LIT_SEMANTIC_PER_SOURCE). Measured reason: CiNii is a third of the index and
holds thousands of short English titles ("Pedestrian safety problems and countermeasures")
that sit nearer a short query than any abstract-bearing record; the with/without-abstract
cosine gap is only ~0.01, so this is corpus composition, not a length artifact, and a cap is
the honest remedy. mode="semantic" is the specialist setting; hybrid stays the default.
Hybrid fusion weights the keyword list 1.0 and the semantic list 0.7
(TRANSPORT_LIT_SEMANTIC_WEIGHT), and a semantic-only candidate must clear cosine 0.5
(TRANSPORT_LIT_SEMANTIC_MIN); that keeps precise queries precise while mode="semantic"
stays the recall / cross-language setting.
embed only processes records that have no vector yet, so after the first pass the weekly
harvest adds seconds. Vectors live in $TRANSPORT_LIT_DATA_DIR/vectors/<backend-model>/ as a
memory-mapped float16 matrix (342k × 384 ≈ 260 MB); search is a chunked dot product, no
extension. The active vector set is recorded in the index, so search_reports(mode=…)
uses whichever backend produced it: hybrid (default), keyword, or semantic;
mode_used in every result says what ran, and it degrades to keyword when no vectors exist.
harvest_status() reports backend, model, dimension and coverage.
Backends measured on 2026-08-26 on a 10-core Apple Silicon laptop, 256 real records
(title + abstract): fastembed MiniLM-L12 ≈ 30 records/s on CPU (the CoreML provider is no
faster); Ollama qwen3-embedding:0.6b ≈ 20/s (1024-d), qwen3-embedding:8b ≈ 1.4/s
(4096-d, truncated to 1024). So the first full pass over 342k records is a one-time ~3 h
with the default model; the weekly increment is seconds. Use --source to embed one source
with a heavier model. Note the MiniLM model reads at most 128 tokens (title plus the first
~90 words of the abstract); Qwen reads the full 1,500-character window and gets the model's
retrieval instruction prefix on queries. Most users should install a snapshot (below) and
never run the full pass at all.
Snapshots: skip the harvest
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 --writeThat is a complete, searchable install in minutes: 224k records (everything except CiNii and
TRID) with vectors. transport-lit snapshot build <file.tar.gz> packs the SQLite index plus the
active vectors; snapshot install <url-or-file> unpacks one into a fresh
TRANSPORT_LIT_DATA_DIR, after which weekly incremental harvests keep it current (the
snapshot carries the harvest bookkeeping, so harvest --source all knows where to resume). Snapshots
leave out CiNii (its API terms require registration and are silent on redistribution)
and TRID imports (TRB's terms); users harvest those themselves. Releases carry a
snapshot when one was built.
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. Dates show when Glama detected each change.
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
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
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