nara-catalog-mcp
Click on "Deploy 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., "@nara-catalog-mcpfind Civil War pension records for John Murphy and show transcriptions"
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.
nara-catalog-mcp
An MCP server for genealogical research in the US National Archives Catalog. Find an ancestor's pension file, service record or census page, read what machines and volunteers have transcribed from it, and fetch the page images you will cite. It also searches NARA's Access to Archival Databases (AAD), which the Catalog cannot reach: the NUMIDENT's Social Security applications and deaths, the WWII Army enlistment cards, and the 1820–1912 ship passenger lists among them.
It works the way a careful genealogist does. A catalogue description is a finding aid, and OCR text, transcriptions and tags are somebody else's reading of the page: all of them are leads. The page image is the source. The tools say which is which, and the server tells the model to read the image before citing it.
Nothing here writes to the Catalog, and nothing here keeps a family tree. The server finds and reads records; what you conclude from them belongs in your genealogy software, or in a family-tree MCP server running alongside this one.
The tools work on any record the Catalog describes, so a historian or a journalist can use them too. The examples throughout are about tracing people.
This is an independent project. It is not affiliated with, endorsed by, or supported by the National Archives and Records Administration.
Tools
The server publishes 21 tools. Twenty only read, and are annotated
read-only for the client. One, download_page_image, writes a new file to
local disk; it never overwrites one.
Finding a record
Tool | Purpose |
| Search by title or full text. Returns totals plus compact summaries: NAID, hierarchy, holding unit, date coverage, image count. Each series names its creator, the office that made it, which tells apart the many series sharing a title. |
| The same search with the filters that narrow a common name: date range, record group, collection, ancestor NAID, level of description, microfilm publication number, local identifier, any control number, Congress number, reference unit, creator, person or organisation, place, type of materials, recurring date, digitised-only, "has transcriptions/tags/comments", exact matching of identifiers, |
| The immediate children of a node: record group to series to file unit to item. Walk down from a series you trust. |
Reading a record
Tool | Purpose |
| Read one record in full by NAID: scope and content note, hierarchy, reference units, every page image with its object id. |
| Page images in page order, each with its object id and URL — the evidence to read before citing. |
| Save one page to a new local file, by page number or by the object id an OCR or transcription entry names. The media host is open, so this spends no API quota. |
| Where else the record is published online, including by commercial partners. |
| Digital object ids a commercial partner (Ancestry among them) has matched to this NAID. An empty list is the common answer. |
What machines and other people read in it
Everything in this group is somebody else's reading of the document. It tells you which page to open. It does not tell you what the page says.
Tool | Purpose |
| OCR text extracted from the page images, per digital object, with who produced it, and the object total and next results page when a file runs longer than one call. |
| Citizen transcriptions — how you get into a handwritten pension file that OCR cannot touch. |
| Citizen tags, which on genealogical records are usually the names of the people inside the file. |
| Other researchers' notes on the record. |
Searching the documents rather than the catalogue
Tool | Purpose |
| Search transcriptions, tags, comments and OCR text — and get full record summaries back. |
| Find records whose transcribed text mentions a name or phrase. |
| Find records carrying a tag, exactly or by word. |
| Find records whose partner-contributed extracted text matches. |
| Find records other researchers have commented on. |
NARA's Access to Archival Databases (AAD)
AAD serves a selection of NARA's electronic records as searchable tables. Each row is a database entry an agency clerk typed from a record: a transcription or index entry, not the record, and cited as an electronic record. These tools need no key and spend none of the Catalog allowance.
Tool | Purpose |
| The series in an AAD category (genealogy by default), each with its files and their ids. A search runs on one file. |
| Search one file by free text over the whole row and by named fields; 50 rows a page, each with its record id. |
| One row in full, every coded value with its meaning, and a citation in NARA's recommended form with the date retrieved. |
Housekeeping
Tool | Purpose |
| Live calls and cache hits this session, the month's live calls from a ledger beside the cache, and what remains of the key's monthly allowance. |
Related MCP server: nara-mcp-server
Setup
You need Python 3.11 or later, uv, and a Catalog API key. Request a key from the Catalog API team via the API documentation; the default allowance is 10,000 calls per month.
There are two ways to run the server.
Without cloning. uvx fetches it from PyPI and runs it in one step, and
caches the result:
NARA_API_KEY=your-key uvx nara-catalog-mcpFrom a clone, which is what you want if you will change it:
git clone https://github.com/ianderso/nara-catalog-mcp
cd nara-catalog-mcp
uv sync
cp .env.example .env # then put your key in it
uv run nara-catalog-mcp # stdio server, usually launched by the clientEither way the server speaks MCP over stdio, so you will normally let an MCP client start it rather than run it by hand.
Claude Desktop
Without cloning:
{
"mcpServers": {
"nara": {
"command": "uvx",
"args": ["nara-catalog-mcp"],
"env": { "NARA_API_KEY": "your-key" }
}
}
}From a clone (the env block can be dropped if the key is in the clone's
.env):
{
"mcpServers": {
"nara": {
"command": "uv",
"args": ["--directory", "/path/to/nara-catalog-mcp", "run", "nara-catalog-mcp"],
"env": { "NARA_API_KEY": "your-key" }
}
}
}A desktop app does not always inherit your shell's PATH. If the server fails
to start because uv or uvx cannot be found, give the full path that
which uvx prints as the command.
Claude Code
claude mcp add nara --env NARA_API_KEY=your-key -- uvx nara-catalog-mcpor, from a clone whose .env holds the key:
claude mcp add nara -- uv --directory /path/to/nara-catalog-mcp run nara-catalog-mcpConfiguration
All settings come from the environment. A .env file in the directory the
server starts in supplies any that the environment does not; with
uv --directory that is the clone. Only that directory is read — not its
parents, and not the directory the package is installed in.
Variable | Meaning |
| Your Catalog API key. Required by the Catalog tools; the AAD tools need none. |
| Response cache directory. Default |
| HTTP timeout in seconds. Default 60. |
| Calls per month the key allows, reported by |
A missing key, or an unusable value, is reported on the first tool call as a
not_configured result naming the variable.
The call budget
A Catalog key is capped per month, and a sweep across many names will exhaust
it faster than expected. Every successful response is cached on disk, keyed by
endpoint and query, so repeating a call costs nothing. Live calls are also
written to a ledger, budget.json beside the cache, so api_budget reports
the month's spend across sessions as well as this session's live calls and
cache hits. A rejected call counts as live, since it reached the API. The
ledger sees one machine and one cache directory; the Catalog's own count is
the authority.
The cache never expires. Pass refresh=true to get_record,
get_record_images, get_extracted_text, get_transcriptions, get_tags
or get_comments to re-read one answer from the Catalog: that spends one
call and replaces the cached copy. New transcriptions and tags arrive over
time, and a file that was paper-only can be digitised, so a cached "nothing
here" is the answer most worth refreshing. Deleting NARA_CACHE_DIR still
works, and also resets the month's ledger.
Searching past the first 10,000 hits
page stops working beyond 10,000 results, which a common surname passes.
search_records_advanced reports a paging_note when you hit that boundary;
either narrow the search or re-run it with search_after="*" and follow the
next_search_after value from each response.
How a search behaves
title matches words in the record title and is the precise option — case
files are usually titled with the person's name. query searches the full
description: broader, noisier, and worth reaching for only when a title search
finds nothing.
Results come back as summaries rather than whole records. A raw Catalog record is large and mostly irrelevant to the decision you are making, which is whether this record is worth opening.
Searching AAD
AAD has no API, so aad_* read its web pages the way a browser does, and
parse them. That shapes how they behave:
One file at a time. A big series is split into files, and a search runs on one. The NUMIDENT is split by entry type (application, claim, death) and by surname range, so
aad_list_seriescomes first.Fields by name.
fields={"LAST NAME": "PRESLEY", "DATE OF BIRTH (YEAR)": "1930-1935"}. A field AAD stores as a code, such as a state or a country, cannot be searched by name: put its meaning inquery, which matches the whole row, code meanings included.Slow on purpose. One request at a time, at least two seconds apart, and a search usually takes two requests because AAD answers first with a "Please Wait" page. Answers are cached for seven days, under
NARA_CACHE_DIR/aad;refresh=trueonaad_get_recordfetches a row again.Record ids are not stable. NARA reloads files, and a reload can renumber the rows. Search again rather than reuse an old id, and cite a row by its fields, its file and its series.
A row is not the record. It was keyed from an SS-5, a punch card or a manifest, with the keying errors that brings, and no file holds everyone. The NUMIDENT has entries only for people with a verified death or born before 1908, and its death file omits state-reported deaths. Each answer carries AAD's own notice for the file, and a NUMIDENT answer says what that file leaves out.
Notes
A description is not evidence. It summarises a file; it says nothing about what any individual page contains. Read the images before citing.
Neither is OCR, and neither is a transcription.
get_extracted_textis a machine reading a scan of handwriting;get_transcriptionsis one volunteer's typing, unreviewed. Both are the fastest way to find the page that matters, and neither is a source. Open the image and cite that.Record the NAID. It is the stable identifier that makes a citation refindable.
Not every record is digitised.
image_count: 0means the description exists but the pages are not online — thereference_unitsfield tells you which archive holds the paper.Open is not unrestricted. The media host needs no key, and most of NARA's holdings are in the public domain, but not all: some descriptions record use restrictions. Check before republishing an image.
Deliberately not here
The Catalog API can post tags and comments and put transcriptions. This server does not, and will not by default: a contribution publishes under whoever's key is configured, and nothing here can take it back.
Security
The key is read from the environment, sent only to
catalog.archives.govas thex-api-keyheader, and never sent to the media host or to AAD. It is not written to the response cache.The AAD client reads one host. A request hook refuses any host but
aad.archives.gov, so nothing a model passes in can make it fetch another site. It identifies itself asMozilla/5.0 (compatible; nara-catalog-mcp/<version>; +<this repository>), the form crawlers such as Googlebot use. AAD's load balancer answered 403 to the plainnara-catalog-mcp/<version>form when it was tried; see docs/API-NOTES.md.Contributions are untrusted text. Tags, comments and transcriptions are written by members of the public and reach the model verbatim, so one could contain instructions aimed at it. The server's instructions tell the model to treat that text as material to weigh, never as instructions; the model is still the one deciding, so review what it proposes to do.
download_page_imagewrites files. It creates a new file wherever the server's user can write, and refuses to overwrite an existing one — so a mistaken or injected path cannot destroy anything. It is annotated as not read-only, so a client can ask before each call.
To report a vulnerability, see SECURITY.md.
Development
uv sync --extra dev
uv run pytest # mocked with respx; no API key needed
uv run ruff check .
uv run ruff format --check .
uv run python -m tests.live_check # needs a key: asks the Catalog what the mocks cannotThe live check asks the Catalog what the mocks cannot: where the two text flags put their text, which search parameters the server does not send, and whether search summaries still name each series' creator. It also asks AAD whether it still admits the client and whether the parsers still read its pages. Run it after a change on either side; a difference shows up in its output.
See CONTRIBUTING.md for how the suite is organised and what a change is expected to carry.
API notes
The published OpenAPI spec is unreliable in specific, repeatable ways — wrong
required flags, maximum used where maxLength is meant, and two
conflicting definitions of the pagination cursor. Corrections verified against
the live Catalog are in docs/API-NOTES.md. Why the server
is shaped the way it is, what is out of scope by decision, and how the test
suite is built are in docs/DESIGN.md.
License
MIT.
Available Tools
18 toolsapi_budgetARead-only
Report the key's Catalog API spend, this session and this month.
A key is capped per month and a long sweep can exhaust it. Live calls are kept in a ledger beside the cache, so the month's figure survives restarts. Cached repeats cost nothing and are not counted.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations by disclosing accounting semantics that directly affect how the returned numbers must be read: per-month key caps, ledger persistence across restarts, and the rule that cached repeats cost nothing and are not counted. These are exactly the behaviors an agent needs to interpret spend correctly.
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 spend figure is front-loaded in the first sentence and the following sentences each carry useful accounting context. 'Beside the cache' is minor implementation detail, but nothing is padded or redundant.
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 reporting tool with no output schema, the description covers what is measured and the counting rules. It stops short of naming the return shape or units/currency, which would fully close the loop, but the essentials are present.
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 takes zero parameters, so the schema baseline of 4 applies. The description adds nothing parameter-related because there is nothing to add.
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?
States a specific verb and resource with scope: 'Report the key's Catalog API spend, this session and this month.' This is unmistakably distinct from the eighteen sibling search/get tools, which all retrieve records rather than account-level usage.
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?
Usage is implied rather than stated: the note about the monthly cap and long sweeps hint at when an agent should care, but there is no explicit 'call this before/after X' instruction. No alternatives are named, though none exist among siblings, so the guidance gap is mild.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_childrenARead-only
List a record's immediate children, one level down the hierarchy.
The Catalog nests record group, then series, then file unit, then item.
Searching finds a node; this walks down from it, which is how you get from
a series you trust to the file unit for one person, and how you find out
what else sits alongside a file you already have. A record's own ancestors
come back from get_record.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page of results, 1-based. | |
| limit | No | Maximum children to return (1-100). | |
| parent_naid | Yes | NAID of the parent: a record group, collection, series or file unit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered externally. The description adds genuinely useful behavioral context: the traversal is strictly one level down and the hierarchy ordering. It stops short of describing pagination or return shape, but the added structural domain knowledge is substantive.
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?
Front-loaded with the core action, then layered with hierarchy context and use cases. Every sentence contributes routing or domain value, though the example clauses in the third sentence run slightly long for a three-parameter read tool.
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 paginated read tool with no output schema, the description conveys what is returned (immediate children) and the traversal model. Pagination behavior lives in the schema, so its absence in prose is acceptable; the definition 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?
Schema description coverage is 100% (page, limit, and parent_naid are all documented), so the schema already carries parameter meaning. The description reinforces parent_naid implicitly via 'a record's immediate children' but adds no syntax or format details beyond the schema. 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?
States a specific verb and resource ('List a record's immediate children, one level down the hierarchy') and immediately situates it within the Catalog's record group/series/file unit/item nesting. It explicitly distinguishes itself from search-based siblings by noting 'searching finds a node; this walks down from it.'
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?
Gives concrete when-to-use scenarios ('get from a series you trust to the file unit for one person', 'find out what else sits alongside a file you already have') and names the alternative for the inverse operation, noting ancestors 'come back from get_record.' Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_page_imageAIdempotent
Download one page of a record so it can actually be read.
This is the step that turns a catalogue hit into evidence. The image is written to disk rather than returned inline — a page scan runs to several megabytes.
NARA's media URLs are open and need no key, so this costs nothing against your API allowance. One catalogue call resolves the page list; the download itself is not an API call.
A pension file can run to sixty pages and the page you need is rarely the first. Use get_extracted_text or get_transcriptions to find which page carries the fact, then fetch it by the object_id they name.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID, e.g. '54765873'. | |
| page | No | Which page to download, 1-based, in the order get_record_images lists them. Defaults to 1 when object_id is not given. | |
| object_id | No | The digital object to download, as get_extracted_text, get_transcriptions and get_record_images name it. An alternative to page: pass one or the other. | |
| destination | Yes | Absolute path of a new file to write, e.g. '/tmp/hall-w17050-p51.jpg'. The directory must already exist, and the file must not: nothing is ever overwritten. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations correctly indicate a non-read-only, open-world, idempotent, and non-destructive operation. The description adds significant value beyond this by explaining that the output is written to disk (not returned inline), that it doesn't count against API limits, and that it requires an existing directory and a new file path. This is rich behavioral context that an agent needs.
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 concise and front-loaded, with the core action stated in the first sentence. However, the final paragraph about typical file sizes and the need to find the right page could be considered slightly extraneous, though it's useful context. Overall, it's well-structured.
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's complexity (file download) and the lack of an output schema, the description covers all necessary aspects: where the file is written, prerequisites (directory existence, no overwriting), cost, and how to obtain the necessary identifiers. It is complete for an agent to use 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?
With 100% schema description coverage, the schema already defines each parameter. The description adds usage context by implying that 'page' and 'object_id' are alternatives and that 'page' is 1-based (matching the schema). It doesn't add new syntax details, but it reinforces how to obtain the 'object_id' from other tools, which is valuable.
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?
States a specific verb (download), resource (one page of a record), and outcome (written to disk, not returned inline). It clearly distinguishes itself from sibling read tools like get_extracted_text or get_transcriptions by describing the physical file download.
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?
Provides explicit guidance on when to use this tool: it explains that you should first use get_extracted_text or get_transcriptions to identify the correct page, and then use this tool to fetch it. It also notes that the page needed is rarely the first in a large file, which provides useful context for usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_commentsARead-only
Read other researchers' comments on a record.
Comments often say what a file actually contains, where a related file sits, or that the description is wrong. None of it is verified by NARA: it is correspondence between researchers, useful for finding the next record and never a source in itself.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID. | |
| refresh | No | True re-reads from the Catalog instead of the cache, spending one call and replacing the cached copy. The cache never expires on its own, so use this when the answer may have changed since you last asked. | |
| max_chars | No | Characters of each comment to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful behavioral context beyond that: the comments are unverified by NARA and are researcher correspondence, so the agent knows to treat the output as low-authority and non-citable.
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?
Purpose is front-loaded in the first sentence, and the following lines add trust/quality context rather than padding. Slightly longer than needed, but every sentence carries a distinct caution about the data's reliability.
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 read-only, single-record tool with no output schema and full annotation coverage, the description supplies the one thing the structured fields cannot: the epistemic status of the returned comments. Nothing an agent needs to invoke it 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 coverage is 100% and the schema already documents all three parameters richly, including the refresh/cache semantics. The description adds nothing about naid, refresh, or max_chars, so the baseline 3 applies.
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?
States a specific verb and resource with scope: 'Read other researchers' comments on a record.' This is enough to separate it from the sibling search_comments by virtue of the single-record scope, though the contrast is left implicit rather than named.
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 the value of the content ('useful for finding the next record and never a source in itself'), which is implied usage guidance, but it never states when to call this tool versus search_comments or get_record, nor any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_extracted_textARead-only
Read the OCR text NARA machine-extracted from a record's page images.
This is a lead, not evidence. OCR was run over scans of handwriting,
carbon copies and microfilm: it drops handwritten pages entirely, and it
turns one surname into another silently. Use it to find which page matters,
then open that page image with get_record_images and cite what you saw
there -- never cite the OCR text itself.
Returns one entry per digital object, in page order, with the text
truncated to max_chars.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID. | |
| page | No | Page of results, 1-based. | |
| limit | No | Maximum digital objects to return (1-100). | |
| refresh | No | True re-reads from the Catalog instead of the cache, spending one call and replacing the cached copy. The cache never expires on its own, so use this when the answer may have changed since you last asked. | |
| max_chars | No | Characters of text to return per page. 0 returns all of it, which for a long file unit is tens of thousands. | |
| object_id | No | Limit to one digital object (one scanned page). Omit it to get the text of every page of the record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover read-only/open-world safety, but the description goes well beyond: it warns OCR 'drops handwritten pages entirely' and 'turns one surname into another silently,' plus defines the return shape (one entry per page, page order, truncated to max_chars). That is exactly the reliability context an agent needs and cannot get from structured fields.
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?
Front-loads the essential action, then the caveat, then the recommended workflow, then the return format. Every sentence carries distinct information; the structure maps cleanly to how an agent consumes it.
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?
With no output schema, the description compensates by describing the return format (one entry per page, ordering, truncation). Combined with the OCR reliability caveats and the recommended get_record_images follow-up, an agent has everything needed to call and use 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?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful framing by tying the output to 'one entry per digital object' and text 'truncated to `max_chars`,' reinforcing the object_id/max_chars semantics. It does not, however, add syntax or defaults beyond the schema.
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?
States a specific verb and resource ('Read the OCR text NARA machine-extracted from a record's page images') and its scope ('one entry per digital object, in page order'). The qualifier 'machine-extracted' implicitly distinguishes it from the human-transcription sibling get_transcriptions, so an agent can route correctly without reading 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?
Explicitly frames usage: 'Use it to find which page matters, then open that page image with get_record_images and cite what you saw there -- never cite the OCR text itself.' This names the alternative tool, the follow-up step, and an explicit prohibition, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_online_availabilityARead-only
List where else this record is available online.
NARA records what has been digitised and published elsewhere, including by commercial partners. Use it to resolve a hint from a subscription site back to the archival original: the NAID and the reference unit are what make a citation refindable, and a partner's index entry is not a substitute for the page.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and openWorldHint=true, so safety and external-data scope are covered. The description adds a useful nuance — that a partner index entry is not a substitute for the page — but says nothing about result volume, pagination, or latency for a tool whose results come from external partners.
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 core action is front-loaded in the first sentence, with supporting rationale after it. The later sentences lean editorial ('a partner's index entry is not a substitute for the page'), which adds tone more than operational information, but the overall length remains reasonable.
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?
No output schema exists, but the description conveys what is returned (a list of online availability, including commercial partners) and why it matters. For a single-parameter read with annotations covering safety, this is largely complete; only return-shape details (e.g., whether partner names/URLs are included) are left implicit.
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 100% and there is a single naid parameter, so the schema already carries the load and baseline 3 applies. The description reinforces why the NAID matters for citation refindability, which is helpful context but not new syntactic or format detail.
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?
States a specific verb and resource — listing where else this record is available online — and clarifies that NARA records digitised/published locations. It is clear on its own, but it never explicitly distinguishes itself from the sibling get_partner_digital_objects, which occupies similar conceptual territory.
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?
Provides a concrete usage scenario: resolving a hint from a subscription site back to the archival original. That is a clear 'when to use' trigger. It does not name an alternative tool or state when not to use it, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_partner_digital_objectsARead-only
List digital object ids a partner has matched to this record.
NARA indexes metadata supplied by commercial partners — Ancestry among them — against its own records. A hit tells you the partner holds imagery for this NAID, which is worth knowing when NARA's own pages are not online.
An empty list is the common answer and is not an error. It means no partner metadata has been matched, not that no partner holds the record.
The ids are pointers into the partner's index, not a citation. Cite the archival record by NAID and reference unit.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID, e.g. '54765873'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely useful behavior the annotations cannot convey: an empty list is the common answer and not an error, and the returned ids are index pointers rather than citations for the archival record.
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?
Front-loaded with the core action in the first sentence, followed by three short paragraphs that each add a distinct point (mechanism, empty-list semantics, citation guidance). No filler, though the citation guidance is marginally tangential to invocation.
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?
With no output schema, the description compensates fully: it characterizes the return value (a list of partner index ids), states that empty is the expected default, and warns against treating the ids as citations. An agent has everything needed to call this and interpret the result.
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 coverage is 100% and the naid parameter is documented with an example ('54765873'), so the structured field carries the load. The description only implies that 'this record' is identified by NAID and adds no format, validation, or lookup semantics beyond the schema — the baseline of 3 for high-coverage schemas applies.
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 first sentence gives a precise verb and resource: list digital object ids that a partner has matched to a record, scoped by NAID. The follow-up paragraph explains the mechanism (NARA index vs. commercial partner metadata), which functionally separates it from siblings such as get_record_images and get_online_availability without naming 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?
It gives clear context for use — 'worth knowing when NARA's own pages are not online' — and explicitly frames the empty-list outcome as normal rather than a failure. It stops short of naming an alternative tool or stating a when-not-to-use condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recordARead-only
Read one Catalog record in full, by NAID.
Returns the scope and content note, the full hierarchy, the holding reference units, and every page-image URL. Use this once a search has given you a NAID worth pursuing.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID, e.g. '54765873'. | |
| refresh | No | True re-reads from the Catalog instead of the cache, spending one call and replacing the cached copy. The cache never expires on its own, so use this when the answer may have changed since you last asked. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, openWorldHint=true), so the bar is lower; the description earns credit by detailing exactly what the read returns (scope note, hierarchy, reference units, page-image URLs). It does not mention caching, freshness, or pagination behavior, though the cache/refresh semantics are handled by the schema.
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-loaded with the action and identifier, then the returned payload, then the usage trigger. No filler or repetition of the schema.
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?
With no output schema, the description carries the return-value burden and does so by listing the four payload categories an agent would care about. Combined with the fully-covered input schema and the read-only annotations, an agent has everything needed to call it 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 100%, including a thorough explanation of the refresh flag and the example NAID format, so the schema does the heavy lifting. The description adds only 'by NAID' and no extra syntax or constraints on the identifier, so the baseline 3 applies.
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?
States a specific verb and resource ('Read one Catalog record in full, by NAID') and enumerates the payload (scope and content note, hierarchy, holding reference units, page-image URLs). This clearly separates it from siblings like search_records and get_record_images without needing to open a 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?
Gives an explicit trigger: 'Use this once a search has given you a NAID worth pursuing,' which implicitly routes the agent from a search sibling to this fetch. It lacks an explicit when-not clause or a named alternative (e.g., browse_children for hierarchy traversal), so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_record_imagesARead-only
List a record's page images in page order, each with its object id.
These are the evidence. A catalog description summarises a file; it does not tell you what any individual page says, so read the images before citing anything to this record. The object id is what get_extracted_text and get_transcriptions entries point at; pass it, or the page number, to download_page_image.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID. | |
| refresh | No | True re-reads from the Catalog instead of the cache, spending one call and replacing the cached copy. The cache never expires on its own, so use this when the answer may have changed since you last asked. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint, openWorldHint) already cover the safety profile, so no contradiction risk. The description adds the read-only role of this output as 'the evidence' and its linkage to other tools. Caching/refresh behavior is disclosed in the schema, not the description, leaving only a minor gap.
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?
Front-loaded with the return shape, followed by the why-this-matters rationale and the cross-tool linkage. Slightly prose-y in the middle sentence but each sentence carries 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?
There is no output schema, so the description must carry the return-value burden, and it does: page order plus per-page object id. Combined with annotations and a fully documented schema, an agent has everything needed to call and use this tool.
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 coverage is 100%, and the schema itself richly documents both naid and the refresh/cache semantics, so the baseline is 3. The description clarifies that the returned object id is the value other tools consume, but it adds nothing about the parameters' own syntax or defaults.
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?
States a specific verb+resource+scope: 'List a record's page images in page order, each with its object id.' An agent knows exactly what it gets back and how it differs from generic record fetchers like get_record.
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?
Explicit workflow guidance: 'read the images before citing anything to this record,' plus the fact that catalog descriptions don't capture individual page content. It names the downstream siblings (get_extracted_text, get_transcriptions, download_page_image) and the condition for using each via the object id or page number.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tagsARead-only
Read the citizen tags on a record.
On genealogical records tags are very often the names of the people who appear inside the file -- the widow, the children, the witnesses -- which the title does not carry. A tag is a stranger's reading of the document and is not evidence: follow it to the page image and cite what the image shows.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID. | |
| refresh | No | True re-reads from the Catalog instead of the cache, spending one call and replacing the cached copy. The cache never expires on its own, so use this when the answer may have changed since you last asked. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover safety (readOnlyHint=true, openWorldHint=true), but the description adds genuinely useful behavioral context beyond them: tags are citizen-contributed, not evidence, and often carry names absent from the title. It omits caching behavior, though that is documented in the schema's refresh parameter.
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 action is front-loaded in one short sentence, followed by domain context. The second paragraph earns its place by explaining what tags actually contain and how to treat them, though it is somewhat discursive.
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?
There is no output schema, so the description ideally would say what a call returns (e.g., a list of tags with their authors or targets). It covers provenance and param behavior but leaves the return shape unspecified.
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 100%: both 'naid' and 'refresh' are fully documented in the schema, including the cache-vs-Catalog tradeoff. The description adds no parameter detail, so the baseline 3 applies.
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?
States a specific verb and resource: 'Read the citizen tags on a record.' The phrase 'on a record' implicitly separates it from the sibling search_tags, but no sibling is named explicitly, so differentiation must be inferred.
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 interpretive guidance ('a tag is a stranger's reading... not evidence: follow it to the page image and cite what the image shows'), which tells the agent how to act on results. However it never says when to call this vs. search_tags or get_record, so routing guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transcriptionsARead-only
Read the citizen transcriptions of a record's pages.
Volunteers have transcribed handwritten pension files, service records and letters that OCR cannot touch, which makes this the fastest way into a document in copperplate. It is still a lead, not evidence: a transcription is one stranger's reading, unreviewed, and names are exactly where such a reading goes wrong. Check the page image before citing a name or date you found here, and cite the image.
Returns one entry per transcription with its text, its author and the page it belongs to.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | Yes | The record's NAID. | |
| refresh | No | True re-reads from the Catalog instead of the cache, spending one call and replacing the cached copy. The cache never expires on its own, so use this when the answer may have changed since you last asked. | |
| max_chars | No | Characters of each transcription to return. 0 returns the whole thing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations by disclosing the trust level of the data: transcriptions are 'one stranger's reading, unreviewed,' and names are the likeliest error. The instruction to verify against the page image and cite the image is actionable behavioral guidance the annotations cannot supply. It stops short of operational detail (empty results when no transcription exists, caching), which is partly covered by the refresh parameter.
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?
Front-loads the one-line purpose, then adds caveats and return shape in two short paragraphs; three paragraphs for a single-read tool is slightly more than needed, but each sentence carries usable signal (provenance warning, citation rule, result shape).
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?
No output schema exists, yet the description states the return shape ('one entry per transcription with its text, its author and the page'), the safety profile is carried by annotations, and the data-reliability caveat is covered. An agent has everything needed to call it and interpret results responsibly.
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 100% and the refresh/max_chars semantics (cache replacement, character truncation) are already fully explained in the schema. The description adds no parameter-level meaning beyond the implied record scope, so the baseline of 3 applies.
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?
States a specific verb and resource ('Read the citizen transcriptions of a record's pages') and immediately scopes it as human-transcribed, OCR-defying material, which cleanly separates it from get_extracted_text and the search_* siblings. An agent knows what it returns and what kind of content it is 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?
Gives clear positive usage context ('fastest way into a document in copperplate') and an implicit contrast with OCR-based siblings ('that OCR cannot touch'). However, it never names an alternative or states when NOT to use it (e.g., when no transcription exists, fall back to get_extracted_text), so the routing is left partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_by_contribution_textARead-only
Search what people wrote on records, and get the records back.
This is the difference between searching a catalogue and searching the documents. A pension file titled only with the veteran's name will name his widow, his children and his witnesses in its transcribed text — none of which a title search reaches.
Unlike search_transcriptions and its siblings, which return the
contributions themselves, this filters the main index and returns full
record summaries. Use this when you want the record; use those when you
want to read what a particular volunteer wrote.
A transcription is one volunteer's reading and OCR is a machine's. Both are leads, not evidence — open the page image before citing anything.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page of results, 1-based. | |
| limit | No | Maximum records (1-100). | |
| tag_text | No | Words to find in citizen tags, which on genealogical records are usually the names of people appearing in them. | |
| comment_text | No | Words to find in researchers' comments on records. | |
| extracted_text | No | Words to find in OCR text, including text NARA's partners contributed. | |
| available_online | No | Restrict to digitised records only. | |
| transcription_text | No | Words to find in volunteers' transcriptions of the handwriting. Accepts AND, OR, NOT, wildcards and "exact phrases". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered; beyond that the description discloses real behavioral traits — that it filters the main index and returns full record summaries rather than contributions, and that transcriptions/OCR are 'leads, not evidence' that should be verified against the page image. It does not cover pagination or result-cap behavior, but that's in the schema.
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?
Front-loaded with the core action, then the differentiator, then the sibling routing, then a caution. The pension-file illustration and the evidence caveat both earn their place, though the medical-advice-style last paragraph is slightly beyond what's needed purely for tool selection.
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?
With no output schema, the description compensates by stating what comes back (full record summaries). Combined with 100% schema coverage, an agent has enough to invoke correctly; only minor gaps (pagination semantics, empty-query behavior) remain.
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 100% and each of the 7 parameters is documented in the schema, so the baseline is 3. The description only broadly characterizes the corpus being searched ('what people wrote') and adds no per-parameter syntax or format detail beyond it.
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?
States a specific verb (search) and resource (what people wrote on records) and immediately clarifies the scope difference from a title/name search with a concrete pension-file example. It explicitly names the sibling it is not (search_transcriptions) so an agent can distinguish tools 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?
Gives an explicit routing rule: 'Use this when you want the record; use those when you want to read what a particular volunteer wrote,' naming search_transcriptions and its siblings as the alternative. The condition that selects each tool is stated rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_commentsARead-only
Find records other researchers have commented on.
Useful for picking up where someone else stopped: a comment naming a surname often marks a file that a researcher has already read. Unverified by NARA, so it points at records rather than settling anything.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | No | Restrict to comments on one record. | |
| page | No | Page of results, 1-based. | |
| limit | No | Maximum records to return (1-100). | |
| query | No | Words to find in comments. | |
| contributor | No | Restrict to one contributor's screen name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only and open-world safety profile, but the description adds real context beyond them: comments are community-contributed and "unverified by NARA," so results are leads rather than authoritative facts. That trust caveat is exactly the kind of behavioral disclosure annotations cannot convey.
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, front-loaded with the core purpose, and each adds something (use scenario, trust caveat). The middle illustrative sentence about surnames is slightly long but still earns its place by explaining why the tool is worth calling.
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 five-parameter read-only search with no output schema, the description covers purpose, value, and data trustworthiness adequately. It stops short of describing the shape of returned records, but no output schema exists and the parameters are fully documented elsewhere.
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 coverage is 100%, so every parameter (naid, page, limit, query, contributor) is already documented in the schema. The description only loosely implies full-text matching on comments via the surname example and adds no syntax or format detail beyond the schema, so the baseline 3 applies.
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?
States a specific verb and resource — find records that have been commented on — which clearly distinguishes the output (records) from get_comments (the comments themselves). It does not name any sibling by name, so an agent must infer the boundary against search_records or search_by_contribution_text.
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?
"Useful for picking up where someone else stopped" gives a concrete use scenario rather than leaving usage implicit. However, no exclusions or explicit alternatives (e.g. when to prefer this over search_records or get_comments) are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_extracted_textARead-only
Find records whose extracted text mentions something.
This reaches text contributed by NARA's digitisation partners over the digital objects -- the searchable layer under the scans. It is machine output and is not evidence: it misses handwriting, it mangles names, and a hit means a page probably says this, not that it does. Read the page image before citing anything you find here.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page of results, 1-based. | |
| limit | No | Maximum records to return (1-100). | |
| query | Yes | Words to find in extracted text. Accepts AND, OR, NOT, wildcards and "exact phrases". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safe read-only, open-world profile, and the description goes well beyond them: results are machine output, not evidence; handwriting is missed; names are mangled; hits are probabilistic rather than authoritative. That is exactly the kind of accuracy caveat an agent needs before asserting a match.
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?
Purpose is front-loaded in one sentence, followed by a tight caveat block; each sentence earns its place. The corpus-scoping sentence is slightly clause-heavy but still informative rather than 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?
With no output schema, the description adequately covers the source corpus, the trustworthiness of results, and the verification step. It does not sketch the returned record shape, but the surrounding get_record/get_extracted_text siblings make that omission minor.
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 100% (page, limit, query syntax all documented in the schema), so baseline 3 applies. The description adds no query-syntax or pagination detail beyond what the schema already provides.
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?
States a specific verb and resource (“Find records whose extracted text mentions something”) and scopes the corpus as the machine-generated searchable OCR layer beneath the page scans, which implicitly separates it from transcription- and tag-oriented siblings. It never names the near-neighbour tools (search_transcriptions, search_by_contribution_text), so an agent must still infer which search surface applies.
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?
Gives strong guidance on how to treat results (“read the page image before citing anything you find here”), which implies download_page_image as a follow-up step. It does not say when to choose this tool over the sibling search tools, so selection between search surfaces remains implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_recordsARead-only
Search the National Archives Catalog for records.
Start with title and a specific phrase; the Catalog holds tens of
millions of descriptions and a broad query will bury the useful hit. A
result is a lead: check the hierarchy and dates against what you already
know before reading the images.
Returns the total number of matches and a page of summaries, each with its
NAID, hierarchy, holding unit and image count. Use search_records_advanced
when you need dates, a record group, an M-number or digitised-only.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page of results, 1-based. The API pages rather than offsetting; beyond 10,000 results it needs cursor pagination. | |
| limit | No | Maximum records to return (1-100). | |
| query | No | Full-text search across the description. Broader and noisier than title; use it when a title search finds nothing. | |
| title | No | Words to match in the record title, e.g. 'Hall pension' or a person's name. Titles of case files usually carry the name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, openWorldHint), so the bar is lower. The description still adds real context: the corpus scale that makes broad queries fail, the "a result is a lead" interpretation warning, and the exact shape of the return (total count plus page of NAID/hierarchy/holding unit/image count summaries). It does not discuss the cursor threshold itself, though the schema does.
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 paragraphs, front-loaded with purpose and then the tactic, then the return shape and the alternative. Nearly every sentence earns its place, though the framing around Catalog scale is slightly verbose for the point it makes.
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?
No output schema exists, but the description supplies the return contract (total match count plus per-record NAID, hierarchy, holding unit, image count). Combined with all-optional, fully documented parameters, an agent has everything needed to call this 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 coverage is 100%, so baseline is 3, but the description adds decision-level meaning: which parameter to start with and why (`title` first, `query` as fallback for noise). That is strategy beyond the schema's per-field definitions, though it introduces no new format or syntax detail.
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?
States a specific verb+resource ("Search the National Archives Catalog for records") and explicitly differentiates itself from the sibling search_records_advanced by naming the conditions that select the other tool. An agent can route between the two without opening either 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?
Gives concrete when-to-use advice ("Start with `title` and a specific phrase"), warns against the failure mode of a broad `query`, and names the alternative plus its trigger conditions (dates, record group, M-number, digitised-only). This is explicit when/when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_records_advancedARead-only
Search the Catalog with the filters that narrow a common name.
Every parameter is optional but at least one is required. The filters that
earn their keep for research are the date range, microform_publication
for an M-number you already cite, record_group_number or ancestor_naid
to stay inside one body of records, and available_online when you intend
to read pages rather than order copies.
Results are the same summaries search_records returns. Past 10,000 hits
use the next_search_after cursor rather than page; a common surname
passes that boundary easily.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page of results, 1-based. Ignored when search_after is given, and unusable past 10,000 results. | |
| exact | No | Match title, local_identifier and microform_publication in full and exactly, instead of by words within them. Use it when a words match returns too much, or you hold the complete title. | |
| limit | No | Maximum records to return (1-100). | |
| query | No | Full-text search across the whole description. | |
| title | No | Words to match in the record title. | |
| creators | No | The agency or person who created the records, matched against the creator headings. | |
| end_date | No | Latest date to include, in the same format as start_date. | |
| exact_date | No | A single date, YYYY-MM-DD. Cannot be combined with start_date or end_date. | |
| start_date | No | Earliest date to include, as YYYY, YYYY-MM or YYYY-MM-DD. Use the same precision as end_date. A surname search is usually only workable once it is bounded to a lifetime. | |
| tags_exist | No | True for records carrying citizen tags. | |
| data_source | No | 'description' for archival descriptions, 'authority' for authority records (people, organisations, topics). This narrows a search and cannot be one on its own. | |
| search_after | No | Cursor for paging past 10,000 results. You MUST pass '*' for the first page, then the 'next_search_after' value from each response. Starting from an ordinary search does not work: without '*' the results are relevance-sorted and their cursor is not resumable. Cannot be combined with page. | |
| ancestor_naid | No | NAID of an ancestor node: returns only records below it in the hierarchy. Use it to search inside one series. | |
| person_or_org | No | A person or organisation named in the description, either as its subject or in a role such as creator. Distinct from `creators`, which is the record's creating body only. | |
| recurring_day | No | Day as DD. Normally used with recurring_month. | |
| comments_exist | No | True for records carrying researcher comments. | |
| congress_number | No | Records of one numbered Congress, e.g. 55 for 1897-99. Private relief bills, petitions and claims naming individuals sit in the records of Congress. | |
| control_numbers | No | Any identifier NARA attaches to a record: accession number, local identifier, microfilm publication, NAID, transfer number or variant control number. For a citation whose kind you cannot name. | |
| recurring_month | No | Month as MM. With recurring_day, finds records dated to that day in any year -- a birthday across every census. | |
| reference_units | No | Name of the archive holding the paper, e.g. 'National Archives at St. Louis'. Comma-separate several. | |
| available_online | No | True for digitised records only -- those whose pages you can read now rather than order from a reading room. | |
| local_identifier | No | The archives' own identifier for the record, as printed in finding aids. | |
| type_of_materials | No | Material type, e.g. 'Textual Records', 'Photographs and other Graphic Materials', 'Maps and Charts', 'Moving Images'. | |
| contributions_exist | No | True for records carrying any contribution at all: a transcription, tag or comment. Someone has already worked on them. | |
| record_group_number | No | Record group number, e.g. '15' for Veterans Affairs. Scopes the search to one agency's records. | |
| geographic_reference | No | Place the records are about, matched against geographic subject headings, e.g. 'Franklin County (Pa.)'. | |
| level_of_description | No | One of recordGroup, collection, series, fileUnit, item. A case file is usually a fileUnit; a single page is an item. | |
| transcriptions_exist | No | True for records someone has transcribed; False for ones nobody has. Transcribed records are searchable by their text. | |
| collection_identifier | No | Collection identifier, the Presidential-library equivalent of a record group. | |
| microform_publication | No | Microfilm publication number, e.g. 'M804' for Revolutionary War pension applications or 'T624' for the 1910 census. This is the citation genealogists actually carry. | |
| include_extracted_text | No | Fold each hit's OCR text into the response, saving a call per hit: each record gains an extracted_text list with one entry per page that carries text, NARA's own OCR or a partner's, capped at 2000 characters each. It makes the response much larger, so use it on a narrowed search rather than a broad one; get_extracted_text returns whole pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, and the description adds real behavioral context beyond them: the 'every parameter is optional but at least one is required' constraint, the identical result shape to search_records, and the pagination cliff past 10,000 hits. It does not discuss rate limits or response size beyond the include_extracted_text warning, so it is good rather than comprehensive.
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 scoping sentence and the 'at least one required' constraint are front-loaded, and the third paragraph handles an important edge case (pagination). Three short paragraphs with little waste, though the middle paragraph is more of a tour of parameters than a tight decision rule.
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 31-parameter tool with no output schema, the description usefully states that results match search_records' summaries and explains cursor behavior and the response-size cost of include_extracted_text. Combined with 100% schema coverage, an agent has what it needs; only the absence of any fallback/broad-search guidance when filters are unknown keeps it from 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 100% and the schema itself carries rich per-parameter documentation (exact_date conflicts, search_after '*' requirement, level_of_description values). The description adds prioritization ('filters that earn their keep') rather than new syntax or format meaning, so it is useful framing layered on a schema that already does the heavy lifting.
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 first sentence states a specific verb and resource ('Search the Catalog') and the modifier 'with the filters that narrow a common name' signals the advanced/filtered character of this tool. It also ties itself to a sibling by noting 'Results are the same summaries search_records returns', clarifying the relationship. It stops short of an explicit "use this instead of search_records when..." statement, so it is clear but not maximally differentiating.
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 concrete when-to-use guidance by naming which filters matter for research and why ('available_online when you intend to read pages rather than order copies'). It also routes between mechanisms: 'Past 10,000 hits use the next_search_after cursor rather than page'. There is no explicit when-not-to-use or a direct sibling comparison to search_records, so it is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_tagsARead-only
Find records that carry a given citizen tag.
Tags are short, so an exact tag_is on a surname is often sharper than a
title search: a volunteer who read the file tagged the people in it. What
comes back is what a stranger thought the document said -- a lead to the
page image, and not evidence.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | No | Restrict to tags on one record. | |
| page | No | Page of results, 1-based. | |
| limit | No | Maximum records to return (1-100). | |
| query | No | Words to find in citizen tags. | |
| tag_is | No | Match one exact tag rather than words within tags. | |
| contributor | No | Restrict to one contributor's screen name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful provenance context not in the annotations: results are volunteer-applied tags, 'a lead to the page image, and not evidence' — telling the agent how much to trust the output. It does not discuss pagination behavior beyond what the schema says.
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?
Front-loaded with the purpose in the first sentence, then a compact rationale. The final sentence ('what a stranger thought the document said') is slightly rhetorical but does real work in conveying reliability, so the length is defensible.
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?
With no output schema and six fully-documented optional parameters, the description supplies the missing pieces an agent needs: what a tag is, when exact matching beats word matching, and how trustworthy the results are. Complete enough, though it leaves result ordering and empty-result behavior unmentioned.
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 100%, so all six parameters are already documented in the schema, establishing a baseline of 3. The description reinforces the tag_is versus query distinction ('tags are short'), which adds a little meaning, but not enough to exceed the schema's own parameter documentation.
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?
States a specific verb+resource: 'Find records that carry a given citizen tag.' It is readily distinguishable from data-retrieval siblings like get_tags (which presumably fetches tags for a record) because it is framed as a search over tags. It does not explicitly name a sibling, so it stops short of 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?
It offers a heuristic ('an exact tag_is on a surname is often sharper than a title search'), which is real usage guidance about matching mode, but it never names an alternative tool among the many siblings (search_records, search_transcriptions, search_by_contribution_text) or states when not to use this one. Guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_transcriptionsARead-only
Find records whose citizen transcriptions mention something.
This searches the documents rather than the catalogue, which is the difference between finding a pension file titled with the veteran's name and finding the file that names his widow, his children and the neighbours who swore to the marriage. Only transcribed records are reachable this way, so silence here means nobody has transcribed it, not that it does not exist.
Returns record summaries. A transcription is a stranger's reading and is not evidence: open the matching page images to see what was written.
| Name | Required | Description | Default |
|---|---|---|---|
| naid | No | Restrict to transcriptions of one record. | |
| page | No | Page of results, 1-based. | |
| limit | No | Maximum records to return (1-100). | |
| query | No | Words to find in transcribed text. Accepts AND, OR, NOT, wildcards and "exact phrases". | |
| contributor | No | Restrict to one contributor's screen name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely non-obvious behavior beyond that: only transcribed records are reachable, results are summaries, and transcriptions are second-hand readings requiring image verification.
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?
Purpose and the document-vs-catalogue distinction are front-loaded, and each subsequent sentence carries distinct value (reachability limit, return shape, evidence caveat). Slightly lengthy, but no sentence is 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?
With no output schema, the description compensates by stating that it returns record summaries. Combined with the transcription caveat and reachability limit, an agent has enough to call and interpret results, though pagination/limit behavior is left to 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?
Schema description coverage is 100%, so naid, page, limit, query and contributor are already fully documented in the schema. The description adds no syntax or format detail beyond that, making the baseline 3 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?
States a specific verb+resource ('Find records whose citizen transcriptions mention something') and immediately draws the crucial line against catalogue-based search ('searches the documents rather than the catalogue'). An agent can distinguish this from search_records/search_extracted_text siblings without opening any 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?
Gives clear when-to-use context via the pension-file example and a when-not-to-conclude caveat ('silence here means nobody has transcribed it, not that it does not exist'). It does not name alternative tools explicitly, so it stops short of the 5-level routing guidance.
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.
18 tool updates
v1.0.2- Changed
api_budget1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
browse_children1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
download_page_image1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_comments1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_extracted_text1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_online_availability1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_partner_digital_objects1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_record1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_record_images1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_tags1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_transcriptions1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_by_contribution_text1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_comments1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_extracted_text1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_records1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_records_advanced1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_tags1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_transcriptions1 field changed- added
Input schema / additionalPropertiesAdded value: +false
18 tool updates
v0.1.0- First observed
api_budget - First observed
browse_children - First observed
download_page_image - First observed
get_comments - First observed
get_extracted_text - First observed
get_online_availability - First observed
get_partner_digital_objects - First observed
get_record - First observed
get_record_images - First observed
get_tags - First observed
get_transcriptions - First observed
search_by_contribution_text - First observed
search_comments - First observed
search_extracted_text - First observed
search_records - First observed
search_records_advanced - First observed
search_tags - First observed
search_transcriptions
TDQS
Scored across 18 tools
Most tools target a distinct action+resource (search vs. get vs. browse vs. download), and the descriptions explicitly draw the tricky lines. However, the five-tool contribution cluster (search_transcriptions, search_extracted_text, search_tags, search_comments, search_by_contribution_text) has a subtle boundary — four return contributions while the fifth returns records — that an agent could easily misselect despite the warning text.
Names are overwhelmingly consistent snake_case verb_noun (search_records, get_record, browse_children, download_page_image), and the read/search pairs mirror each other predictably. The lone deviation is api_budget, a bare noun with no verb, which breaks the pattern.
18 tools is on the heavy side of the 3-15 sweet spot, but the domain genuinely spans four contribution types each needing read+search, two search modes, hierarchy walking, image download, availability lookups and budget reporting. Nearly every tool maps to a distinct research step rather than being redundant.
The surface covers the full research lifecycle: discovery (basic/advanced search, contribution search), retrieval (record, images, hierarchy), evidence extraction (OCR, transcriptions, tags, comments, page download), and external availability (partner objects, online availability). Minor gaps only — ancestors are folded into get_record rather than browsable, and there is no upward hierarchy walk mirroring browse_children.
Maintenance
Related MCP Connectors
US National Archives Catalog (NARA): search the federal government's permanent records…
Read-only OpenHeritage search for genealogy and cultural heritage records.
Search and trace US federal rules across the Federal Register, eCFR, and Regulations.gov.
Search the Wayback Machine and IA library (40M+ items), fetch snapshots, item metadata, and text.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables users to search and access digital collections from the Swedish National Archives (Riksarkivet) through multiple APIs. Supports searching records by keywords, exploring collections, and downloading historical images and documents.227Apache 2.0
- AlicenseAqualityCmaintenanceRead-only Model Context Protocol server for the US National Archives Catalog API, enabling search and retrieval of archival records, child records, extracted text, comments, and tags.71MIT
- FlicenseAqualityCmaintenanceEnables users to search catalog metadata, read captured pages, verify quotations, and detect changes in accepted catalog captures for New York City's September 11th Document Portal using local, read-only snapshots.10-
- AlicenseAqualityCmaintenanceEnables searching and reading Fold3 military records, including files, index records, memorials, and collection browsing, along with full-resolution page image downloads, using an existing Ancestry session in read-only mode.6MIT