ndl-mcp
Search Japanese national library catalogues (NDL Search) and fetch individual bibliographic records, all read-only.
Search books/monographs in NDL holdings (
ndl_search_books)Search the Japanese National Bibliography for authoritative imprint data (
ndl_search_national_bibliography)Search the NDL periodicals index for Japanese magazine/journal articles, including online materials (
ndl_search_articles)Search NDL Digital Collections open-data materials (
ndl_search_digital_open)Search all five declared provider sets at once (
ndl_search_all)Fetch a single record by JP number or NDL bibliographic ID (
ndl_get_record)Filter searches by title, creator, publisher, subject, keyword, NDC/NDLC, ISBN, ISSN, and date range
Limit results to 1–100 records and page from a start position
Receive structured response envelopes with diagnostics, matched terms, and provider credit
Use tools safely with serialized, rate-limited requests and no credential required
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., "@ndl-mcpsearch for books about Japanese history"
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.
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.
What this is for
The National Diet Library receives everything published in Japan, and this reaches five of its own catalogues: general holdings, the Japanese National Bibliography, the periodicals index, that index's online-materials companion, and the open-data digital collections.
Use the national bibliography when an imprint fact has to be right — a date, a publisher, an edition statement — because it is the authority other catalogues copy from. The periodicals index reaches article-level records for Japanese magazines and journals going back well beyond what CiNii or J-STAGE hold, which is where prewar and early postwar material becomes searchable. Single records resolve by JP number or NDL bibliographic ID.
Requests are issued one at a time, at a measured pace, under the undertakings filed with the library.
Related MCP server: jp-lit-mcp
What the receipts are for
A search you cannot re-run is a claim you cannot check. When a footnote rests on a database query, say that no article in this index uses a term before a certain year, the reader is asked to take the search on trust: which term, in which script, on what date, against which index and which version of it, and how far down the results the author went. Ordinary searching leaves none of that behind. This server leaves all of it. Every query-answering tool returns its envelope through the ledger, which appends one line to an append-only file: the term actually sent and its script, how the source matched it, how many records existed and how many came back, the diagnostics, the tool and its parameters, the server version, a timestamp, and the hash of the previous line. The hash makes the file a chain: a line cannot be altered, removed or reordered afterwards without the verifier saying so.
What that gives a researcher:
A citable search. Name the receipt in the footnote (session slug, server, date, line hash) and a reader can see exactly what was asked and run it again against the same version.
Negative findings that carry weight. "Not found" is evidence only if the search that produced it is on record, with its term, its script and its breadth.
A method section that writes itself.
ndl-mcp-ledgermanifest <folder>summarises every query a project made, by server, script and session: the disclosure a journal, a data-availability statement or a research-integrity review asks for.A record of AI-mediated research. When a model chose the term, the receipt shows the term it chose and what came back, which is the thing to disclose about work done with an assistant.
Nothing interpreted. The receipt is the source's own answer with credentials removed. The server does not summarise, rank or paraphrase, so the record is of the source, not of the tool.
Receipts are off until you name a folder (MCP_RECEIPT_DIR); each server then writes its own
<server>.jsonl inside it, and MCP_RECEIPT_SESSION stamps a project or article slug on every
line so one folder can serve several projects. ndl-mcp-ledger verify-dir <folder> checks the chains.
The mechanics, the variables and what the envelope says when nothing is deposited are in the
receipts section below.
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.
Registering is recommended. The author filed a notification of continuous use on 19 August 2026 through the form described in APIのご利用について. The library replied that registration is no longer required, though still welcome. A formal 利用申請 remains necessary only for revenue-generating use.
Register anyway. It costs a few minutes, it tells the library who is using the interface and for what, and a national library that can see its API being used by researchers has an argument for keeping it funded and open that it does not otherwise have. Scholarly infrastructure survives on evidence of use.
install.ps1 records the date to NDL-API-NOTIFICATION.txt when you pass it:
.\install.ps1 -NotificationFiled 2026-08-19Run it without the flag and it prints the form URL, offers to open it, and continues with the install.
Python. The pip and source routes need Python 3.10 or later; 3.10, 3.12, 3.13 and 3.14 are tested in CI on Windows, macOS and Linux. The Claude Desktop bundle uses whichever of these is already installed, and has uv download one only if none is.
Install
Three routes. All three give you the same server; pick by how much you want to see of it.
Getting Python
Every route needs Python 3.10 to 3.14. The Claude Desktop bundle uses one already on the machine
and has uv download one only if none is; the other routes also need the venv module, which the
official installers include.
Windows. Download the 64-bit installer from python.org/downloads and run it; tick "Add python.exe to PATH" on the first screen. Afterwards
py --version(the launcher the installer adds) orpython --versionin a new terminal should print 3.1x. If typingpythonopens the Microsoft Store instead, Windows has no Python yet: that Store page is a stub, and it is also what "'python' is not recognized" usually means.macOS. The python.org installer, or
brew install python@3.13with Homebrew. The/usr/bin/python3that Xcode's command-line tools provide may be older than 3.10;python3 --versionsays.Linux. Your distribution's package:
sudo apt install python3 python3-venvon Debian and Ubuntu,sudo dnf install python3on Fedora. Or let uv provide one (next line).Any platform, with uv. uv installs Python itself:
uv python install 3.13, thenuv venvor theuvxroute below.
One click: the Claude Desktop bundle
Download ndl-mcp-1.2.1.mcpb from the latest release and open it; Claude Desktop installs it. One bundle serves Windows, macOS (Apple Silicon and Intel) and Linux. Claude Desktop asks only for a receipts folder at install time.
The bundle carries the server's source and a lock file, nothing compiled, and needs no Python of its own: Claude Desktop runs it with uv, using a uv already on your PATH if there is one and otherwise the copy the app ships. On first launch uv uses a Python 3.10 or later already on the machine, downloading one only if there is none, and installs the locked libraries: roughly 40 MB, or 60 MB with an interpreter, which took 26 to 46 seconds on the author's connection; later launches take under a second. If the first launch is slow enough that Claude Desktop reports the server disconnected, restart the app: what uv already fetched is cached, and the second launch completes. Bundles before 1.2.0 vendored libraries compiled for CPython 3.12 only and failed on every other interpreter; see Troubleshooting.
From GitHub, pinned to a release
pip install "git+https://github.com/ckgerteis/ndl-mcp@v1.2.1"
# or, without an environment of your own:
uvx --from "git+https://github.com/ckgerteis/ndl-mcp@v1.2.1" ndl-mcpinstalls the ndl-mcp console script and ndl-mcp-ledger. The tag is the thing to cite; @main gets whatever is current. Then register it in Claude Desktop (below), or let install.py do that.
The whole family
pip install "git+https://github.com/ckgerteis/bibliograph-mcp@v1.0.3" && bibliograph installinstalls all six servers and registers them together — one receipts folder, credentials asked for once. See bibliograph-mcp. From a checkout of this repository, python install.py does the same for this server alone, python install.py --all for the six, on Windows, macOS and Linux; install.ps1 remains for Windows.
From source
python3 -m venv .venv
.venv/bin/pip install .
.venv/bin/python -c "import ndl_mcp; print(ndl_mcp.__version__)"That import fails loudly if the package or one of its vendored modules is
missing. Do not use ndl-mcp --help as the check: unknown arguments are
ignored, the server starts, reads end-of-input and exits 0, so it reports
success whatever the state of the code.
Installing more than this one
Six independent packages. None imports another, none depends on another, and
each installs and answers on its own — pip install . in this directory is a
complete install of this server and nothing else.
They do share three things: a response envelope, a query ledger, and — if you
run more than one — a receipts folder. install.ps1 is vendored byte-identical
into all six and handles that on Windows; install.py is its cross-platform port. Both install this server by default, because
cloning one repository is not a request for five more.
.\install.ps1 # this server
.\install.ps1 -All # all six
.\install.ps1 -Servers ndl,cinii # a chosen subsetNothing about where things go is decided for you. The script asks where to
install (the virtual environment Claude Desktop will be pointed at), which
folder receives the receipts, and which session slug to stamp on them,
offering a neutral suggestion for each that Enter accepts; run without a
terminal it does not guess, and stops unless --venv and --receipts-dir
(or --no-receipts; -VenvDir and -ReceiptsDir for install.ps1) say
so. Whatever subset you name is registered against one receipts folder, asked for
once. The script prefers a sibling checkout to the network, carries across
credentials already registered rather than asking again, leaves servers it was
not asked about alone, and stops rather than guessing where the servers already
registered disagree about the folder or the session slug. It also asserts that
ledger.py and mediation.py are byte-identical across everything it
installed, so two envelope versions cannot end up in one environment unnoticed.
Claude Desktop
install.ps1 writes this entry for you. By hand, add it to
%APPDATA%\Claude\claude_desktop_config.json under mcpServers, pointing at
the console script in the environment you installed into. On macOS or Linux use
the absolute path to .venv/bin/ndl-mcp. There is no credential to supply.
{
"mcpServers": {
"ndl": {
"command": "C:\\path\\to\\.venv\\Scripts\\ndl-mcp.exe",
"env": {
"MCP_RECEIPT_DIR": "C:\\path\\to\\receipts",
"MCP_RECEIPT_SESSION": "project-or-article-slug"
}
}
}
}Changed in 1.1.0. Earlier versions were registered by path —
"command": "…\\python.exe", "args": ["…\\server.py"]. That entry will not
start this version, because server.py is now a module inside a package rather
than a script beside its imports. Replace it with the console script above.
Restart Claude Desktop. The six tools should appear under "ndl" in the tool list.
Any other MCP client
Nothing here is specific to Claude. The server speaks the Model Context Protocol over stdio and nothing else: any client that can start a process and talk JSON-RPC to it (Claude Code, Cursor, VS Code and Continue, Zed, LibreChat, a script of your own using an MCP SDK) can use it. The Claude Desktop bundle and the installers are conveniences for one client; the server underneath is the same console script. Register it anywhere by giving the client the absolute path of the console script and, optionally, the environment:
{
"mcpServers": {
"ndl": {
"command": "/absolute/path/to/.venv/bin/ndl-mcp",
"env": {
"MCP_RECEIPT_DIR": "/absolute/path/to/receipts",
"MCP_RECEIPT_SESSION": "project-or-article-slug"
}
}
}
}Claude Code takes the same thing on the command line:
claude mcp add ndl -- /absolute/path/to/.venv/bin/ndl-mcpOn Windows the path ends in \.venv\Scripts\ndl-mcp.exe. MCP_RECEIPT_DIR and MCP_RECEIPT_SESSION
are optional; without them the server runs and every envelope says RECEIPT_NOT_DEPOSITED. The
stdio transport is the only one: there is no HTTP endpoint to expose, and nothing to host.
Troubleshooting
"Server disconnected" is all Claude Desktop says when the server process exited before or during the handshake, whatever the reason. The reason is in the log:
Windows:
%APPDATA%\Claude\logs\mcp-server-<name>.log(the extension's display name, or the key undermcpServers), withmcp.logbeside it for the app's side of the conversation.macOS:
~/Library/Logs/Claude/mcp-server-<name>.logandmcp.log.Linux:
~/.config/Claude/logs/.
Read the last launch from the bottom up. Three shapes account for nearly every report:
A Python traceback ending in
ImportErrororModuleNotFoundError(for exampleNo module named 'pydantic_core._pydantic_core'). The interpreter started, the code was found, and a compiled library did not match that interpreter. This is what every bundle before 1.2.0 did on any Python other than 3.12. Install the current bundle, or use the pip route, which resolves wheels for the interpreter you install into.'python' is not recognized,spawn python ENOENT, or a line from the Microsoft Store: no interpreter was found on the PATH Claude Desktop constructs. Nothing of this server ran. The current bundle does not launchpythonat all; for the pip route, register the console script by absolute path as shown above.A line from uv (
error: ..., or a download that never finished): the current bundle's runtime could not build its environment, usually because the first launch had no network or ran past Claude Desktop's sixty-second limit. Restart the app; uv keeps what it fetched. A uv older than 0.5 cannot read the lock file; upgrade it or remove it so the app uses its own.
The bundle's own entry point writes one line naming the interpreter, its path and the supported range before re-raising an import failure, so a log from 1.2.0 onwards says which of these it is.
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 |
|
Minimum one-second interval |
|
A cap on records per search; no bulk retrieval |
|
The harvesting interface is not used | OAI-PMH is not implemented |
Credit on every response |
|
Metadata displayed, not accumulated | no cache, no local store |
Change any of them and you change what this server declares about itself. Update this table, the module comment in src/ndl_mcp/server.py, and NDL-API-NOTIFICATION.txt in the same commit, so the description a reader checks stays true to what the code does.
Providers
Only the five sets declared in the notification of 19 August 2026 are reachable. All are NDL-created, all are marked ○ in both the 非営利 and 営利 columns of the provider list, and none requires a usage application. Their metadata is governed by 公共データ利用規約(第1.0版)(PDL1.0), which the NDL states to be compatible with CC BY 4.0 — PDL1.0 is the licence, CC BY 4.0 the compatibility claim:
dpid | 名称 |
| 国立国会図書館蔵書 |
| 国立国会図書館全国書誌情報 |
| 国立国会図書館雑誌記事索引 |
| 国立国会図書館雑誌記事索引オンライン資料編 |
| 国立国会図書館デジタルコレクション(オープンデータ) |
ndl-dl and ndl-dl-online — the wider Digital Collections — are marked ○ for 非営利 and △ only for 営利 on the provider list, so scholarly use needs no usage application. They are out of scope here because they sit outside the set this server declares, and because their metadata carries no open licence — displayable, not redistributable. Adding them is a documentation change in this repository, not an application to the library. A request naming them is refused in process, with a DPID_NOT_PERMITTED diagnostic, rather than sent.
Tools
Tool | Set searched |
| 蔵書 |
| 全国書誌情報 |
| 雑誌記事索引 (both sets) |
| デジタルコレクション(オープンデータ) |
| all five |
| one record by |
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
A bare and or or between words makes NDL reject the whole query, in any case. Not "returns nothing" — rejects. NOT is not reserved and is left alone.
This was measured against the live API on 27 August 2026, because the rule stated here until then was wrong in both directions. It claimed the check was case-sensitive and that War and Peace passes. It does not: anywhere="War and Peace" is refused where anywhere="War Peace" returns 5,025. What "passed" was the guard, not the library — and the query then came back as API_ERROR with a total of zero, which reads exactly like an absence. The same sentence also treated NOT as reserved, so the server declined in process a query NDL answers: anywhere="cats NOT dogs" returns 96 records.
Position matters, and the check follows what the API does rather than what would be tidy: anywhere="and Peace" is tolerated (14,375), anywhere="Peace and" is refused, anywhere="cats and dogs" is refused. So whitespace is required before the word, and whitespace or the end of the term after it. A word that merely contains the letters is untouched — Thailand, Andorra and notation all return records.
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. The remedy is usually to drop the conjunction: "Civil Information and Education Section" is refused, "Civil Information Education Section" returns 21,690.
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.
Response format
Every tool returns the response envelope built by mediation.py and defined in response-schema.json, schema version 2.3.0. The module and the schema are vendored byte-identically across cinii-mcp, jstage-mcp, korea-scholarship-mcp and this server, so an envelope from one can be read by a consumer written for another.
Search operations carry searched_for — the term actually sent, its detected script, and the matching mode — hoisted to the top of the envelope so a relaying client cannot drop it. ndl_get_record omits it: a fetch is handed an identifier and chooses no term.
Receipts
mediation.emit() writes each response envelope to an append-only, hash-chained ledger. Unset the receipt variables and nothing is written and nothing fails — which is exactly what happened here between 19 and 22 August 2026: the code called emit() at every exit while no variable was set in this server's environment, so three days of queries went unrecorded behind well-formed envelopes. Since schema 2.3.0 the envelope reports it: RECEIPT_NOT_DEPOSITED when nothing is configured, RECEIPT_WRITE_FAILED when it is and the write did not land.
MCP_RECEIPT_DIR names a folder, and this server writes ndl.jsonl inside it. One file per server, because appending is read-the-last-hash-then-write and the lock around it does not hold between processes: six servers pointed at one file will fork the chain when two answer at once. Measured — six processes, 150 lines, fourteen forks. MCP_RECEIPT_LOG still names a single file and is honoured when MCP_RECEIPT_DIR is unset.
install.ps1 holds no path of its own. It asks for the folder, offering whatever the already-registered servers use and otherwise %APPDATA%\Claude\mcp-receipts, and registers every server it installs against the same one. MCP_RECEIPT_SESSION — the project slug that groups a project's queries — is taken from the registered servers or asked for, never invented per server. Where the registered servers disagree about either, the install stops and asks rather than putting NDL in one of two records. (Earlier revisions of this README said the installer defaulted to %APPDATA%\Claude\mcp-receipts.jsonl. It did not; the statement described an installer that no longer existed. What it did default to, until 1.1.0, was a path inside the author's own Dropbox folder, written into a public repository.)
Verify with ndl-mcp-ledger verify-dir <folder>, or write the citable manifest with ndl-mcp-ledger manifest <folder>. A failure is typed: a fork means concurrent writers and every line is still present; tamper means a line no longer hashes to its own content. The two are not the same finding and are no longer reported as though they were.
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, for the server code. Metadata retrieved through this server is governed by 公共データ利用規約(第1.0版)(PDL1.0), read with 「国以外の者」 as 「国立国会図書館以外の者」; the NDL states that condition to be compatible with CC BY 4.0, which is a compatibility claim rather than a grant of CC BY 4.0 itself. The credit line the server emits is the attribution PDL1.0 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, as it then stood:War AND Peacecaught,War and Peacepassed the guard. What the library did with it afterwards was not checked, and the entry should not have been written as though it had been — see 27 August below.The rate limiter, involuntarily — see HTTP 429 above.
Verified against the live API on 23 August 2026, closing two rows that had been read rather than run:
The "Record does not exist" passthrough. That string is not a fault. It is how NDL answers a search that matched nothing, and it answers that way for every provider —
zassaku,zassaku-online,iss-ndl-opacandndl-dl-openall return it for a term with no hits. The server maps it tototal: 0with aZERO_CONJUNCTIONdiagnostic rather than toAPI_ERROR, which is the distinction the whole envelope exists to preserve: a search that found nothing is not a search that failed.ndl_get_record.jpno=71009951, taken from a national-bibliography result, resolves to one record with anOKdiagnostic.The reserved-word rule, corrected.
andandorare refused by NDL in any case;NOTis not reserved at all. Measured across seventeen cases:cats and dogs,cats AND dogs,cats And dogs,cats or dogsandcats OR dogsall refused;cats not dogs,cats NOT dogs,war not peaceandtitle="not for sale"all answered;Thailand,Andorraandnotationunaffected. The guard now matches that behaviour exactly, having previously both missed every lowercase conjunction and refused a word the library accepts.Multi-provider search, after the CQL correction —
ndl_search_articlesreturns 23,766 fortitle="労働運動", matchingdpid="zassaku"alone, becausezassaku-onlineholds nothing under that title. The union total is a count, not a floor.
Still not verified, and read rather than run: 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. It will be exercised in ordinary use, a query at a time.
Verified on 4 September 2026 with tests/smoke_stdio.py, which starts the installed console script over stdio, performs the MCP handshake, checks tools/list against the tool table above, and with RUN_LIVE=1 … <tool> '<json params>' makes one live call: ndl_search_books for 軍艦島 answered 524 records with an OK diagnostic.
Available Tools
6 toolsndl_get_recordARead-onlyIdempotent
Retrieve a single record by NDL bibliographic ID or 全国書誌番号 (JP number).
A fetch, not a search: the envelope omits searched_for because no term was
chosen. Exactly one identifier is required.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 detail beyond annotations by explaining that the envelope omits 'searched_for' because no search term is chosen, which gives the agent insight into the response format.
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 convey the purpose and the key operational distinction. The description is front-loaded with the primary action, and every sentence adds relevant information with 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-record fetch tool, the description is complete: it covers the identifier requirement, the fetch-vs-search distinction, and a response envelope nuance. The output schema and annotations handle return format and safety, so nothing essential is missing for the agent to invoke this 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?
With schema description coverage reported at 0%, the description partially compensates by naming both accepted identifier types: NDL bibliographic ID and 全国書誌番号. It also adds the critical constraint that exactly one identifier is required, which is not enforced by the schema (both params are individually optional). However, it does not elaborate on identifier format or which identifier should be preferred when both are known.
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: 'Retrieve a single record by NDL bibliographic ID or 全国書誌番号 (JP number).' It further distinguishes itself from the search sibling tools by explicitly stating 'A fetch, not a search,' so an agent can clearly tell it apart.
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 context: this tool is for fetching by a known identifier, not for searching. It also provides a key usage requirement, 'Exactly one identifier is required,' which helps the agent avoid invalid calls. It does not explicitly name alternative tools, but since all siblings are search tools, the contrast is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ndl_search_allARead-onlyIdempotent
Search all five declared provider sets at once.
Use when the material type is unknown. For a bibliographic check, the narrower tools return a cleaner set.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, idempotent, and non-destructive behavior, so the description doesn't need to restate safety. It adds the useful behavioral context that one call hits all five provider sets at once. It doesn't disclose behaviors like result merging, duplication, or pagination, but with strong annotations and an output schema this is acceptable.
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 core action is front-loaded, and the usage guidance follows immediately. Every sentence carries 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 an aggregate search tool with read-only annotations, rich nested parameter descriptions, and an output schema, the description covers the key decision (when to use all vs. narrower). It would be slightly stronger if it named the five provider sets or the narrower sibling tool names, but the sibling list and schema supply that context.
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 description says nothing about parameters. Reported schema description coverage is 0% at the top level, and the description does not compensate by explaining search fields or constraints. The nested schema does contain useful per-field descriptions (ndc, isbn, title, year, etc.), which prevents this from being a 1.
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 specific verb and resource: 'Search all five declared provider sets at once.' This distinguishes it from the narrower sibling search tools by scope (all sets vs. one set), so an agent can tell it apart from ndl_search_books, ndl_search_articles, etc. without opening the schema.
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 gives an explicit use condition — 'Use when the material type is unknown' — and an explicit alternative condition: 'For a bibliographic check, the narrower tools return a cleaner set.' The alternative names aren't listed verbatim, but the sibling list makes them identifiable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ndl_search_articlesARead-onlyIdempotent
Search 国立国会図書館雑誌記事索引, including the online-materials set.
The index covers Japanese periodical articles, including many not in CiNii or J-STAGE. It indexes articles, not their full text.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as readOnly, idempotent, and non-destructive. The description adds useful behavioral context: it includes the online-materials set, covers articles often missing from CiNii/J-STAGE, and explicitly does not provide full text. 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 short, purposeful sentences with no filler. The action and resource are front-loaded, followed by scope and a clear limitation. Every sentence 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 search tool with a rich schema and an output schema, the description adequately explains what is searched, the coverage scope, and the key limitation (no full text). It could be more explicit about sibling routing, but overall it is complete enough 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?
The tool description itself does not describe any parameters, but the nested SearchInput schema gives detailed descriptions for each field (e.g., partial match, date formats, bounds). The description adds no extra parameter meaning, and the structured schema already carries the burden.
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 specific verb and resource: 'Search 国立国会図書館雑誌記事索引', then clarifies that it covers Japanese periodical articles and indexes articles, not full text. This makes it easy to distinguish from sibling tools like ndl_search_books or ndl_search_national_bibliography.
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 gives clear context on when this tool is relevant: for Japanese periodical article records, including coverage beyond CiNii and J-STAGE. It does not explicitly name sibling tools or state when not to use them, but the scope is clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ndl_search_booksARead-onlyIdempotent
Search 国立国会図書館蔵書 for books and monographs.
Fields are combined with AND; title, creator, publisher and subject match partially. Returns the unified response envelope. Records are displayed, not stored.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only and idempotent, and the description adds meaningful behavioral detail: fields are combined with AND, title/creator/publisher/subject match partially, it returns the unified response envelope, and records are displayed but not stored. This clearly communicates side effects and result shaping, and it does not contradict any annotation.
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 terse sentences: the first states purpose, the second states matching behavior, the third states output and side-effect semantics. No filler words, no repetition of schema details, and the most important information is front-loaded.
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, together with a rich input schema and an output schema, gives an agent enough to invoke the tool correctly: scope, query combination semantics, return envelope, and non-storage behavior. It falls short only in not explicitly routing the agent away from sibling search tools or mentioning pagination parameters, though those are documented in the schema.
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 description names a few parameters (title, creator, publisher, subject) and notes they match partially, but the input schema already documents each field with equivalent or richer descriptions. The main addition beyond the schema is 'fields are combined with AND', which is useful but modest. Given the schema descriptions are strong, baseline 3 is appropriate.
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 action ('Search'), a concrete resource ('国立国会図書館蔵書'), and a clear scope ('books and monographs'). This distinguishes it from sibling tools like ndl_search_articles or ndl_search_digital_open without needing to inspect their 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?
The description implies this tool is for searching books and monographs rather than articles or digital collections, but it never explicitly names alternatives or says when to prefer this tool over sibling searches. It does provide practical query semantics (AND combination, partial matching), but not exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ndl_search_digital_openBRead-onlyIdempotent
Search 国立国会図書館デジタルコレクション(オープンデータ).
The open-data set only. The wider Digital Collections (ndl-dl, ndl-dl-online) are marked ○ for 非営利 use and so need no usage application, but they were outside the set this server declares and their metadata carries no open licence — displayable, not redistributable. Adding them is a documentation change here, not an application to the library.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and destructiveHintfalse, so the safety profile is covered. The description adds value by clarifying the data set scope and licensing: only open-data records are included, and the wider collections are 'displayable, not redistributable'. This is useful behavioral context about what the tool can return, though it does not describe response format or limits.
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 compact and well-structured: a one-line purpose statement in Japanese, then a concise English explanation of the key scope constraint and licensing nuance. It front-loads the main action and does not waste words, though the language mix is slightly awkward for an English-first agent.
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 tool has an output schema and annotations cover read-only/idempotent behavior, the description’s main job is scoping and usage guidance. It handles scoping well and adds useful licence context, but it leaves out any explicit guidance on when to choose this over siblings like ndl_search_books or ndl_search_all, and it does not mention pagination or result count controls (though those are in the schema). Overall it is adequate but not thorough.
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 description contains no parameter information. Context signals report 0% schema description coverage, so the description must compensate but does not. The nested schema fields have some descriptions, but the top-level 'params' parameter is undocumented in the description, leaving an agent to delve into the $ref to construct a query. The description's licence discussion gives no help with the many search fields.
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 clear verb and resource: 'Search 国立国会図書館デジタルコレクション(オープンデータ)', reinforced by the annotation title 'Search NDL Digital Collections (Open Data)'. It distinguishes from the wider Digital Collections by explicitly saying 'The open-data set only', so an agent can tell this tool is scoped to the open subset. It does not name sibling search tools, but the scoping qualifier differentiates 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 description gives context about when to use this tool: it searches only the open-data set, and the wider collections are explicitly excluded. It does not name alternative tools or say 'use X for the wider collections', but the scope limitation clearly implies this tool is for open data. The licence discussion adds context about the data set, but no explicit when-not-to-use or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ndl_search_national_bibliographyARead-onlyIdempotent
Search 国立国会図書館全国書誌情報.
The national bibliography is the authority for Japanese imprint data — use it when a publication date, publisher or edition statement has to be right rather than merely plausible.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempoentHint=true, openWorldHint=true, and destructiveHint=false, covering safety and side-effect profile. The description adds only the data-quality trait (authority of imprint data), which is contextual but not a behavioral disclosure such as result ordering, matching semantics, or limits. It adds some value beyond annotations but does not carry new behavioral information.
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, zero redundancy. The resource and action are front-loaded, and the second sentence earns its place by explaining why this tool exists and when it matters.
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, every parameter is documented in the schema, and annotations cover the operational profile, so the description need not explain return values or side effects. What it adds — the authority positioning and the when-to-use rule — completes the picture for correct selection. A brief note distinguishing it from ndl_search_books or ndl_search_all would make it complete, hence not a 5.
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% — the tool description contributes nothing about the 12 parameters, though the schema itself documents each property well. The phrase "publication date, publisher or edition statement" faintly hints at which search fields matter, but that is indirect and does not compensate for the coverage 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 verb and resource — "Search 国立国会図書館全国書誌情報" — and then sharpens the scope by positioning this as the authoritative source for Japanese imprint data. The "authority" framing distinguishes it from sibling search tools without ambiguity: this is the tool to trust for dates, publishers, and edition statements.
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 when-to-use guidance: choose this tool when a publication date, publisher, or edition statement must be authoritative rather than merely plausible. It stops short of naming alternative siblings or stating when NOT to use it, so a score of 5 would overstate its completeness.
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.
6 tool updates
v1.1.0- First observed
ndl_get_record - First observed
ndl_search_all - First observed
ndl_search_articles - First observed
ndl_search_books - First observed
ndl_search_digital_open - First observed
ndl_search_national_bibliography
TDQS
Scored across 6 tools
Each search tool targets a distinct NDL dataset or scope, and get_record is clearly separate as an ID-based fetch. The main ambiguity is between ndl_search_books and ndl_search_national_bibliography, since both can return book-like records, though their descriptions clarify holdings vs. authority data.
All tool names follow a predictable ndl_<action>_<scope> pattern: get_record and search_* for the rest. This makes the set easy to navigate and avoids stylistic mixing.
Six tools is well-scoped for the server's purpose: one record retrieval tool and five search tools covering separate NDL data sources plus a combined search. No tool feels redundant or out of place.
The set covers the main NDL search surfaces and record retrieval by ID, which supports core bibliographic workflows. The main minor gap is that only the open Digital Collections subset is exposed, while wider digital collection content is not covered by a dedicated tool.
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
MCP server for searching Airweave collections with natural language queries.
Read-only MCP server for searching Japan government procurement bid information from the KKJ portal.
Hosted MCP server for finding authoritative primary data sources and official portals.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for searching Japanese Diet bills and committee Q\&A records via the NDL Kokkai API.4131MIT
- AlicenseAqualityAmaintenanceAn MCP server for Japanese literature research that provides unified search across NDL, CiNii, J-STAGE, and other Japanese academic databases, with Skills to assist in search planning and result evaluation.302066MIT
- AlicenseBqualityFmaintenanceMCP server for accessing Japanese government statistics portal 'e-Stat' API, enabling language models to search and retrieve statistical data.520MIT
- FlicenseBqualityDmaintenanceMCP server for searching Japanese government procurement notices via the Kanpou API. Enables LLMs to search by date, keyword, or detailed criteria.31-