Libofcongress Mcp Server

io.github.cyanheadsPublished by GitHub account cyanheadsv0.6.0Updated Nov 3, 2026

Search LOC digital collections, Chronicling America newspapers (full OCR), and LC Subject Headings.

VerifiedStreamable HTTPWeb executableWeb Search & ScrapingKnowledge & Memory

Overview

Libofcongress's hosted MCP server (libofcongress.caseyjhand.com); no sign-in required; Streamable HTTP; 6 tools.

No AI overview yet: these facts come from the registry entry and the server itself.

Endpoint
libofcongress.caseyjhand.com
Last checked

Installation

In SourceWeft

  1. Open Libofcongress Mcp Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.cyanheads%2Flibofcongress-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "libofcongress": {
      "type": "http",
      "url": "https://libofcongress.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/libofcongress-mcp-server

Search LOC digital collections, browse Chronicling America newspapers with full OCR text, and look up LC Subject Headings via MCP. STDIO or Streamable HTTP.

6 Tools • 1 Resource • 1 Skill


Overview

Library of Congress digital collections, Chronicling America historic newspapers, and LC Subject Headings. Search items and newspaper pages, read full metadata and OCR text, resolve subject terms, and browse curated collections.

Tools

ToolDescription
libofcongress_search_itemsSearch LOC digital collections by keyword with format, date range, subject, location, and collection filters.
libofcongress_get_itemRetrieve full metadata for a specific LOC digital item — imprint, contributors, subjects, rights, formats, its digital resources, and a paged list of its pages.
libofcongress_search_newspapersSearch historical newspaper pages in the Chronicling America corpus, with an excerpt of each page's opening OCR text.
libofcongress_get_newspaper_pageRetrieve the full text and metadata of one page — a newspaper page, or a book or manuscript page from libofcongress_get_item — or only the passages around a search term.
libofcongress_search_subjectsSearch Library of Congress Subject Headings (LCSH) by keyword.
libofcongress_browse_collectionsList and browse LOC curated digital collections, optionally filtered by keyword.

Resources

ResourceDescription
libofcongress://item/{+item_id}LOC digital item metadata by ID — stable URI for injecting item context into agent conversations.

All resource data is also reachable via libofcongress_get_item. Use libofcongress_search_items to discover item IDs first.

Research guide

libofcongress-guide covers identifier chains, OCR uncertainty, research coverage, and collection, newspaper, book, and manuscript workflows. It ships with plugin, npm, Docker, and MCPB installs and is also available through MCP skill discovery and resource reads.

Capability reference

libofcongress_search_items tool

  • Filters: eight material formats (photo, map, newspaper, manuscript, audio, film, book, notated-music), inclusive year range (date_start/date_end), subject (an LCSH heading from libofcongress_search_subjects or a facet term), location, and collection_slug (from libofcongress_browse_collections, combinable with format); up to 100 results per page — a larger limit (up to 1000) is served as 100 with effectiveLimit and a notice
  • Use query: "*" to browse without a keyword. sort accepts relevance (default), date (oldest first), or date_desc (newest first); effectiveSort echoes the order LOC applies before pagination
  • Each result carries date as LOC catalogs it and is_item: true for catalog items whose id resolves via libofcongress_get_item, false for other resources. Newspaper rows include page_url for libofcongress_get_newspaper_page; retired catalog links carry link_notice and retain their original URL. Other non-item rows can be opened at url
  • include_facets: true adds subject_facets and location_facets (LOC's top 10 terms across all matches, each with its item count); off by default since it slows every search. A zero-result notice names the subject terms and location applied

libofcongress_get_item tool

  • Takes a search result's id (simple or multi-segment, e.g. sn95047246/1935-09-05/ed-1), a loc.gov item link, or an lccn.loc.gov permalink; any other URL is rejected as invalid_item_id before any request
  • Returns the imprint, contributors with roles, LCSH subject_headings, subject_terms (the lowercase terms the search subject filter accepts), notes, summary, languages, locations, rights_information as plain text, physical description, call number, former IDs, formats, and access_restricted; fields absent upstream are omitted
  • resources lists each digital resource with its page count, image, pdf, and audio (MP3). pages lists 50 pages at a time by default (page_offset, page_limit, page_total, next_page_offset; at most 100 per call — a larger page_limit, up to 1000, is served as 100 with effectivePageLimit and a notice), each with a page_url and has_text that read through libofcongress_get_newspaper_page. include_files: true adds each page's download URLs

libofcongress_search_newspapers tool

  • Filters: keyword, inclusive date range down to the day (date_start/date_end take an integer year or a YYYY, YYYY-MM, or YYYY-MM-DD string), indexed state/province (full name or supported US postal code), and newspaper title (the exact newspaper_title of a search result); up to 100 results per page — a larger limit (up to 1000) is served as 100 with effectiveLimit and a notice
  • sort accepts relevance (default), date (oldest first), or date_desc (newest first); effectiveSort echoes the applied order
  • Each result carries the opening ~500 characters of the page's OCR text, states, and the url that libofcongress_get_newspaper_page takes verbatim
  • The excerpt is the page's first lines, not the text around the match; pass the same query as match to libofcongress_get_newspaper_page for the passages around it

libofcongress_get_newspaper_page tool

  • Takes the url from a libofcongress_search_newspapers result, or a pages[].page_url from libofcongress_get_item (newspaper, book, and manuscript pages alike), plus Chronicling America page links; a link that names no single page, any other host, or a malformed path or sp is rejected as invalid_page_url before any request
  • Returns the page's text as ocr_text with newspaper_title, date, place_of_publication, states, edition, sequence, segment_count, item_title, and item_id (pass it to libofcongress_get_item to list the item's pages). ocr_available: false marks an image-only page, and a notice explains an empty result: the text service did not answer (retry), the body could not be read as text, or the page is blank
  • match returns only the passages around a term — pass the query you searched with. Space-separated words are separate terms and a double-quoted span is one phrase, matched case-insensitively. matches holds up to 10 passages of about 300 characters either side of each occurrence, match_count counts every occurrence, and ocr_text is empty; a notice says when nothing matched or some occurrences fall outside the passages. If text retrieval fails, both match fields are absent because the result is unknown; blank and image-only pages still report zero

libofcongress_search_subjects tool

  • Keyword query, up to 250 results per call (default 10; a larger limit, up to 1000, returns up to 250 with a notice); returns the authorized LCSH label and stable LOC uri
  • Start at offset: 0 (default), then pass next_offset to continue. total counts this page's headings; the final or past-end page omits next_offset. A past-end offset succeeds empty with a recovery notice
  • An exact match from the first 50 results moves to the start. Subsequent offsets and changed limits preserve that ordering while the upstream results remain unchanged
  • Pass the label verbatim as libofcongress_search_items's subject filter. A partial word (aerial photog) falls back to headings that begin with it

libofcongress_browse_collections tool

  • Optional keyword filter on collection name and description; up to 100 collections per page — a larger limit (up to 1000) is served as a 100-collection page with effectiveLimit and a notice
  • Each collection carries a slug for libofcongress_search_items's collection_slug (taken from the loc.gov route, not derivable from the title); item_count is approximate and omitted when LOC doesn't provide it

libofcongress://item/{+item_id} resource

  • Returns the same record as libofcongress_get_item, as application/json, with the first 50 pages and no files; next_page_offset marks where libofcongress_get_item's page_offset continues
  • item_id comes from a libofcongress_search_items result's id; anything that is not an item ID is rejected as invalid_item_id. Multi-segment newspaper IDs keep their slashes (libofcongress://item/sn95047246/1935-09-05/ed-1)

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

Library of Congress-specific:

  • Request queue in front of www.loc.gov: calls start in arrival order, at least LOC_REQUEST_DELAY_MS apart (default 3100ms, ~19 req/min), never exceeding LOC's 20 per minute. A call that cannot start in time fails as server_busy with retryAfter
  • Rate-limit handling: a 429 triggers LOC's 1-hour block, and calls fail without sending anything until it lifts (never retried); a Cloudflare challenge or HTML page instead of JSON fails as upstream_unavailable with retryAfter: 60. libofcongress_search_subjects (id.loc.gov) is unaffected
  • A 50-second budget per tool call covers queue wait, retries, and the OCR fetch, so a slow upstream fails as request_timed_out; other upstream failures (dropped connections, 5xx or 403, empty or truncated bodies) fail as upstream_unavailable with a retry hint
  • Pages past the end of the results or past the retrieval ceiling return an empty result with a notice, not an error
  • Newspaper OCR is surfaced as-is; 19th-century or degraded pages may contain garbled text

Agent-friendly output:

  • Empty results include a notice with recovery hints that echo the applied filters
  • Item and newspaper searches carry pagination status (total, page, pages, has_next), capped at LOC's ~100,000-item retrieval ceiling; subject searches use offset and next_offset with a page-local total
  • ocr_available and is_item let callers branch without parsing text
  • Every typed error carries a recovery hint

Getting started

Connect Claude Code to the hosted server:

sh
claude mcp add --transport http libofcongress-mcp-server https://libofcongress.caseyjhand.com/mcp

Or run it locally:

sh
claude mcp add libofcongress-mcp-server -- npx -y @cyanheads/libofcongress-mcp-server

For other clients, add this to the MCP config file:

json
{  "mcpServers": {    "libofcongress-mcp-server": {      "command": "npx",      "args": ["-y", "@cyanheads/libofcongress-mcp-server"]    }  }}

No API key is required. Set LOC_USER_AGENT to identify your application to LOC. For Docker or a source build, see Running the server.

Configuration

All configuration is validated at startup via Zod schemas in src/config/server-config.ts.

VariableDescriptionDefault
LOC_USER_AGENTUser-Agent header sent with LOC API requests. LOC recommends a descriptive value for polite access.libofcongress-mcp-server/0.6.0
LOC_REQUEST_DELAY_MSDelay in milliseconds between LOC API requests to stay under the 20 req/min rate limit.3100
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_SESSION_MODEHTTP session mode. This server is explicitly stateless.stateless
MCP_LOG_LEVELLog level (RFC 5424).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
LOG_TOOL_FAILURE_PAYLOADSLog each failed tool call's arguments and result, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). A secret inside a free-form value is not redacted.false
STORAGE_PROVIDER_TYPEStorage backend.in-memory
OTEL_ENABLEDEnable OpenTelemetry instrumentation (spans, metrics, completion logs).false

See .env.example for the full list of optional overrides.

Running the server

Local development

Requires Bun v1.4.0 or higher (or Node.js v24+).

sh
git clone https://github.com/cyanheads/libofcongress-mcp-server.gitcd libofcongress-mcp-server && bun installcp .env.example .env# Optionally set LOC_USER_AGENT or LOC_REQUEST_DELAY_MS.
  • Build and run:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:stdio# orbun run start:http
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, securitybun run test       # Vitest test suitebun run lint:mcp   # Validate MCP definitions against spec

Docker

sh
docker run --rm -p 3010:3010 ghcr.io/cyanheads/libofcongress-mcp-server:latest

The image defaults to HTTP transport, stateless session mode, and logs to /var/log/libofcongress-mcp-server. For stdio in an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/libofcongress-mcp-server:latest"]. Build locally with docker build -t libofcongress-mcp-server .; OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools, resource, and initializes services.
src/configServer-specific environment variable parsing (LOC_USER_AGENT, LOC_REQUEST_DELAY_MS).
src/mcp-server/toolsTool definitions (*.tool.ts) — six LOC tools.
src/mcp-server/resourcesResource definitions — libofcongress://item/{+item_id}.
src/services/loc-apiLocApiService wrapping www.loc.gov — search, item fetch, page text, collection browser.
src/services/lc-linked-dataLcLinkedDataService wrapping id.loc.gov — LCSH subject heading suggest.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools and resources via the arrays in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

Source: README.md at commit c80159d

Tools

6

libofcongress_search_items

Search LOC Items

Search the Library of Congress digital collections by keyword. Optionally filter by material format (photos, maps, newspapers, audio, etc.), date range, subject heading, or geographic location, or scope the search to a single curated collection with collection_slug. Returns item summaries with titles, dates, descriptions, LOC IDs, and format tags. Each result carries is_item: pass the id of a result where is_item is true to libofcongress_get_item for full metadata. Non-item resources include collections, exhibit and research-guide pages, newspaper pages, catalog.loc.gov records, and hdl.loc.gov finding aids. When page_url is present, pass it to libofcongress_get_newspaper_page, optionally using the search query as match; its item_id identifies the issue. A link_notice warns that a retired catalog URL no longer opens its record; otherwise follow a non-item url. Use libofcongress_search_subjects to find an LCSH heading for the subject filter. To discover the subject and location values the filters accept for a search, set include_facets to get its top subject_facets and location_facets.

Parameterspagesortlimitqueryrequiredformatsubjectdate_endlocationdate_startinclude_facetscollection_slug

libofcongress_get_item

Get LOC Item

Retrieve the full metadata record for a specific LOC digital item. Returns the imprint (place, publisher, and date of publication), contributors, LCSH subject headings and the subject terms the search subject filter accepts, summary, languages, locations, rights information, physical description, call number, original and online formats, access restrictions, former catalog IDs, notes, and related items, plus the item's digital resources (each with its page count, representative image, PDF, and audio) and a window of its pages. Each page has a page_url and has_text; pass a page_url with has_text true to libofcongress_get_newspaper_page to read that page's text (newspaper, book, and manuscript pages alike). A long item lists 50 pages per call: continue with page_offset set to next_page_offset. Set include_files for each listed page's downloadable files (TIFF, JP2, JPEG sizes, text). Use after libofcongress_search_items on a result whose is_item is true. Pass the result id — a simple ID, an LCCN, or a slash-separated newspaper path — or a loc.gov item link (`https://www.loc.gov/item/<id>/`) or LCCN permalink (`https://lccn.loc.gov/<lccn>`), which is read as its id. Non-item results (is_item: false) — collections, exhibits, guides, newspaper pages, catalog.loc.gov records, hdl.loc.gov finding aids — have no item record and cannot be retrieved here.

Parametersitem_idrequiredpage_limitpage_offsetinclude_files

libofcongress_search_newspapers

Search Historical Newspapers

Search historical newspaper pages in the Chronicling America corpus. Returns matching pages with the opening of each page's OCR text (~500 characters), publication title, date, the states LOC indexes the title under, and the page URL needed for libofcongress_get_newspaper_page. Filters by keyword, date range, indexed state/province, and newspaper title. The excerpt is the page's first lines, not the text around the match: to read where the query occurs, call libofcongress_get_newspaper_page with the returned url field and this query as its match, which returns the passages around each occurrence; omit match for the full page text. OCR quality varies: 19th-century and degraded materials may contain fragmented or garbled text.

Parameterspagesortlimitqueryrequiredstatedate_enddate_startnewspaper_title

libofcongress_get_newspaper_page

Get Newspaper Page

Retrieve the full text of one LOC page — a historical newspaper page, or a book or manuscript page — or, with match, only the passages around your search terms, with its publication metadata: for newspapers the title, issue date, place of publication, indexed states, and edition; for every page its sequence, the page count, and the item_title and item_id of the issue, book, or manuscript it belongs to — pass item_id to libofcongress_get_item to list every page of the item. Pass the url field from a libofcongress_search_newspapers result, or a pages[].page_url from libofcongress_get_item (has_text true), or a Chronicling America page link (…/ed-N/seq-M/) — do not construct this URL manually. A dense newspaper page runs to 50,000 characters: to find the article a search hit on, pass the search query as match and read the passages around it rather than the whole page. The text is OCR, or for some manuscripts a volunteer transcription; OCR quality varies by digitization batch and era, and 19th-century and degraded materials may contain fragmented text, garbled words, and line-break artifacts that are surfaced as-is. When a page exists but has no digitized text, ocr_available is false and ocr_text is empty — this is a data property, not an error.

Parametersmatchpage_urlrequired

libofcongress_search_subjects

Search LC Subject Headings

Search Library of Congress Subject Headings (LCSH) by keyword. Returns authorized subject headings and their URIs in a stable paged order, promoting an exact match from the first 50 results to the start; a partial word with no keyword match returns the headings that begin with it. Use the returned label as the subject filter in libofcongress_search_items — LCSH uses precise, standardized terms that differ from natural language (e.g., "World War, 1939-1945" not "World War II"; "Aerial photography" not "Photography, Aerial"). Running this tool before a subject-filtered libofcongress_search_items dramatically improves result quality.

Parameterslimitqueryrequiredoffset

libofcongress_browse_collections

Browse LOC Collections

List and browse Library of Congress curated digital collections. Returns collection names, descriptions, item counts, slugs, and URLs. Optionally filter by keyword. Collections are curated subsets of the digital holdings with specific focuses (e.g., "Civil War Glass Negatives", "Baseball Cards", "WPA Posters"). Pass a returned slug to libofcongress_search_items.collection_slug to search within it; use query "*" to browse matching records, optionally with format, date and sort filters. Use the returned URL to navigate directly to a collection on loc.gov.

Parameterspagelimitquery

Version history

8
  1. v0.6.0LatestNov 3, 2026
  2. v0.5.1Oct 16, 2026
  3. v0.5.0Oct 15, 2026
  4. v0.4.0Oct 14, 2026
  5. v0.3.1Oct 7, 2026
  6. v0.3.0Sep 23, 2026
  7. v0.2.18Sep 19, 2026
  8. v0.2.17Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts