NRT Agentic AI Michigan State University

DEMO 11 · ADVANCED — A BIBLIOGRAPHY THAT CHECKS ITSELF

Zotero

A bibliography is a set of promises: that each work exists, that it says what you say it says, and that it is where you say it is. Which of those can an agent check, and which can only you?

Download Demo 11  ↓ ← Demo 10 All demos

← Back to all demos

Looking for the step-by-step? This page explains why the demo is shaped the way it is. The handbook is the manual — prerequisites with verification commands, the full annotated file map, what every file does, how information flows, and the daily, weekly and monthly routines for keeping it running. The package itself also ships SETUP.md (step by step) and MAINTENANCE.md (how to live with it).

Package:

Demo11_zotero_bibliography.zip · 540 KB · 30–40 minutes

Three corrections to the usual tutorial

There is a widely shared seven-step guide to connecting Zotero to Claude Code. It works. Three of its steps are worth questioning before you follow them.

1. You probably do not want the web API. The usual instructions have you create a Zotero API key, paste it into .mcp.json, and reach your library through api.zotero.org. Zotero has had a local API since version 7 — Settings → Advanced → “Allow other applications on this computer to communicate with Zotero” — at http://localhost:23119/api/, with no key at all. zotero-mcp reaches it with one line: "env": {"ZOTERO_LOCAL": "true"}. Nothing leaves the machine, and there is no password-equivalent string to leak into a config file, a screenshot or a repository.

2. The MCP server cannot organise your library. zotero-mcp exposes exactly three tools: search items, get metadata, get full text. All three are reads. There is no tool to add a tag, create a collection, fix a year or merge a duplicate.

Worth knowing alongside this: the web API is free — no paid tier, no request quota. But zotero_item_fulltext only works on PDFs synced to Zotero’s servers, and file storage is metered at 300 MB free, then $20–$120 a year. Past the quota the API can tell you a paper exists and not give you its text. Local reads your disk, at full size, for nothing.

So “use an agent to manage my Zotero library” resolves into something more modest and more correct: the agent reads the library and writes files beside it. You apply changes in Zotero. That keeps a human between an agent and ten years of references, which is where a human belongs.

3. You need none of it to start. A Zotero library on disk is a .bib export, a .csv export, and a storage/ folder of PDFs. That is what this demo uses — no account, no key, no MCP, no Zotero installed, works offline. The live route is an appendix, for afterwards.

The library

Nine entries. Six attachment folders. That gap is the demo.

The three views of this library — the .bib, the .csv and storage/ — disagree in five places, and every disagreement is something that happens to a real library through ordinary use:

The orphaned folder is the one that matters. It holds the supplementary information for the paper the whole topic turns on, and in it the authors report their own method at 8.0 °C on proteins it has not seen, against the 4.9 in the abstract. Every bibliography built from the .bib misses it, because the .bib does not know it exists.

The deny list is the lesson

"deny": [
  "Edit(./storage/**)",      "Write(./storage/**)",
  "Edit(./My Library.bib)",  "Write(./My Library.bib)",
  "Edit(./My Library.csv)",  "Write(./My Library.csv)",
  "Bash(rm:*)",
  "Bash(mv:*)"
]

The library is read-only and the agent cannot talk its way out of it. Not a polite request in CLAUDE.md — a rule checked before the tool runs. Output goes to bib/; you apply changes in Zotero yourself.

Bash(mv:*) is denied for a specific reason. Without it, “tidy up storage/” is one plausible command away from a library whose every attachment has stopped resolving — and Zotero will not tell you until you click one.

Six prompts

  1. Audit first. “Reconcile the .bib, the .csv and storage/. Report every place they disagree. Change nothing.” Five disagreements. Searching before auditing means never finding the orphan.
  2. Search. scout looks for everything bearing on one question — does sequence-only prediction beat a trivial baseline on proteins the model has not seen? It cannot be answered from titles.
  3. Build. A bibliography into bib/, every entry traced to a file in storage/ or explicitly marked [metadata only — not read].
  4. Check its homework. citecheck has no Write tool. For every factual claim in every annotation it finds the claim in the PDF, or says it cannot. It can report that a citation is wrong; it cannot make the problem disappear.
  5. Three sentences you could put in a paper, each citing an item key. If they come out hedged and short, the library did its job.
  6. The review outline, and the test nobody runs. Ask for the eight-section outline everyone asks for — then ask which of these sections could you have written without my library?

The sixth prompt is the one that matters

Every guide to this subject ends at “and then it wrote me a literature review.” Look closely at what those outlines contain: Introduction · Mechanisms · Global distribution · Methods · Open problems. That is the generic structure of a review in almost any field. A model can produce it from training data alone — no library, no PDFs, no Zotero. The output looks identical whether it read your library or recalled the field, and you cannot tell by reading it.

The item key settles it. 4J8KQW2M is an eight-character string that exists only in your library. It cannot be recalled from training; it can only be read. Either the agent names one and you can check it, or it cannot.

On the library as shipped, an eight-section outline comes back three sections grounded, one hollow, four generic:

A run that marks nothing as generic has failed this prompt. Not because the outline is wrong, but because it is claiming library support it does not have — the same error as the paywalled abstract in Demo 10, one level up.

The last part of the template is the part worth keeping: sections this library cannot support. That is a reading list, and it is the only output in either demo that tells you what to go and do next.

The defect nothing catches

The journal article entered as @book is well-formed, internally consistent, and wrong. No layer in this package finds it: not the contract, not the permissions, not the verifier. The person who notices is the one who has had a reference list come back from a copy editor.

That is the honest end of the sequence the course has been building. Prose asks, permissions enforce, a missing tool removes the option — and some things are still only caught by someone who knows what the output is supposed to look like.

Pairs with Demo 10

Same literature, deliberately. Demo 10 is the notes — what you thought about what you read. Demo 11 is the library — what you have, and whether you can cite it. Together they are the shape worth copying: Zotero holds the PDFs, an Obsidian vault holds the thinking, and the agent reads both and writes only to the vault.

What is verified and what is not. The library is verified: the .bib parses, every planted defect was checked mechanically, the broken path really is broken, the orphan really is unreferenced, and the metadata/PDF mismatch is real in both directions. The agent’s behaviour was not measured — assembled without Claude Code available, so the expectations here are predictions. The documents are synthetic; the papers, authors, journals and DOIs do not exist. Do not cite anything in the package.