zotero-agent 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. zotero_agent-0.2.0/.github/ISSUE_TEMPLATE/bug_report.yml +37 -0
  2. zotero_agent-0.2.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. zotero_agent-0.2.0/.github/ISSUE_TEMPLATE/feature_request.yml +21 -0
  4. zotero_agent-0.2.0/.github/pull_request_template.md +17 -0
  5. zotero_agent-0.2.0/.github/workflows/ci.yml +57 -0
  6. zotero_agent-0.2.0/.github/workflows/pages.yml +68 -0
  7. zotero_agent-0.2.0/.github/workflows/release.yml +44 -0
  8. zotero_agent-0.2.0/.gitignore +26 -0
  9. zotero_agent-0.2.0/AGENTS.md +65 -0
  10. zotero_agent-0.2.0/CHANGELOG.md +60 -0
  11. zotero_agent-0.2.0/CONTRIBUTING.md +43 -0
  12. zotero_agent-0.2.0/LICENSE +21 -0
  13. zotero_agent-0.2.0/PKG-INFO +138 -0
  14. zotero_agent-0.2.0/README.md +112 -0
  15. zotero_agent-0.2.0/SECURITY.md +34 -0
  16. zotero_agent-0.2.0/cli/zot +20 -0
  17. zotero_agent-0.2.0/docs/ai-agents.md +95 -0
  18. zotero_agent-0.2.0/docs/architecture.md +59 -0
  19. zotero_agent-0.2.0/docs/commands.md +430 -0
  20. zotero_agent-0.2.0/docs/install.md +84 -0
  21. zotero_agent-0.2.0/docs/security.md +73 -0
  22. zotero_agent-0.2.0/install.sh +67 -0
  23. zotero_agent-0.2.0/marketing/README.md +64 -0
  24. zotero_agent-0.2.0/marketing/awesome-lists.md +97 -0
  25. zotero_agent-0.2.0/marketing/github-repo-metadata.md +67 -0
  26. zotero_agent-0.2.0/marketing/metrics.md +80 -0
  27. zotero_agent-0.2.0/marketing/reddit-r-zotero.md +44 -0
  28. zotero_agent-0.2.0/marketing/show-hn.md +62 -0
  29. zotero_agent-0.2.0/marketing/zotero-forums-post.md +35 -0
  30. zotero_agent-0.2.0/packaging/homebrew/zotero-agent.rb +30 -0
  31. zotero_agent-0.2.0/plugin/build.sh +28 -0
  32. zotero_agent-0.2.0/plugin/zotero-agent-bridge/bootstrap.js +225 -0
  33. zotero_agent-0.2.0/plugin/zotero-agent-bridge/manifest.json +15 -0
  34. zotero_agent-0.2.0/pyproject.toml +56 -0
  35. zotero_agent-0.2.0/scripts/gen_cli_reference.py +99 -0
  36. zotero_agent-0.2.0/skill/SKILL.md +195 -0
  37. zotero_agent-0.2.0/skill/evals/evals.json +68 -0
  38. zotero_agent-0.2.0/skill/references/pdf-and-notes.md +158 -0
  39. zotero_agent-0.2.0/skill/references/recipes.md +268 -0
  40. zotero_agent-0.2.0/skill/references/setup.md +20 -0
  41. zotero_agent-0.2.0/src/zotero_agent/__init__.py +10 -0
  42. zotero_agent-0.2.0/src/zotero_agent/__main__.py +4 -0
  43. zotero_agent-0.2.0/src/zotero_agent/audit.py +59 -0
  44. zotero_agent-0.2.0/src/zotero_agent/cli.py +217 -0
  45. zotero_agent-0.2.0/src/zotero_agent/commands/__init__.py +5 -0
  46. zotero_agent-0.2.0/src/zotero_agent/commands/admin.py +184 -0
  47. zotero_agent-0.2.0/src/zotero_agent/commands/features.py +394 -0
  48. zotero_agent-0.2.0/src/zotero_agent/commands/read.py +392 -0
  49. zotero_agent-0.2.0/src/zotero_agent/commands/write.py +218 -0
  50. zotero_agent-0.2.0/src/zotero_agent/config.py +73 -0
  51. zotero_agent-0.2.0/src/zotero_agent/constants.py +26 -0
  52. zotero_agent-0.2.0/src/zotero_agent/http.py +200 -0
  53. zotero_agent-0.2.0/src/zotero_agent/jslib.py +131 -0
  54. zotero_agent-0.2.0/src/zotero_agent/mcp_server.py +187 -0
  55. zotero_agent-0.2.0/src/zotero_agent/output.py +47 -0
  56. zotero_agent-0.2.0/src/zotero_agent/resolve.py +32 -0
  57. zotero_agent-0.2.0/src/zotero_agent/term.py +61 -0
  58. zotero_agent-0.2.0/tests/fake_zotero.py +95 -0
  59. zotero_agent-0.2.0/tests/test_zot.py +181 -0
  60. zotero_agent-0.2.0/updates.json +18 -0
  61. zotero_agent-0.2.0/web/.gitignore +15 -0
  62. zotero_agent-0.2.0/web/README.md +46 -0
  63. zotero_agent-0.2.0/web/astro.config.mjs +80 -0
  64. zotero_agent-0.2.0/web/package.json +18 -0
  65. zotero_agent-0.2.0/web/pnpm-lock.yaml +4403 -0
  66. zotero_agent-0.2.0/web/pnpm-workspace.yaml +4 -0
  67. zotero_agent-0.2.0/web/public/favicon.svg +4 -0
  68. zotero_agent-0.2.0/web/src/content/docs/ai-agents/claude-code.md +37 -0
  69. zotero_agent-0.2.0/web/src/content/docs/ai-agents/codex-cli.md +31 -0
  70. zotero_agent-0.2.0/web/src/content/docs/ai-agents/cursor.md +26 -0
  71. zotero_agent-0.2.0/web/src/content/docs/ai-agents/gemini-cli.md +30 -0
  72. zotero_agent-0.2.0/web/src/content/docs/ai-agents/mcp.md +66 -0
  73. zotero_agent-0.2.0/web/src/content/docs/architecture.md +70 -0
  74. zotero_agent-0.2.0/web/src/content/docs/compare.md +56 -0
  75. zotero_agent-0.2.0/web/src/content/docs/cookbook/bulk-tag-by-topic.md +62 -0
  76. zotero_agent-0.2.0/web/src/content/docs/cookbook/clean-500-items.md +62 -0
  77. zotero_agent-0.2.0/web/src/content/docs/cookbook/dedupe-and-merge.md +57 -0
  78. zotero_agent-0.2.0/web/src/content/docs/cookbook/find-missing-metadata.md +54 -0
  79. zotero_agent-0.2.0/web/src/content/docs/cookbook/import-by-identifier.md +46 -0
  80. zotero_agent-0.2.0/web/src/content/docs/cookbook/index.md +31 -0
  81. zotero_agent-0.2.0/web/src/content/docs/cookbook/summarize-pdf-to-note.md +51 -0
  82. zotero_agent-0.2.0/web/src/content/docs/faq.md +74 -0
  83. zotero_agent-0.2.0/web/src/content/docs/getting-started/install.md +100 -0
  84. zotero_agent-0.2.0/web/src/content/docs/getting-started/quickstart-agent.md +79 -0
  85. zotero_agent-0.2.0/web/src/content/docs/getting-started/quickstart-cli.md +102 -0
  86. zotero_agent-0.2.0/web/src/content/docs/index.mdx +99 -0
  87. zotero_agent-0.2.0/web/src/content/docs/reference/commands.md +94 -0
  88. zotero_agent-0.2.0/web/src/content/docs/reference/configuration.md +74 -0
  89. zotero_agent-0.2.0/web/src/content/docs/reference/zot-exec-js.md +204 -0
  90. zotero_agent-0.2.0/web/src/content/docs/security.md +72 -0
  91. zotero_agent-0.2.0/web/src/content.config.ts +7 -0
  92. zotero_agent-0.2.0/web/tsconfig.json +5 -0
@@ -0,0 +1,37 @@
1
+ name: Bug report
2
+ description: Something isn't working
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: Thanks for the report! Please include the diagnostics below — they resolve most issues quickly.
8
+ - type: textarea
9
+ id: ping
10
+ attributes:
11
+ label: Output of `zot ping`
12
+ description: Run `zot ping` and paste the full output.
13
+ render: text
14
+ validations:
15
+ required: true
16
+ - type: input
17
+ id: version
18
+ attributes:
19
+ label: Version
20
+ description: Output of `zot --version`
21
+ placeholder: zot (zotero-agent) 0.2.0
22
+ validations:
23
+ required: true
24
+ - type: input
25
+ id: platform
26
+ attributes:
27
+ label: Platform + Zotero version
28
+ placeholder: macOS 14 / Zotero 7.0.15
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: what
33
+ attributes:
34
+ label: What happened
35
+ description: What you did (the exact command or agent prompt), what you expected, and what happened instead.
36
+ validations:
37
+ required: true
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security vulnerability
4
+ url: https://github.com/alex-roc/zotero-agent/security/advisories/new
5
+ about: Please report security issues privately, not as a public issue.
6
+ - name: Question / discussion
7
+ url: https://github.com/alex-roc/zotero-agent/discussions
8
+ about: Ask a question or share how you use zotero-agent.
@@ -0,0 +1,21 @@
1
+ name: Feature request
2
+ description: Suggest an idea or a new command/tool
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: The problem / use case
9
+ description: What are you trying to do with your Zotero library that's hard today?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: idea
14
+ attributes:
15
+ label: Proposed solution
16
+ description: A command, MCP tool, or behaviour you have in mind (rough is fine).
17
+ - type: dropdown
18
+ id: surface
19
+ attributes:
20
+ label: Which surface?
21
+ options: ["CLI", "MCP server", "Claude Code skill", "the bridge plugin", "not sure"]
@@ -0,0 +1,17 @@
1
+ <!-- Thanks for contributing! Keep the core stdlib-only and writes guarded. -->
2
+
3
+ ## What & why
4
+
5
+ <!-- What does this change and what problem does it solve? -->
6
+
7
+ ## How I verified
8
+
9
+ - [ ] `python -m unittest discover -s tests` passes
10
+ - [ ] `uvx ruff check src tests cli/zot` is clean
11
+ - [ ] Rebuilt the XPI (`bash plugin/build.sh`) if the plugin changed
12
+ - [ ] Updated `docs/` / `skill/` / `CHANGELOG.md` (Unreleased) if behaviour changed
13
+ - [ ] (If a live test was relevant) ran `zot ping` / the affected command against a real library
14
+
15
+ ## Notes
16
+
17
+ <!-- Anything reviewers should know: trade-offs, follow-ups, screenshots. -->
@@ -0,0 +1,57 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.9", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - name: Run tests (stdlib only, no network)
20
+ run: python -m unittest discover -s tests -v
21
+
22
+ lint:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: astral-sh/ruff-action@v3
27
+ with:
28
+ args: check src tests cli/zot
29
+
30
+ build-xpi:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - uses: actions/setup-python@v5
35
+ with:
36
+ python-version: "3.13"
37
+ - name: Build the bridge XPI
38
+ run: bash plugin/build.sh
39
+ - name: Verify the XPI is a valid zip with a manifest
40
+ run: |
41
+ unzip -l dist/zotero-agent-bridge.xpi | grep -q manifest.json
42
+ - uses: actions/upload-artifact@v4
43
+ with:
44
+ name: zotero-agent-bridge-xpi
45
+ path: dist/zotero-agent-bridge-*.xpi
46
+
47
+ build-package:
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+ - uses: astral-sh/setup-uv@v5
52
+ - name: Build wheel + sdist
53
+ run: uv build
54
+ - uses: actions/upload-artifact@v4
55
+ with:
56
+ name: dist
57
+ path: dist/*.whl
@@ -0,0 +1,68 @@
1
+ name: Deploy docs to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'web/**'
8
+ - '.github/workflows/pages.yml'
9
+ workflow_dispatch:
10
+
11
+ # Allow the GITHUB_TOKEN to deploy to Pages.
12
+ permissions:
13
+ contents: read
14
+ pages: write
15
+ id-token: write
16
+
17
+ # Allow one concurrent deployment; don't cancel in-progress production deploys.
18
+ concurrency:
19
+ group: pages
20
+ cancel-in-progress: false
21
+
22
+ defaults:
23
+ run:
24
+ working-directory: web
25
+
26
+ jobs:
27
+ build:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - name: Checkout
31
+ uses: actions/checkout@v4
32
+
33
+ - name: Install pnpm
34
+ uses: pnpm/action-setup@v4
35
+ with:
36
+ version: 11
37
+
38
+ - name: Setup Node
39
+ uses: actions/setup-node@v4
40
+ with:
41
+ node-version: 22
42
+ cache: pnpm
43
+ cache-dependency-path: web/pnpm-lock.yaml
44
+
45
+ - name: Install dependencies
46
+ run: pnpm install --frozen-lockfile
47
+
48
+ - name: Build with Astro
49
+ run: pnpm build
50
+
51
+ - name: Configure Pages
52
+ uses: actions/configure-pages@v5
53
+
54
+ - name: Upload artifact
55
+ uses: actions/upload-pages-artifact@v3
56
+ with:
57
+ path: web/dist
58
+
59
+ deploy:
60
+ needs: build
61
+ runs-on: ubuntu-latest
62
+ environment:
63
+ name: github-pages
64
+ url: ${{ steps.deployment.outputs.page_url }}
65
+ steps:
66
+ - name: Deploy to GitHub Pages
67
+ id: deployment
68
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,44 @@
1
+ name: Release
2
+
3
+ # Tag a version (vX.Y.Z) to build the XPI + wheel, publish a GitHub Release with
4
+ # the XPI attached, and publish the package to PyPI via Trusted Publishing.
5
+ #
6
+ # One-time setup on pypi.org: add a Trusted Publisher for this repo + workflow
7
+ # (Publishing → Add a new pending publisher) so no API token is needed here.
8
+
9
+ on:
10
+ push:
11
+ tags: ["v*"]
12
+
13
+ permissions:
14
+ contents: write # create the GitHub Release
15
+ id-token: write # PyPI Trusted Publishing (OIDC)
16
+
17
+ jobs:
18
+ release:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: astral-sh/setup-uv@v5
24
+ - name: Build wheel + sdist (into dist/)
25
+ run: uv build
26
+
27
+ - name: Build the bridge XPI (into release-assets/, keeping dist/ PyPI-only)
28
+ run: |
29
+ bash plugin/build.sh
30
+ mkdir -p release-assets
31
+ mv dist/zotero-agent-bridge-*.xpi release-assets/
32
+ rm -f dist/zotero-agent-bridge.xpi # drop the symlink so dist/ is PyPI-only
33
+
34
+ - name: Create GitHub Release with the XPI
35
+ uses: softprops/action-gh-release@v2
36
+ with:
37
+ files: release-assets/zotero-agent-bridge-*.xpi
38
+ generate_release_notes: true
39
+
40
+ - name: Publish to PyPI (Trusted Publishing)
41
+ uses: pypa/gh-action-pypi-publish@release/v1
42
+ with:
43
+ packages-dir: dist # wheel + sdist only
44
+ verbose: true
@@ -0,0 +1,26 @@
1
+ # Built artifacts (produced by plugin/build.sh)
2
+ /dist/
3
+
4
+ # Self-contained skill bundle (produced by install.sh from cli/ and plugin/)
5
+ /skill/scripts/
6
+
7
+ # OS / editor cruft
8
+ .DS_Store
9
+ *.swp
10
+
11
+ # Python
12
+ __pycache__/
13
+ *.pyc
14
+ *.egg-info/
15
+ .venv/
16
+
17
+ # Website (Astro Starlight)
18
+ /web/node_modules/
19
+ /web/dist/
20
+ /web/.astro/
21
+
22
+ # Release scratch
23
+ /release-assets/
24
+
25
+ # skill-creator eval workspace (artefactos + backup)
26
+ /zotero-workspace/
@@ -0,0 +1,65 @@
1
+ # AGENTS.md — driving Zotero with the `zot` CLI
2
+
3
+ This file gives coding/agent tools (Codex CLI, Gemini CLI, Aider, and any agent
4
+ that reads `AGENTS.md`) what they need to control a **local Zotero library**
5
+ through the `zot` command. It mirrors the Claude Code skill in `skill/SKILL.md`.
6
+
7
+ ## Setup check
8
+
9
+ Run `zot ping`. It must show the local API up, the bridge endpoint answering
10
+ `1+1 == 2`, and a known userID. If it fails, the bridge plugin isn't installed —
11
+ see `docs/install.md`; do **not** work around it.
12
+
13
+ ## Reading (fast, prefer these)
14
+
15
+ ```bash
16
+ zot search "<query>" [--limit N] [--tag T] [--item-type book] # full-text
17
+ zot get <KEY|@citekey> # one item's fields
18
+ zot pdf <KEY|@citekey> # local PDF path(s) — then read the file directly
19
+ zot collections | zot tags # list
20
+ zot stats # analytics
21
+ zot missing abstract|date|doi [--collection C]
22
+ zot author "<name>" | zot recent | zot lint
23
+ ```
24
+
25
+ Add `--json` to any command for machine-readable output.
26
+
27
+ ## Writing (guarded — pass `--yes` for non-interactive)
28
+
29
+ ```bash
30
+ zot add doi|isbn|arxiv <id> [--pdf] [--collection C]
31
+ zot set <field> <value> <KEY…> --yes
32
+ zot tag add|rm <tag> <KEY…> --yes | zot tag rename <old> --new <n> --yes
33
+ zot move <collection> <KEY…> --yes
34
+ zot note <KEY> --file note.html
35
+ zot dedupe [--by title|doi] [--fuzzy] [--merge --yes]
36
+ ```
37
+
38
+ ## Batch edits (preferred for anything at scale — undoable)
39
+
40
+ Write a JSONL file, one edit per line, then apply it:
41
+
42
+ ```jsonl
43
+ {"key":"ABCD1234","set":{"abstract":"…","date":"2021"},"addTags":["review"]}
44
+ {"key":"EFGH5678","addToCollection":"To Read","removeTags":["old"]}
45
+ ```
46
+
47
+ ```bash
48
+ zot apply edits.jsonl --dry-run # preview
49
+ zot apply edits.jsonl # apply (snapshots first)
50
+ zot undo last # roll back the last apply/enrich
51
+ ```
52
+
53
+ **You** decide the values (e.g. cleaned titles, topic tags) and write the JSONL;
54
+ `zot` performs the writes. The CLI never calls an LLM itself.
55
+
56
+ ## Safety rules (follow these)
57
+
58
+ 1. `zot backup` before any bulk or destructive change — always before `dedupe --merge`.
59
+ 2. Prefer `--dry-run` and scope with `--collection` before touching the whole library.
60
+ 3. Apply to 1–2 items and verify before the full set.
61
+ 4. Deletions: prefer trash (`"trash": true` in `apply`), not permanent erase.
62
+ 5. Merges are **not** reversible; everything via `zot apply`/`zot enrich` is.
63
+
64
+ Full JS recipe book: `skill/references/recipes.md`. PDF/notes workflow:
65
+ `skill/references/pdf-and-notes.md`.
@@ -0,0 +1,60 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Fixed
10
+ - **`apply`/`update_items` dry-run no longer executes any JS**, so it can never
11
+ persist changes (the old monkey-patch-`save()` interception could leak writes
12
+ on Zotero 7). The preview is reported straight from the parsed edits.
13
+ - `dedupe --fuzzy` is now tractable on large libraries (prefix-blocking instead
14
+ of O(n²) over the whole library) — seconds instead of timing out.
15
+ - Bridge/read calls that time out now return a clean error instead of an
16
+ uncaught traceback (`post_code` and `main` handle `TimeoutError`/`OSError`).
17
+ - `exec --dry-run` now states honestly that it executes the script with
18
+ best-effort interception and may still persist (backup is the guarantee).
19
+
20
+ ## [0.2.0] — 2026-07-23
21
+
22
+ The project was renamed from `zotero-cli-skill` to **`zotero-agent`** and rebuilt
23
+ into an installable Python package with an MCP server.
24
+
25
+ ### Added
26
+ - **Python package** `zotero-agent` (installable from PyPI; entry point `zot`).
27
+ The former single-file CLI is now a modular package under `src/zotero_agent/`.
28
+ - **MCP server** (`zot mcp`) exposing ~18 high-level tools to any Model Context
29
+ Protocol client (Claude Desktop, Codex CLI, Gemini CLI, Cursor). Optional
30
+ `[mcp]` extra.
31
+ - **`zot apply`** — declarative JSONL batch edits (set fields / add-remove tags /
32
+ add to collection / trash), with a pre-image snapshot.
33
+ - **`zot undo`** — restore items to their state before an `apply`/`enrich`.
34
+ - **`zot enrich`** — fill missing DOI / date / abstract from Crossref or OpenAlex.
35
+ - **`zot tag normalize`** — fold case- and whitespace-variant tags together.
36
+ - **`zot dedupe --fuzzy`** — group near-identical titles (Levenshtein).
37
+ - **Audit log** of every bridge execution at `~/.local/state/zotero-agent/audit.jsonl`.
38
+ - `--version` flag; `--json` is now a global flag on every command.
39
+ - Fake-Zotero test server; expanded unit + integration tests. CI on GitHub Actions.
40
+
41
+ ### Changed
42
+ - **Rebranding:** endpoint `POST /zotexec` → `POST /zotero-agent`; token header
43
+ `X-Zotexec-Token` → `X-Zotero-Agent-Token`; pref `extensions.zotexec.token` →
44
+ `extensions.zotero-agent.token`; config dir `~/.config/zotero-exec` →
45
+ `~/.config/zotero-agent`; env `ZOTEXEC_*` → `ZOTERO_AGENT_*`; plugin →
46
+ "Zotero Agent Bridge" (`zotero-agent-bridge-<version>.xpi`).
47
+ - `export`/`bib` no longer silently truncate large collections (paginate fully).
48
+ - Minimum Python is now 3.9.
49
+
50
+ ### Migration
51
+ Single-user project, no back-compat shim: reinstall the bridge XPI and run
52
+ `zot init` to regenerate `~/.config/zotero-agent/config.json`.
53
+
54
+ ## [0.1.0] — 2026-07-23
55
+ - Initial release as `zotero-cli-skill`: `zotexec` plugin + `zot` CLI + Claude
56
+ Code skill.
57
+
58
+ [Unreleased]: https://github.com/alex-roc/zotero-agent/compare/v0.2.0...HEAD
59
+ [0.2.0]: https://github.com/alex-roc/zotero-agent/releases/tag/v0.2.0
60
+ [0.1.0]: https://github.com/alex-roc/zotero-agent/releases/tag/v0.1.0
@@ -0,0 +1,43 @@
1
+ # Contributing to zotero-agent
2
+
3
+ Thanks for your interest! This is a small, focused project — a CLI + MCP server +
4
+ Zotero bridge plugin for **local** library control. Contributions that keep it
5
+ simple, safe, and dependency-light are very welcome.
6
+
7
+ ## Ground rules
8
+
9
+ - **Core stays stdlib-only.** The `zotero_agent` core must not add runtime
10
+ dependencies. Anything heavier goes behind an optional extra (like `[mcp]`).
11
+ - **Writes are guarded.** New write commands must respect `confirm_write` (refuse
12
+ non-interactive runs without `--yes`) and, where sensible, support `--dry-run`
13
+ and snapshot for `zot undo`.
14
+ - **Behaviour parity.** MCP tools reuse the CLI command functions — don't fork the
15
+ logic.
16
+
17
+ ## Dev setup
18
+
19
+ ```bash
20
+ git clone https://github.com/alex-roc/zotero-agent.git && cd zotero-agent
21
+ ./install.sh # dev shim on PATH + skill + XPI
22
+ python3 -m unittest discover -s tests # tests (no network, no live Zotero)
23
+ uvx ruff check src tests # lint
24
+ uv build # build wheel + sdist
25
+ ```
26
+
27
+ The tests use a fake in-process Zotero server (`tests/fake_zotero.py`), so they
28
+ run without Zotero. For a real end-to-end check against your own library, set
29
+ `ZOT_LIVE=1` and run `zot ping` with Zotero open.
30
+
31
+ ## Making a change
32
+
33
+ 1. Branch from `main`.
34
+ 2. Keep commits focused; update `docs/`, the `skill/`, and `CHANGELOG.md` when you
35
+ change behaviour (see the "Unreleased" section).
36
+ 3. Run tests + ruff. Rebuild the XPI (`bash plugin/build.sh`) if you touched the
37
+ plugin.
38
+ 4. Open a PR describing what changed and how you verified it.
39
+
40
+ ## Reporting bugs / requesting features
41
+
42
+ Use the issue templates. For bugs, include the output of `zot ping` and
43
+ `zot --version`. For anything security-related, see [`SECURITY.md`](SECURITY.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zotero-cli-skill contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: zotero-agent
3
+ Version: 0.2.0
4
+ Summary: Local read-write control of a Zotero library — from your terminal or your AI agent. No cloud, no API key.
5
+ Project-URL: Homepage, https://github.com/alex-roc/zotero-agent
6
+ Project-URL: Documentation, https://alex-roc.github.io/zotero-agent
7
+ Project-URL: Repository, https://github.com/alex-roc/zotero-agent
8
+ Project-URL: Issues, https://github.com/alex-roc/zotero-agent/issues
9
+ Author: Alex Ojeda Copa
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai-agent,bibliography,cli,local-first,mcp,reference-manager,zotero
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Topic :: Text Processing :: Markup
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.9
21
+ Provides-Extra: dev
22
+ Requires-Dist: ruff>=0.6; extra == 'dev'
23
+ Provides-Extra: mcp
24
+ Requires-Dist: mcp>=1.2.0; extra == 'mcp'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # zotero-agent
28
+
29
+ **Full local control of your Zotero library — from your terminal or your AI agent. No cloud, no API key.**
30
+
31
+ `zot` is a CLI and AI-agent toolkit that gives you full **read-write** control of
32
+ your *local* Zotero library: search, bulk-edit metadata, tag, deduplicate, import
33
+ by DOI/ISBN/arXiv, export, and summarize PDFs into notes. Zotero's local API is
34
+ read-only, so writes go through a tiny plugin exposing a single token-protected
35
+ endpoint, with a documented [three-layer security model](docs/security.md). No
36
+ zotero.org account, no API key, no cloud — **your library never leaves your machine.**
37
+
38
+ ```
39
+ Agent / user → [ MCP server | agent skill | zot CLI ] ─┬─ read → Zotero local API /api/… (GET, fast)
40
+ └─ write → POST /zotero-agent (bridge plugin, JS)
41
+ ```
42
+
43
+ ## Why this exists
44
+
45
+ The dominant Zotero automation tools (zotero-mcp, pyzotero) can only *write* via
46
+ the zotero.org web API — which needs an account, an API key and sync. Zotero's
47
+ **local** HTTP API returns `501` on every write. The only way to write locally is
48
+ a plugin, and that is exactly what the `zotero-agent` bridge is. That makes this
49
+ the local-first, offline, private option: batch metadata edits, real dedup, and
50
+ tag cleanup that people have asked Zotero for [since 2016](https://forums.zotero.org/discussion/111815/feature-batch-editing-metadata-for-multiple-items) — done on your own machine.
51
+
52
+ ## Three ways to use it
53
+
54
+ - **AI agents via MCP** — `zot mcp` is a Model Context Protocol server for Claude
55
+ Desktop, **Codex CLI**, **Gemini CLI**, Cursor, and any MCP client. See
56
+ [`docs/ai-agents.md`](docs/ai-agents.md).
57
+ - **Claude Code skill** — the `zotero` skill drives `zot` with a safe workflow.
58
+ - **Plain CLI** — script it in bash, pipe it, put it in a Makefile.
59
+
60
+ ## What's inside
61
+
62
+ | Path | What |
63
+ |------|------|
64
+ | `src/zotero_agent/` | The Python package: CLI, command modules, JS builders, MCP server. Stdlib-only core. |
65
+ | `plugin/zotero-agent-bridge/` | The write endpoint (`POST /zotero-agent`), token-protected, ~200 lines. |
66
+ | `skill/` | The `zotero` skill for Claude Code (SKILL.md + recipe book + evals). |
67
+ | `docs/` | Install, security model, architecture, AI-agent setup. |
68
+ | `web/` | The documentation site (Astro Starlight → GitHub Pages). |
69
+
70
+ ## Install
71
+
72
+ ```bash
73
+ # CLI (+ optional MCP server):
74
+ uv tool install zotero-agent # or: pipx install zotero-agent
75
+ uv tool install "zotero-agent[mcp]" # include the MCP server
76
+
77
+ # then install the bridge plugin in Zotero:
78
+ # Tools → Plugins → gear → "Install Plugin From File" → the .xpi from Releases
79
+ zot init # generates a token, writes config, auto-detects your userID
80
+ zot ping # verify: local API up, bridge answering, userID known
81
+ ```
82
+
83
+ From a checkout, `./install.sh` wires up the skill, a dev `zot`, and builds the
84
+ XPI. Full instructions: [`docs/install.md`](docs/install.md).
85
+
86
+ ## Using the CLI
87
+
88
+ ```bash
89
+ zot search "bolivia" --limit 10 # read (fast API)
90
+ zot get ABCD1234 # one item (Zotero key or BBT citekey)
91
+ zot missing abstract --collection SS5MVVB6 # items lacking a field
92
+ zot stats # library analytics
93
+ zot add doi 10.1371/journal.pmed.0020124 --pdf # import by identifier (+ OA PDF)
94
+ zot dedupe --by title --fuzzy # find near-duplicate titles
95
+ zot dedupe --merge --yes # merge duplicates (oldest = master)
96
+ zot enrich --field doi --dry-run # fill missing DOIs from Crossref
97
+ zot apply edits.jsonl # declarative batch edit (undoable)
98
+ zot undo last # roll it back
99
+ zot tag normalize --dry-run # fold case/space tag variants
100
+ zot export "My Collection" --format bibtex --out refs.bib
101
+ zot exec 'return Zotero.version;' # escape hatch: run privileged JS
102
+ ```
103
+
104
+ Add `--json` to any command for machine-readable output. Writes refuse to run
105
+ non-interactively without `--yes`. The canonical JS recipe book is
106
+ [`skill/references/recipes.md`](skill/references/recipes.md).
107
+
108
+ ## Using with an AI agent
109
+
110
+ Ask *"tag every abstract-less item #review and merge duplicate titles in
111
+ collection X"*, *"fill in missing DOIs"*, or *"summarize this paper's PDF chapter
112
+ by chapter and save it as a note"*. The agent drives `zot` and follows a safe
113
+ workflow (backup → sync-off → dry-run → small batch) for bulk or destructive edits.
114
+ Batch edits are **undoable** (`zot undo`).
115
+
116
+ ## Requirements
117
+
118
+ - Zotero 7+ (tested through 9.x) running, local API enabled (default).
119
+ - Python 3.9+ (stdlib-only core; the MCP server needs the `[mcp]` extra).
120
+ - macOS and Linux; Windows paths are noted in `docs/install.md`.
121
+
122
+ ## Security
123
+
124
+ Arbitrary local JS execution, gated by a required token + browser-origin
125
+ rejection + loopback binding, with an append-only audit log. This is a deliberate
126
+ capability; read [`docs/security.md`](docs/security.md) before installing.
127
+ License: [MIT](LICENSE).
128
+
129
+ ## Development
130
+
131
+ ```bash
132
+ python3 -m unittest discover -s tests # unit + fake-server tests (no network, no Zotero)
133
+ uvx ruff check src tests # lint
134
+ uv build # build wheel + sdist
135
+ bash plugin/build.sh # rebuild the bridge XPI
136
+ ```
137
+
138
+ See [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`CHANGELOG.md`](CHANGELOG.md).