ndl-mcp
MCP server for searching the National Diet Library of Japan (NDL Search), enabling Japanese-script bibliographic and article searches with rate limiting and attribution.
README
ndl-mcp
An MCP server for searching 国立国会図書館サーチ (NDL Search), operated by the National Diet Library of Japan, over the SRU searchRetrieve interface.
Third in a series with cinii-mcp and jstage-mcp, and sharing their response envelope: typed query and script, matching mode, graduated breadth, per-item matched_in, typed diagnostics, a loggable receipt, attribution.
Before you run this
There is no credential. The NDL search APIs are open. No API key, no application ID, no token, nothing to paste into a config file. If you are waiting for something to arrive before you can use this, you are waiting for something that is not coming.
There is still an obligation. Section 17 of APIのご利用について asks continuous API users to report their contact details and the nature of their use through the application form — 「事前の利用申請の要否にかかわらず」, whether or not a prior usage application is required of them. A formal 利用申請 is required only for revenue-generating use; the notification is asked of everyone who accesses continuously.
Because access is not gated on the filing, nothing in the world will stop you skipping it. So install.ps1 stops you: it refuses to register the server until the notification is recorded, and writes the date to NDL-API-NOTIFICATION.txt.
.\install.ps1 -NotificationFiled 2026-08-19
Run it without the flag and it prints the form URL, offers to open it, and exits.
What the server will not do
The undertakings below were filed with the NDL. They are implemented, not aspired to, and the installer's smoke test asserts the first three:
| Undertaking | Implementation |
|---|---|
| Requests issued serially; no concurrent access | _rate_lock is held across the wait and the request |
| Minimum one-second interval | MIN_REQUEST_INTERVAL = 1.0 |
| A cap on records per search; no bulk retrieval | MAX_RECORDS = 100, a fifth of the NDL's own 500; no auto-pagination |
| The harvesting interface is not used | OAI-PMH is not implemented |
| Credit on every response | ATTRIBUTION plus provider_credit() on every envelope |
| Metadata displayed, not accumulated | no cache, no local store |
Change any of them and you are changing what was declared to a national library. File a supplementary notification first.
Providers
Only the five sets declared in the application are reachable. All are NDL-created and CC BY, and none requires a usage application:
| dpid | 名称 |
|---|---|
iss-ndl-opac |
国立国会図書館蔵書 |
iss-ndl-opacnational |
国立国会図書館全国書誌情報 |
zassaku |
国立国会図書館雑誌記事索引 |
zassaku-online |
国立国会図書館雑誌記事索引オンライン資料編 |
ndl-dl-open |
国立国会図書館デジタルコレクション(オープンデータ) |
ndl-dl and ndl-dl-online — the wider Digital Collections — are marked △ on the provider list and require an application that has not been made. A request naming them is refused in process, with a DPID_NOT_PERMITTED diagnostic, rather than sent.
Tools
| Tool | Set searched |
|---|---|
ndl_search_books |
蔵書 |
ndl_search_national_bibliography |
全国書誌情報 |
ndl_search_articles |
雑誌記事索引 (both sets) |
ndl_search_digital_open |
デジタルコレクション(オープンデータ) |
ndl_search_all |
all five |
ndl_get_record |
one record by jpno or ndl_bib_id |
Search fields: title, creator, publisher, subject, anywhere, ndc, isbn, issn, from_year, to_year. They are combined with AND; title, creator, publisher and subject match partially, ndc by prefix, identifiers exactly.
ndl_get_record is a fetch, so its envelope omits searched_for — no term was chosen.
Two things that will bite
An uppercase AND, OR or NOT inside a search term makes NDL reject the whole query. Not "returns nothing" — rejects. The rule is case-sensitive as the specification states it: War AND Peace is caught, War and Peace passes. The server checks before sending and returns a RESERVED_WORD_IN_QUERY diagnostic naming the offending field, rather than letting the library answer with a parse failure.
NDL enforces a rate limit it will not quantify, and answers HTTP 429. The help page says only 「同時リクエスト数には制限を設けています」 and declines to publish a figure. In testing on 19 August 2026 a 429 arrived at well under one sustained request per second — so the one-second floor filed with the library is a minimum, not a guarantee. A 429 buys one backoff, honouring Retry-After, and then the server stops rather than pressing. It reports RATE_LIMITED, deliberately distinct from API_ERROR, because the two mean different things to a reader: a rate-limited search has an unknown result, not an empty one, and must never be written up as an absence.
A romanised term will under-return. NDL Search indexes Japanese-language records in Japanese script. A Latin-script query against a Japanese corpus is the romaji trap, and the envelope raises SCRIPT_LATIN_QUERY for it. The searched_for headline exists so that the term the assistant actually chose is visible at the top of the response rather than buried — that is the whole point of the field, and the reason a disclosure can report the terms a search used.
Receipts
mediation.emit() writes each response envelope to the append-only, hash-chained ledger at MCP_RECEIPT_LOG, which install.ps1 sets to the same file the other servers use. Unset the variable and nothing is written and nothing fails.
Note what the ledger holds and what it does not: the query, the normalised term, the parameters sent, the timestamp, a SHA-256 over query and parameters, and the identifiers of the records returned. It does not hold the bibliographic records themselves. Logging a query is not accumulating a database, and the undertaking against accumulation is not breached by keeping the receipt — but the distinction is worth stating rather than assuming, because the two look similar from outside.
Why SRU only
The application declares SRU and OpenSearch. This server implements SRU alone, which is less than was declared and therefore safe — you may always use less than you told the library you would.
The reason is evidential. The OpenSearch response format is not documented in the 第1.4版 specification: no element table, no sample, and the appendices cover SRU and OAI-PMH only. Worse, the spec states that a malformed parameter returns a zero-result response rather than an error — 「引数(パラメータ)誤りの場合には検索結果ゼロ件となる」 — so a typo in a field name is indistinguishable from a genuine absence. For a tool whose purpose is to let a historian trust that nothing was found, that is disqualifying. SRU returns typed diagnostics and a documented DC-NDL record schema. Adding OpenSearch later needs no new notification; it needs a documented response format.
Sources
- 国立国会図書館サーチ 外部提供インタフェース仕様書 第1.4版 (2026-03-31)
- APIのご利用について — terms, credit requirement, concurrency, notification
- API提供対象データプロバイダ一覧 — dpid values and licence conditions
Licence
MIT. Metadata retrieved through this server is CC BY 4.0 from the National Diet Library; the credit line the server emits is the attribution that licence requires, and it should survive into anything you publish from the results.
What has been tested, and what has not
Verified against the live API on 19 August 2026:
- Japanese-script search across 蔵書 and 雑誌記事索引 — correct totals, correct records, correct years and identifiers.
- DC-NDL parsing, including the manifestation-stub filter. NDL returns two
BibResourceelements per record; taking both doubled the result set with blanks until the filter went in. searched_forreports the term chosen, not the assembled CQL, so its script detection is meaningful; the exact CQL is carried inquery.paramsand is fixed by the receipt hash.- The
DPID_NOT_PERMITTEDguard: a request namingndl-dlis refused in process. RESERVED_WORD_IN_QUERY:War AND Peacecaught,War and Peacepassed.- The rate limiter, involuntarily — see HTTP 429 above.
Not verified against the live API, and read rather than run: the "Record does not exist" passthrough, ndl_get_record, and the backoff path. Testing stopped at the 429 rather than continuing, because characterising an undisclosed rate limit by probing it is precisely the 継続して大量のアクセス the terms warn about, and the point of this server is not to be the thing the National Diet Library has to block. Exercise those paths in ordinary use, a query at a time.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。