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

LayerToolQuestion it answersScope
1. Metadatazotero_search_items, default qmodeWhat do I hold with this in the title?All 17 libraries
2. Full text and own wordszotero_semantic_searchWhat sits inside my PDFs, notes and annotations?Personal and Deep Design Lab only
3. Citation graphzotero_scholar, or the OpenAlex APIWho does this build on, and who took it up?Open scholarly web, DOI required
4. DiscoveryUndermind search_papers, launch_deep_searchWhat exists that I have never seen?Global corpus
5. Gap checkLayer 1 and 2 again, on layer 3 and 4 findingsWhich 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 gardening to zotero_search_items returned zero, because every term has to match. Searching geoengineering alone returned thirteen items the library had held all along. Check gaps one concept at a time, and confirm a suspected absence with zotero_semantic_search before 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.

LayerResult
1. Metadata1 item: Pawlyn and Ichioka, Flourish
2. Full text, personal10 items, all from PDF bodies: environmental sociology, Earth system governance, ecological economics, environmental humanities, Earth jurisprudence
2. Full text, DDL10 items: Rockström's founding planetary boundaries papers, the planetary commons, Chakrabarty on the geological agent, Folke on reconnecting to the biosphere
3. Citation graphForward citations of the planetary commons paper land in Earth science, geology, physics and astronomy, and public health. No design venue appears.
4. UndermindAn entirely separate literature: geoengineering, solar radiation management, Earth systems engineering, Earth system governmentality
5. Gap checkFive 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:

  1. zotero_get_item with include:"csljson" returns the record, carrying publisher-place, page and the Better BibTeX citation-key even though the rendered bibliography omits them.
  2. Pass that object in the items array of zotero_format_bibliography, with style: "chicago-notes-bibliography-17th-edition" and format: "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.