{"slug": "show-hn-mktero-a-source-linked-markdown-reader-for-zotero", "title": "Show HN: Mktero – a source-linked Markdown reader for Zotero", "summary": "Mktero, a new open-source Zotero extension for Zotero 7 through 10, converts local PDFs into source-linked Markdown using MinerU's API, with features like citation preview, annotation editing, and AI translation. The beta extension requires a MinerU API token and uploads complete PDFs on cache misses, raising privacy considerations for sensitive documents.", "body_md": "**English** · [简体中文](/tenglvjun/mktero/blob/main/README.zh-CN.md)\n\n**Read Zotero PDFs as source-linked Markdown.**\n\nMktero is a restartless Zotero extension for Zotero 7, 8, 9, and 10. It sends a\nlocal PDF to [MinerU](https://mineru.net/) when needed, then opens the\nresulting Markdown, formulas, tables, figures, citations, and annotations in a\ntemporary, reading-first Zotero tab. A content-addressed local cache avoids\nrepeating conversions for the same PDF.\n\nImportant\n\nMktero is in beta. On a cache miss, the complete PDF is uploaded to MinerU,\nso a MinerU API Token is required. Optional AI translation sends protected\nMarkdown batches to the provider configured by you. Review [Privacy and data\nhandling](#privacy-and-data-handling) before processing sensitive documents.\n\nUseful links: [Product page](https://tenglvjun.github.io/mktero/) ·\n[Download](https://github.com/tenglvjun/mktero/releases/latest) ·\n[Discussions](https://github.com/tenglvjun/mktero/discussions) ·\n[Issues](https://github.com/tenglvjun/mktero/issues)\n\n- Reflow OCR output, multi-column text, formulas, tables, figures, lists, and code into a continuous academic reading document.\n- Keep reliable page and region mappings so text, formulas, tables, and figures can jump back to their PDF source.\n- Preview citations, author affiliations, figures, and tables without losing the current reading position.\n- See whether each Markdown reference already exists in any accessible Zotero library. Choose a writable personal or group library, explicitly copy a reference from another library, review local/online metadata matches for title-only references, and import missing metadata from the citation popup with an optional public PDF attachment.\n- Display Zotero PDF highlights and underlines in Markdown, and create, recolor, comment on, or delete annotations.\n- Correct recognition errors in existing paragraphs, headings, and GFM table cells without modifying the immutable MinerU result. Corrections can be reviewed, restored, or removed.\n- Translate a complete article through a configured Vercel AI SDK provider and switch between Original, Translation, and continuous Bilingual reading; look up a selected term or passage from the Original view or the source side of Bilingual reading.\n- Explore direct reference relationships among papers already in the current Zotero library, using cache-first refreshes from Semantic Scholar, OpenCitations, and OpenAlex when identifiers are available.\n- Save a portable Zotero snapshot containing HTML, Markdown, source maps, and embedded figures.\n- Export the corrected source Markdown and its extracted figures to a user-selected local path.\n- Follow Zotero's English or Simplified Chinese display language; other locales fall back to English.\n\n- Desktop Zotero\n`7.0`\n\nthrough`10.0.*`\n\n- A PDF attachment downloaded and available as a local file\n- A\n[MinerU API Token](https://mineru.net/apiManage/token) - Network access to the MinerU API\n\nMinerU controls file-size, page-count, quota, and service-availability limits.\nSee the [MinerU API documentation](https://mineru.net/apiManage/docs) for the\ncurrent limits.\n\n- Download the latest\n`mktero-<version>.xpi`\n\nfrom[GitHub Releases](https://github.com/tenglvjun/mktero/releases/latest). - In Zotero, open\n`Tools -> Plugins`\n\n. - Open the gear menu and choose\n`Install Add-on From File...`\n\n. - Select the XPI and follow Zotero's prompts.\n\nFormal GitHub releases receive automatic updates through Zotero. Drafts and prereleases are not offered as automatic updates.\n\nOpen `Settings -> Mktero`\n\nafter installation.\n\n| Setting | Required | Purpose |\n|---|---|---|\n| MinerU API Token | Yes for a cache miss | Upload and convert PDFs with MinerU |\n| AI features and provider settings | Optional | Translate Markdown through a hosted or loopback model service |\n| Translation language | Optional | Choose Simplified/Traditional Chinese, Japanese, Korean, Spanish, French, or Brazilian Portuguese |\n| Automatically translate Markdown selections | Optional, off by default | Translate a stable selection without an extra click; disabling it keeps the manual popup action |\n| Body text font and size | Optional | Choose the reading font and a 16–22 px body size |\n| Reuse conversion results | Optional | Reuse results for the same PDF content and parser profile |\n\nMinerU and AI credentials are stored as ordinary, unencrypted preferences in\nthe active Zotero profile. Use `Test connection`\n\nto validate an AI endpoint\nbefore translating.\n\n- Open a PDF in Zotero and click the Mktero file icon in the reader toolbar, or\nright-click a PDF or library item and choose\n`Read as Markdown with Mktero`\n\n. - Follow the upload, conversion, and download progress in the temporary Mktero tab. A valid cache entry skips the remote conversion.\n- Use the outline, citations, figure/table previews, source links, and Zotero notes panel to navigate the document.\n- Use the reader toolbar to adjust typography, switch reading mode, translate, correct recognition errors, save a snapshot, or export Markdown.\n\nMktero tabs are session-only and are not restored after Zotero restarts. Closing the tab or shutting down the extension cancels active conversion and translation requests.\n\nMinerU content mappings connect Markdown blocks to physical PDF pages and regions. Source links and source-aware copy use those mappings when they are reliable; Mktero does not guess a location when a match is ambiguous. Markdown is rendered in an isolated shadow root with a restricted link and image policy.\n\nDouble-click an existing paragraph, heading, or GFM table cell to edit it, then\nsave or cancel explicitly. Existing paragraphs and headings can also be\ndeleted and restored from `Manage corrections`\n\n. Corrections are stored\nseparately from the conversion cache and are tied to the PDF content and MinerU\nparser profile. They cannot insert or reorder blocks, add images, or add raw\nHTML.\n\nExisting Zotero text highlights and underlines are loaded when a document opens. Selecting Markdown text can create a local annotation immediately; Mktero then creates the corresponding Zotero annotation only when the local PDF text index can identify one reliable match. Repeated or ambiguous text remains local and can be retried instead of receiving a guessed PDF position. When a highlight overlaps a citation, table reference, or figure reference, that semantic reference keeps interaction priority; annotation actions remain available from the surrounding highlighted text or its note marker.\n\nAI translation is always opt-in and never rewrites the source Markdown. Mktero\ngroups the article into bounded Markdown batches, protects formulas, citations,\nlinks, code, images, and structural placeholders, and runs at most five\nrequests concurrently. Choose `Original`\n\n, `Translation`\n\n, or `Bilingual`\n\nin\nthe reader. Translations are cached independently by source content, provider,\nprotocol, model, language, and prompt version, so partial work can resume.\n\nFor a focused lookup, select text in `Original`\n\nor on the source side of\n`Bilingual`\n\nreading. The selection popup places its manual translation action\nat the end of the action row; loading, results, and errors expand below it only\nwhen needed in a compact panel. A successful result can be translated again or\ncopied as plain text. The `Automatically translate Markdown selections`\n\nsetting\nis off by default; when enabled, a stable selection starts one bounded request\nautomatically after a short delay. The translated side of `Bilingual`\n\n,\n`Translation`\n\nreading, and saved HTML snapshots do not offer selection\ntranslation. Selection results stay in the popup, do not modify Markdown or\nnotes, and are not added to the full-document translation cache. Each selection\nrequest sends the selected text and a bounded amount of nearby source context\nto the configured AI provider and may incur provider usage costs.\n\nMktero includes adapters for OpenAI, Anthropic, Google Gemini, DeepSeek, Alibaba Cloud Model Studio, Moonshot/Kimi, MiniMax, and custom OpenAI-compatible or Open Responses services through Vercel AI SDK Core. Remote endpoints must use HTTPS; loopback services such as Ollama or LM Studio may use HTTP.\n\nThe citation graph contains the focused paper and direct references that can be\nmatched to items already in the current Zotero library. DOI and arXiv\nidentifiers are queried concurrently from Semantic Scholar, OpenCitations, and\nOpenAlex when supported. Matching uses a unique normalized identifier, never a\ntitle, and provider metadata stays local. The graph details include a button\nlabeled `Open with Mktero`\n\n. It opens the first local PDF attachment through the\nsame Markdown reading workflow as `Read as Markdown with Mktero`\n\n.\n\nOpen a citation popup to see local Zotero presence before any network lookup is\nmade. Choosing `Import reference`\n\nfor a title-only reference explicitly starts\na bounded OpenAlex lookup. A unique exact title, year, and author match\ncontinues directly into import. Mktero also accepts a one-year provider date\ndifference only when the cleaned title is nearly identical and the first author\nmatches. Otherwise it shows at most three plausible candidates, and choosing\none continues the same import. The lookup retries with a cleaned title when a\nfull citation is too noisy and also covers OpenAlex records such as books that\ndo not have a DOI. For IEEE-style references, a paired straight or typographic\ndouble-quoted article title is searched separately from its authors, venue,\nvolume, and pages. For unquoted conference references, Mktero separates a\npaper title from a following `In ... Conference`\n\n, proceedings, workshop, or\nsymposium venue. The popup lists accessible\npersonal and group libraries and lets you choose the import target. A read-only\nlibrary remains selectable for presence checks, while its import actions stay\ndisabled with a permission explanation. If a matching item exists in another\nlibrary, Mktero offers an explicit copy action rather than silently creating a\nduplicate. Missing references with a reliable DOI, arXiv ID, or PMID can be\nimported through Zotero's native translator; confirmed OpenAlex-only records\nsuch as books are created directly from their bounded metadata. When the target\nlibrary permits files, Mktero also tries an arXiv or configured open-access\nPDF; metadata remains available when the PDF download fails and can be retried.\nThe popup header contains only the target-library picker. Each reference shows\nits status on the left and its own import, retry, copy, or open action on the\nright, so actions always apply to one visible reference.\n\nGrouped author-year citations resolve every matched bibliography entry. If PDF conversion inserts a stray heading inside an APA-style bibliography, Mktero continues the reference list only when multiple bibliography-shaped entries clearly resume after it, so a genuine author note still ends the list.\n\n`Save snapshot`\n\ncreates a dedicated `Mktero Markdown Snapshot`\n\nNote under the\nPDF's parent item. The Note contains portable HTML; figures are embedded image\nattachments; the original Markdown and source map are related attachments.\nMktero refuses to silently overwrite a snapshot Note that you edited. A\nstandalone PDF without a parent library item cannot save a snapshot.\n\n`Export Markdown`\n\nopens the system folder picker. If the selected folder is `A`\n\nand the paper title is `B`\n\n, Mktero creates `A/B/B.md`\n\nand writes extracted\nfigures under `A/B/assets/`\n\n, updating their Markdown paths accordingly. If `B`\n\nalready exists, a numbered directory such as `B-2`\n\nis created with a matching\n`B-2.md`\n\n; existing exports are never overwritten. Export does not include\ntranslated or bilingual views and never runs automatically.\n\n``` php\nLocal Zotero PDF\n        |\n        v\nMinerU conversion -----> Markdown + figures + content map\n        |                               |\n        v                               v\nLocal content cache             Safe normalization/rendering\n                                        |\n                                        v\n                           Reading-first Mktero tab in Zotero\n```\n\nPDFs, MinerU results, archives, image paths, API responses, and preferences are treated as untrusted input. Archives and Markdown are checked against resource budgets, archive paths are normalized, remote Markdown images are not loaded, and raw HTML is escaped or sanitized before rendering.\n\n| Data | Sent to or stored in | Zotero sync |\n|---|---|---|\n| Complete PDF on a cache miss | MinerU | Not by Mktero |\n| MinerU API Token and AI credentials | Active Zotero profile, unencrypted | No |\n| Cached Markdown, figures, source maps, PDF indexes, corrections, and translations | Active Zotero profile, unencrypted | No |\n| Focused DOI/arXiv/OpenAlex identifiers and provider-specific candidate identifiers | Semantic Scholar, OpenCitations, or OpenAlex | Not by Mktero |\nBounded citation text after the user chooses `Import reference` for a title-only reference |\nOpenAlex | Not by Mktero |\n| A normalized DOI, arXiv ID, PMID, or OpenAlex work ID plus confirmed metadata after the user clicks the import action; optional open-access PDF request | The selected metadata/PDF provider | Not by Mktero |\n| Protected Markdown translation batches | AI provider configured by you | Not by Mktero |\n| Selected Markdown text and bounded surrounding source context for selection translation | AI provider configured by you | Not by Mktero |\n| Zotero PDF annotations | Local Zotero library | According to Zotero settings |\n| Saved snapshot Note and attachments | Zotero items and attachments | According to Zotero settings |\n| Exported Markdown and figures | User-selected local path | No |\n| Imported reference metadata and PDF attachments | Active Zotero profile, unencrypted | According to Zotero settings |\n\nMktero does not send PDF annotations, local PDF.js indexes, Zotero notes, complete item records, local paths, or cached Markdown to reference/PDF providers. Reference import requests are local-first. A title-only metadata lookup sends only bounded citation text after the explicit import action. A unique high-confidence match continues automatically; uncertain matches require candidate confirmation. Citation and reference requests use anonymous provider access and contain only the bounded citation text, normalized identifiers, and confirmed metadata described above, never Zotero keys or PDF bytes. Translation requests contain protected Markdown and instructions; if placeholder validation repeatedly fails, the final retry contains only the affected block's ordinary text segments. API Tokens, presigned URLs, PDF bytes, and authenticated responses are not written to logs. Selection translation requests contain only the selected text and bounded nearby source context; they are not written to the full-document translation cache.\n\nReview the privacy policy of MinerU and any AI or citation provider Mktero uses. Do not process confidential PDFs unless their data-handling terms are suitable for your use case.\n\n- Only local PDF attachments are supported. A scanned PDF may convert through OCR but still lacks the text layer needed for precise Zotero highlights.\n- Source navigation depends on the stable MinerU\n`*_content_list.json`\n\nformat; older cached results may remain readable without source links. - Navigation currently goes from Markdown to PDF. Reverse navigation is not implemented.\n- Mktero displays text highlights and underlines, not standalone notes, image/area annotations, or ink annotations.\n- Markdown images are limited to supported GIF, JPEG, PNG, and WebP files from the current result archive. Remote images are blocked.\n- Links are restricted to\n`http`\n\n,`https`\n\n,`zotero`\n\n, and document fragments. - Markdown correction mode only edits or removes existing blocks; it cannot change document structure, formulas, images, or raw HTML.\n- AI translation is an optional cached reading layer. It does not modify source Markdown or get included in snapshots.\n- Selection translation is a separate, on-demand reading aid. It is available only from source text in Markdown reading views, is not cached, and may incur AI provider usage costs.\n- Archives, Markdown, images, source maps, PDF indexes, and KaTeX rendering have local resource limits and fail safely when those limits are exceeded.\n\nIn Zotero, open `Help -> Debug Output Logging`\n\n, enable logging, reproduce the\nproblem, and filter for `Mktero:`\n\n. Confirm that the PDF is downloaded locally,\nthe MinerU Token is valid, and the current network can reach MinerU. Logs do\nnot contain API Tokens, presigned upload URLs, MinerU batch IDs, or PDF content.\n\nFor a confirmed, reproducible bug, open a [GitHub Issue](https://github.com/tenglvjun/mktero/issues)\nwith the Zotero and Mktero versions, operating system, PDF type, reproduction\nsteps, expected behavior, and actual behavior. Never attach API Tokens, private\nPDFs, authenticated URLs, or local file paths.\n\nUse the Node.js version in [ .node-version](/tenglvjun/mktero/blob/main/.node-version), currently\n\n`24.15.0`\n\n. Node.js 25 is outside the supported dependency range.\n\n```\nnpm ci\nnpm run check\nnpm test\nnpm run build\n```\n\nRun one test while iterating with `node --test test/<name>.test.js`\n\n. The build\ncreates the reproducible XPI, SHA-256 checksum, and `build/updates.json`\n\nunder\n`build/`\n\n; `build/`\n\nand `node_modules/`\n\nare generated and ignored.\n\nKeep the versions in `manifest.json`\n\n, `package.json`\n\n, and `package-lock.json`\n\nconsistent before tagging a release. See [AGENTS.md](/tenglvjun/mktero/blob/main/AGENTS.md) for the\narchitecture, security invariants, and contribution checklist.\n\nPull requests are welcome. For ideas, reading workflows, and beta feedback, use\n[GitHub Discussions](https://github.com/tenglvjun/mktero/discussions). For\nchanges to runtime behavior, run the complete verification commands above and\ninclude tests for the affected behavior. Please keep credentials, private PDFs,\nand other sensitive data out of issues, pull requests, and logs.\n\n[MIT](/tenglvjun/mktero/blob/main/LICENSE) © 2026 Tony", "url": "https://wpnews.pro/news/show-hn-mktero-a-source-linked-markdown-reader-for-zotero", "canonical_source": "https://github.com/tenglvjun/mktero", "published_at": "2026-08-30 15:11:15+00:00", "updated_at": "2026-08-30 15:22:35.719299+00:00", "lang": "en", "topics": ["ai-tools", "ai-products"], "entities": ["Mktero", "Zotero", "MinerU", "Semantic Scholar", "OpenCitations", "OpenAlex", "Vercel AI SDK"], "alternates": {"html": "https://wpnews.pro/news/show-hn-mktero-a-source-linked-markdown-reader-for-zotero", "markdown": "https://wpnews.pro/news/show-hn-mktero-a-source-linked-markdown-reader-for-zotero.md", "text": "https://wpnews.pro/news/show-hn-mktero-a-source-linked-markdown-reader-for-zotero.txt", "jsonld": "https://wpnews.pro/news/show-hn-mktero-a-source-linked-markdown-reader-for-zotero.jsonld"}}