MCP server by Bouch002
NARA MCP Server
A Model Context Protocol (MCP) server for the National Archives and Records Administration (NARA) Catalog API v2. Built with pure Python stdlib — no external dependencies.
Features
- 8 MCP tools covering persons, military, immigration, presidential records, and more
- SQLite caching — repeat queries are instant and free
- Rate limiting — max 1 live API call per second, with automatic retry on gateway errors
- Cross-server hints — every military/immigration result includes clickable links to complementary TNA Discovery series and Old Bailey searches
- GEDCOM integration — tag searches with a GEDCOM person ID (
@I47@) to group results by ancestor - Zero dependencies — Python 3.10+ stdlib only
Requirements
- Python 3.10+
- A NARA API key (contact Catalog_API@nara.gov)
Setup
1. Clone and configure
git clone <repo-url>
cd NARA_MCP
2. Set your API key
export NARA_API_KEY=your_key_here
Or add it to your shell profile / .env loader of choice.
3. Register with Claude Code (or any MCP client)
Add to your claude_desktop_config.json (or equivalent):
{
"mcpServers": {
"nara": {
"command": "python",
"args": ["/path/to/NARA_MCP/server.py"],
"env": {
"NARA_API_KEY": "your_key_here"
}
}
}
}
Files
| File | Purpose |
| --- | --- |
| server.py | MCP server — all tools, caching, API logic |
| nara_cache.db | SQLite cache (auto-created on first run) |
| nara_mcp.log | Rotating log file (auto-created, max 1 MB x 3) |
| pyproject.toml | Package metadata |
Tools
nara_search_history
Query the local SQLite cache. Always call this first — cache hits are instant and free.
| Parameter | Type | Description |
| --- | --- | --- |
| gedcom_id | string (optional) | Filter to a specific ancestor, e.g. @I47@ |
| keyword | string (optional) | Filter cached records by title or description |
nara_suggest_series
Get NARA record group suggestions plus complementary TNA Discovery and Old Bailey links from a plain-English research context. No API call — instant.
| Parameter | Type | Description |
| --- | --- | --- |
| context | string (required) | e.g. "WWI soldier born 1895 New York, immigrant from Ireland" |
Supported categories: Civil War, Revolutionary War, naval/piracy, WWI, immigration and naturalisation, Freedmen's Bureau, Native American, Presidential.
nara_search_person
Primary person search. Automatically generates:
- US census search links for relevant years
- Draft eligibility assessment (WWI, WWII, Civil War pension)
- Immigration links if birthplace is non-US
- Military/naval cross-server fan-out hints
- NPRC fire warning where applicable
| Parameter | Type | Description |
| --- | --- | --- |
| forename | string (required) | |
| surname | string (required) | |
| date_from | integer (optional) | Birth year |
| date_to | integer (optional) | Death year |
| birthplace | string (optional) | Triggers immigration links if non-US |
| occupation | string (optional) | Triggers military/naval fan-out if applicable |
| record_type | string (optional) | military, immigration, naturalisation, pension, draft |
| gedcom_id | string (optional) | Tags the cache entry — no other effect |
nara_search_records
Broad keyword search across all 35M+ NARA catalogue records. Best for places, events, units, ships, or topics rather than specific persons.
| Parameter | Type | Description |
| --- | --- | --- |
| query | string (required) | |
| collection | string (optional) | Record Group number, e.g. "94" for Adjutant General |
| date_from | integer (optional) | |
| date_to | integer (optional) | |
| level | string (optional) | recordGroup, series, fileUnit, item |
| gedcom_id | string (optional) | |
nara_search_military
Targeted military records search. Automatically selects the relevant Record Groups for the given war and includes cross-server hints for TNA WO/ADM series and Old Bailey soldier/sailor searches.
| Parameter | Type | Description |
| --- | --- | --- |
| query | string (required) | Person name, regiment, unit, or battle |
| war | string (optional) | revolutionary, civil_war, wwi, wwii, korea, vietnam |
| date_from | integer (optional) | |
| date_to | integer (optional) | |
| gedcom_id | string (optional) | |
Record Groups searched by war:
| War | Record Groups |
| --- | --- |
| revolutionary | RG 93, RG 15 |
| civil_war | RG 94, RG 109, RG 15 |
| wwi | RG 120, RG 163, RG 92 |
| wwii | RG 407, RG 147, RG 338 |
| korea | RG 338, RG 319 |
| vietnam | RG 472, RG 319 |
| (default) | RG 94, RG 15, RG 24, RG 45 |
nara_search_immigration
Targeted immigration and naturalisation search across RG 36 (passenger lists 1820-1957), RG 85 (INS), and RG 21 (court naturalisation records pre-1906). Includes TNA BT 26/27 cross-reference links.
| Parameter | Type | Description |
| --- | --- | --- |
| surname | string (required) | |
| forename | string (optional) | |
| arrival_year_from | integer (optional) | |
| arrival_year_to | integer (optional) | |
| origin_country | string (optional) | |
| gedcom_id | string (optional) | |
nara_get_record
Fetch the full catalogue description for a specific record.
| Parameter | Type | Description |
| --- | --- | --- |
| identifier | string (required) | Numeric NaId (e.g. "12345678") or reference string |
| gedcom_id | string (optional) | |
nara_search_presidential
Search Presidential Library holdings (Hoover through Obama). Includes TNA FO 371 and PREM cross-reference links for Anglo-American diplomatic research.
| Parameter | Type | Description |
| --- | --- | --- |
| query | string (required) | |
| president | string (optional) | e.g. "truman", "kennedy", "reagan" |
| date_from | integer (optional) | |
| date_to | integer (optional) | |
| gedcom_id | string (optional) | |
Caching
All search results are stored in nara_cache.db (SQLite, created alongside server.py). The schema has three tables:
searches— one row per tool call, keyed by a SHA-256 hash of the parametersrecords— one row per unique NARA record (keyed by NaId), upserted on each cache writesearch_records— many-to-many join between searches and records
Cache hits bypass the API entirely. There is currently no TTL/expiry — to refresh a result, delete the relevant row from searches.
Rate Limiting
A 1-second minimum interval is enforced between live API calls. Network errors and 502/503/504 responses are retried up to 3 times with exponential backoff (2 s, 4 s).
Cross-Server Research
This server is designed to complement two other MCP servers:
- TNA (The National Archives) — British records. Every military and immigration result includes direct TNA Discovery series links (WO 363, WO 372, ADM 36, BT 26, BT 27, FO 371, etc.)
- Old Bailey Online — Criminal proceedings 1674-1913. Military and naval results include pre-built Old Bailey search URLs filtered by relevant terms (soldier, sailor, regiment, ship).
For military or naval queries, always fan out to all three servers in parallel.
Logging
Logs are written to nara_mcp.log alongside the server file. The handler rotates at 1 MB, keeping 3 backups. Log level: INFO.
Known Limitations
- 1890 census: Substantially destroyed by fire in 1921 — fragments survive for some counties only.
- NPRC St Louis fire (1973): ~80% of Army records 1912-1960 and ~75% of Air Force records 1947-1964 were destroyed. Absence of a service record does not mean the person did not serve.
- 1960+ census: Under the 72-year privacy rule — most recent publicly available census is 1950.
- Old Bailey archive: Ends at 1913 in the online edition.
License
See repository root for licence information.