agentleFS
kltngkltng/humanities-skills/princeton-library-catalog/SKILL.md

princeton-library-catalog

Skill9 starsChanged 19 days agoMITView on GitHub

Search the Princeton University Library catalog (Alma) through its public SRU interface for books, journals, manuscripts, microfilm, and e-resources, including the East Asian Library and its rare Chinese books. Use this skill whenever the user wants to look up items at Princeton, check whether Princeton holds a book and where it is shelved, search by title/author/subject/ISBN/OCLC/call number, read MARC records with vernacular (880) script fields, or compare Princeton holdings with other libraries. Returns call numbers, locations, availability, and online access.

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 6 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Search Princeton's library catalog (Alma) for print and online holdings.

    line 13
  2. Very specific:

    Use phrase=True (CLI --phrase) to keep only titles that contain the term as one connected phrase.

    line 45
  3. Very specific:

    Subject headings: write LCSH as plain words, without -- , in LC's inverted form.

    line 55
  4. Very specific:

    Search fields: keyword, title, author, subject, isbn, issn, oclc, lccn, publisher, series, call_number, language (MARC code: chi, jpn, kor, …

    line 102
  5. Distinctive:

    alma-sru-catalogs: search this library and 20 others (Oxford, Cambridge, Toronto, Berkeley, …) in one call

    line 118
  6. Distinctive:

    hathitrust-catalog: use OCLC numbers from here to find digitized copies

    line 121
  7. Distinctive:

    Ask the user before filing.

    line 135
  8. Very specific:

    Check for an existing report: gh issue list --repo kltng/humanities-skills --state all --search "princeton-library-catalog"

    line 136
  9. Distinctive:

    Cite: If this skill helped work that is published, please cite it, together with the data source it uses:

    line 140
  10. Distinctive:

    When you help a user write up results that relied on this skill, remind them once about this citation.

    line 144

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Princeton University Library Catalog Skill

Search Princeton's library catalog (Alma) for print and online holdings. No API key needed.

Overview

Princeton runs its catalog on Ex Libris Alma. Alma has a public SRU interface (Search/Retrieve via URL, a library standard for searching catalogs over plain HTTP). Queries are written in CQL (Contextual Query Language, e.g. alma.title="明史"). Records come back as MARCXML; the script turns them into simple JSON.

https://princeton.alma.exlibrisgroup.com/view/sru/01PRI_INST
  ?version=1.2&operation=searchRetrieve&recordSchema=marcxml
  &query=alma.title="明史"&maximumRecords=10

Critical: Things Claude Won't Know Without This Skill

Do not scrape catalog.princeton.edu

Princeton's catalog website (Orangelight) has a catalog.json search, but its robots.txt disallows search URLs (/*?q=*) for automated clients and asks for a 10-second crawl delay. Record pages also redirect scripts to a /challenge bot check. Use Alma SRU instead. Give people catalog.princeton.edu/catalog/{mms_id} links to open in a browser. Princeton's MMS IDs end in 06421.

Holdings are in the AVA and AVE fields

  • AVA = print/physical copy. $q library name, $c location, $d call number, $e available/unavailable, $f item count, $t volume summary.
  • AVE = online copy. $m collection, $t interface (platform), $e Available, $n note, $u access link (when supplied).

The script reads both into holdings.physical and holdings.electronic. Keys: holdings.physical[] has library, location, call_number, availability, items_total, items_unavailable, summary; holdings.electronic[] has collection, interface, availability, note, url. East Asian Library holdings show $q = East Asian Library and location codes such as cjk: East Asian Library.

Chinese/Japanese/Korean script is in 880 fields

The main fields (245 title, 100 author, 260/264 publisher) are romanized (pinyin, Hepburn, McCune-Reischauer). The original script is in a linked 880 field. The script pairs them, so title reads like 明史 (Ming shi). Search in both scripts: alma.title="明史" and alma.title="Ming shi" return different sets.

Title searches match words, not phrases

  • alma.title="shi dian" matches records with shi and dian anywhere in the title (278 hits at Princeton on 2026-10-26, many of them unrelated titles). Quotes and adj change nothing; == matches the whole title field exactly.
  • Use phrase=True (CLI --phrase) to keep only titles that contain the term as one connected phrase. It filters each page after the search, so total is still the server's count; use search_all(..., phrase=True) to scan every page.
  • Pinyin syllables stay ambiguous: shi dian also matches 知识典籍 (zhi shi dian ji), and ji qi is 機器 as well as 祭器. After a romanized search, keep the records whose vernacular title has the characters you want.
  • A CJK title search can also miss titles that contain the term. Alma splits CJK titles into words with a dictionary: 文廟祀典考 is indexed as 文 / 廟祀 / 典考, so alma.title="文廟" misses it at U-M and Princeton (Yale finds it). The romanized Wen miao finds it.
  • So never treat one CJK title search as complete. Search the traditional, simplified, and romanized forms (文廟, 文庙, Wen miao) and merge the results by mms_id.

Limits and quirks

  • 50 records per request at most. Page with startRecord (1-based); search_all() does this for you.
  • Sort goes inside the CQL: ... sortBy alma.main_pub_date/sort.descending. The sortKeys parameter is ignored. Records with unknown dates (uuuu) sort first in ascending order; add cql="alma.main_pub_date>=1000" to drop them. But placeholder years such as #### still pass that filter and sort first (seen at Princeton and U-M on 2026-10-26). Add known_dates=True (CLI --known-dates) to drop records whose year is not four digits. It filters each page after the search, like phrase.
  • Default order is not relevance ranking. Narrow the query (title + language, or a date range) rather than relying on the first results.
  • Subject headings: write LCSH as plain words, without --, in LC's inverted form. alma.subjects="Confucius Cult" works; "Confucius -- Cult" gives 0. "Temples, Confucian" works; "Confucian temples" gives 0.
  • Subject heading output: name and title subjects (600/610/611/630) keep their dates and title in the heading, e.g. Song, Yingxing, 1587-approximately 1666. Dian gong kai wu. Only the subdivisions $v $x $y $z are joined with --, e.g. Science -- China -- History.
  • Network errors are retried. Dropped connections, read timeouts, and HTTP 429/5xx are retried up to 4 times (waiting 5, 10, 20 s, or Retry-After). If a later page of search_all() still fails, it raises IncompleteResults; the records fetched so far are in its .records.
  • Unknown index names fail with a vague "Catalog search has encountered an error". Check the spelling against references/api_reference.md.
  • Encode the query with normal URL encoding. Raw Chinese or quotes in the URL give HTTP 400.

When to Use

  • "Does Princeton have X?" / "Where is X shelved at Princeton?"
  • Finding Chinese, Japanese, or Korean books in Princeton's East Asian collections
  • Finding pre-modern editions with a date range (alma.main_pub_date<1900)
  • Getting MARC data (OCLC, LCCN, ISBN, subjects) for a known item
  • Comparing holdings across libraries

Quick Start

CLI

python scripts/princeton_api.py search --title 明史 --language chi --limit 5
python scripts/princeton_api.py search --author "Elman, Benjamin A." --sort date_desc
python scripts/princeton_api.py search --cql 'alma.title=明史 and alma.main_pub_date<1900' --sort date_asc
python scripts/princeton_api.py search --call-number 'DS753*' --json
python scripts/princeton_api.py record 9953348843506421
python scripts/princeton_api.py record 9953348843506421 --raw   # all MARC fields

Python

from scripts.princeton_api import PrincetonCatalogAPI

lib = PrincetonCatalogAPI()
result = lib.search(title="明史", language="chi", sort="date_asc",
                    cql="alma.main_pub_date>=1000", limit=10)
print(result["total"])
for rec in result["records"]:
    print(rec["title"], rec["year"])
    for h in rec["holdings"]["physical"]:
        print("  ", h["library"], h["call_number"], h["availability"])

lib.search(oclc="424023")                        # exact identifier lookups
lib.search(isbn="9787101003277")
lib.search_all(subject="China History Ming dynasty", max_results=200)
lib.get_record("9953348843506421")                 # one record by MMS ID

Search fields: keyword, title, author, subject, isbn, issn, oclc, lccn, publisher, series, call_number, language (MARC code: chi, jpn, kor, eng), mms_id. Sort: date_desc, date_asc, title, author.

Each summary has mms_id, title, titles (romanized + vernacular), author, authors, contributors, edition, publication, year, language, physical_description, series, subjects, isbns, oclc, lccn, lc_call_number, classifications, subject_headings, holdings, and url (the public record page).

Cataloging fields (for comparing cataloging traditions): subject_headings lists each 6XX heading with its vocabulary (lcsh, csht = Taiwan's Chinese subject headings, fast, mesh, …), and classifications lists each class number with its scheme (lcc, ddc, ncsclt = 中文圖書分類法, the Chinese classification used in Taiwan, …). subjects stays a plain list of strings.

Best Practices

  1. Search both scripts (Chinese characters and romanization) for full coverage.
  2. Narrow with language (chi, jpn, kor) when a title word is common.
  3. Match across catalogs with oclc or isbn. These are exact.
  4. Give people the url so they can see live status and request items in a browser.
  5. Respect the server. The script waits 1 second between requests and backs off on HTTP 429/503 with Retry-After. Do not page through thousands of records.

Related Skills

  • alma-sru-catalogs: search this library and 20 others (Oxford, Cambridge, Toronto, Berkeley, …) in one call
  • umich-library-catalog, yale-library-catalog, pitt-library-catalog: the same Alma SRU method at other libraries
  • harvard-library-catalog, loc-catalog: other catalogs to compare holdings
  • hathitrust-catalog: use OCLC numbers from here to find digitized copies
  • zotero-local: save found records into Zotero

Resources

  • references/api_reference.md — SRU parameters, CQL syntax, index list, MARC and AVA/AVE field guide
  • scripts/princeton_api.py — Alma SRU client and CLI (zero dependencies)
  • tests/test_princeton_api.py — offline tests (python -m unittest discover -s tests)
  • Ex Libris SRU docs: https://developers.exlibrisgroup.com/alma/integrations/sru/

Feedback and Citation

Report a problem. This skill is part of the public repository kltng/humanities-skills. If it fails (an API changed, a script errors, or these instructions are wrong), report it as a GitHub issue:

  1. Ask the user before filing. Issues are public.
  2. Check for an existing report: gh issue list --repo kltng/humanities-skills --state all --search "princeton-library-catalog"
  3. File it: gh issue create --repo kltng/humanities-skills --label bug --title "[princeton-library-catalog] <short summary>" --body "<details>". Without gh, give the user this link: https://github.com/kltng/humanities-skills/issues/new?template=skill-problem.yml
  4. Include the skill name and version, what you ran, the error text, what you expected, and the environment (OS, Python version). Leave out API keys, personal data, private file paths, and unpublished research.

Cite. If this skill helped work that is published, please cite it, together with the data source it uses:

Tang, Kwok-leong. humanities-skills: princeton-library-catalog (version <version at the top of this file>). GitHub, <year>. https://github.com/kltng/humanities-skills

When you help a user write up results that relied on this skill, remind them once about this citation.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.