Literature Search
Five search layers answer five different questions. Running them in order moves from what the library already holds, through what it holds but has forgotten, out to what exists in the literature and the library lacks. Any single layer used alone gives a misleading picture of the field.
The Layers
| Layer | Tool | Question it answers | Scope |
|---|---|---|---|
| 1. Metadata | zotero_search_items, default qmode | What do I hold with this in the title? | All 17 libraries |
| 2. Full text and own words | zotero_semantic_search | What sits inside my PDFs, notes and annotations? | Personal and Deep Design Lab only |
| 3. Citation graph | zotero_scholar, or the OpenAlex API | Who does this build on, and who took it up? | Open scholarly web, DOI required |
| 4. Discovery | Undermind search_papers, launch_deep_search | What exists that I have never seen? | Global corpus |
| 5. Gap check | Layer 1 and 2 again, on layer 3 and 4 findings | Which of these do I already own? | All 17 libraries |
Layer 5 matters most and gets skipped most often. Discovery tools return long lists whose value depends entirely on which entries are new.
How Each Layer Behaves
Layer 1 is deliberately narrow. It matches title, creator and year. Use it to establish ground truth on holdings and to check whether a specific work is present. Passing qmode: "everything" widens it to notes and Zotero's own extracted full text, which reaches all 17 libraries including the 14 that carry no semantic index.
Layer 2 reads inside documents. Every hit reports a source field: fulltext came from a PDF body, note and annotation came from your own writing. Phrase the query in the vocabulary of the field you want to reach rather than the field you work in. Searching for planetary boundaries and biogeochemical cycles surfaces sociology, law and Earth system science. Searching for planetary design surfaces design.
Choose mode deliberately. semantic gives pure meaning matching and drops keyword noise. keyword gives BM25 precision on titles and abstracts. auto fuses both and is the right default for exploration.
Layer 3 requires a DOI and explores rather than searches. It takes references (what a work cites), citations (who cites it), and related. It cannot answer a text query, so it always needs a seed from layers 1, 2 or 4. Setting include_in_library: true folds layer 5 into it.
Layer 4 wants a pseudo-abstract. Undermind's sample_abstract should read as two or three sentences excerpted from the paper you wish existed, written in that paper's voice. Keyword lists degrade it. launch_deep_search takes a research goal in plain paragraph form instead, runs autonomous agents for several minutes, and suits questions worth waiting for.
Traps
- Keyword search is conjunctive, so multi-word gap checks lie. Passing
terraform geoengineering planetary gardeningtozotero_search_itemsreturned zero, because every term has to match. Searchinggeoengineeringalone returned thirteen items the library had held all along. Check gaps one concept at a time, and confirm a suspected absence withzotero_semantic_searchbefore believing it. - Trade books are invisible to citation databases. Pawlyn and Ichioka's Flourish returns nothing from OpenAlex, so no citation graph exists for it. Practitioner and small-press design books generally fail here. Seed layer 3 from a DOI-bearing neighbour instead.
- Google Scholar has no API. It indexes books and grey literature better than OpenAlex does, and it blocks automated access, so treat it as a manual step rather than an agent step.
- Full text broadens recall and dilutes precision. A passing mention deep inside a 400 page book now competes with a paper devoted to the topic. Fall back to
mode: "keyword"when you want title and abstract precision. - Only two libraries carry a semantic index. The other 14 groups reach layer 1 alone. One index file holds one library, so each additional library needs its own server and data directory.
- Zotero must be running. The setup is local-only with no cloud key, so a closed app fails every layer that touches the library.
Worked Example: Planetary Design Outside the Design Disciplines
Run on 2026-09-05, deliberately phrased to avoid design vocabulary.
| Layer | Result |
|---|---|
| 1. Metadata | 1 item: Pawlyn and Ichioka, Flourish |
| 2. Full text, personal | 10 items, all from PDF bodies: environmental sociology, Earth system governance, ecological economics, environmental humanities, Earth jurisprudence |
| 2. Full text, DDL | 10 items: Rockström's founding planetary boundaries papers, the planetary commons, Chakrabarty on the geological agent, Folke on reconnecting to the biosphere |
| 3. Citation graph | Forward citations of the planetary commons paper land in Earth science, geology, physics and astronomy, and public health. No design venue appears. |
| 4. Undermind | An entirely separate literature: geoengineering, solar radiation management, Earth systems engineering, Earth system governmentality |
| 5. Gap check | Five of the Undermind papers were genuinely new. A conjunctive keyword query wrongly reported the whole topic as absent; a single-term query found thirteen geoengineering items already held. |
The single most useful find was Klosterwill's 'In What Style Should We Terraform? Geoengineering, Planetary Gardening and the Creation of Flourishing Ecologies of Practice', Journal of Landscape Architecture, 2021, which sits precisely on the boundary and carries only two citations. No layer except Undermind surfaced it.
The finding worth acting on is one of connection rather than absence. The library already held geoengineering, Mars planetary engineering and Earth system intervention material, including a paper whose body uses the phrase planetary design directly. That literature sat unread beside Planetary Design because no layer 1 query reached it and because the gap check was posed wrongly. Discovery added five papers; the layered search revealed a dozen more that were already on the shelf.
Reusable Prompt
Paste and edit the topic:
Search my Zotero in layers for TOPIC.
1. mcp__zoteus__zotero_search_items, default qmode, to establish what I hold by title.
2. mcp__zoteus__zotero_semantic_search and mcp__zoteus-ddl__zotero_semantic_search.
Phrase the query in the vocabulary of ADJACENT FIELD rather than my own.
Flag every hit whose source is note or annotation, since those are my words.
3. Take the best DOI-bearing hit and run zotero_scholar citations and references
with include_in_library true.
4. Undermind search_papers with a sample_abstract written as if excerpted from
the paper I wish existed.
5. Check every layer 3 and 4 finding back against my library and tell me only
what I do not already hold.
Do not use zotero_scholar to search my library. It queries the open web.
Rendering References in Chicago 17th
Zoteus renders this correctly as of v1.15.0, so pandoc is no longer needed. Three of the four obvious routes fail, and only one works on a local-only setup.
What does not work. zotero_get_item with include:"bib" accepts a style argument and ignores it: apa and chicago-notes-bibliography-17th-edition return byte-identical output, always Zotero's own default of Chicago 18th, which drops the place of publication. zotero_bibliography and zotero_format_bibliography both refuse with "Access denied (Forbidden)" when given item_keys, because that path exports through the cloud Web API and no key exists here.
What works. Feed CSL-JSON to zotero_format_bibliography inline. That path renders with citeproc-js locally and never touches the cloud:
zotero_get_itemwithinclude:"csljson"returns the record, carryingpublisher-place,pageand the Better BibTeXcitation-keyeven though the rendered bibliography omits them.- Pass that object in the
itemsarray ofzotero_format_bibliography, withstyle: "chicago-notes-bibliography-17th-edition"andformat: "text".
Verified output includes "Cham: Springer, 2021" and the page range, which is the 17th-edition behaviour Dendron notes need.
The style id uses notes plural. The singular form that the CSL repository documents does not match what Zotero installs, and it silently resolves to nothing. Confirm one first with zotero_styles action:"resolve", which now reports available: true where it previously reported false for every style.
Keep the pandoc route for batch work over many items, since the inline path takes one record at a time. Pull CSL-JSON straight from the local API and render against the installed CSL:
KEYS=WKRAVCC5,T68JYSLD,VS5V4M3S
LIB=groups/1795159 # or users/0 for the personal library
CSL="D:/_LOCAL_ONLY/Zotero/styles/chicago-notes-bibliography-17th-edition.csl"
curl -s "http://127.0.0.1:23119/api/$LIB/items?itemKey=$KEYS&format=csljson" > raw.json
node -e "const a=require('./raw.json').filter(x=>x.id&&x['citation-key']);require('fs').writeFileSync('refs.json',JSON.stringify(a))"
printf -- '---
nocite: "@*"
' > stub.md pandoc stub.md --citeproc --bibliography=refs.json --csl="$CSL" -t markdown-citations --wrap=none
The filter matters because a request by item key also returns child attachments and notes, which carry no id and break citeproc.
Related Notes
- Zotero, the Zoteus MCP bridge and its configuration
- Ai, agent tooling more broadly
- Semantic Analysis
- Data Sources
- Planetary Design, the worked example above