Repository Analysis

54yyyu/zotero-mcp

Zotero MCP: Connects your Zotero research library with Claude and other AI assistants via the Model Context Protocol to discuss papers, get summaries, analyze citations, and more.

70.4 Strong AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of 54yyyu/zotero-mcp, a Python project with 4,267 GitHub stars. SynthScan v2.0 examined 46,571 lines of code across 125 source files, recording 2016 pattern matches distributed across 15 syntactic categories. The overall adjusted score of 70.4 places this repository in the Strong AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

70.4
Adjusted Score
70.4
Raw Score
100%
Time Factor
2026-07-13
Last Push
4.3K
Stars
Python
Language
46.6K
Lines of Code
125
Files
2.0K
Pattern Hits
2026-07-14
Scan Date
0.03
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 0HIGH 4MEDIUM 544LOW 1468

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 2016 distinct pattern matches across 15 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Decorative Section Separators494 hits · 1812 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_page_layout.py48# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py50# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py110# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py112# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py212# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py214# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py23# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py25# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py136# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py138# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py301# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py303# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py560# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_page_layout.py562# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_scite.py37# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_scite.py39# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_scite.py58# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_scite.py60# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py85# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py87# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py16# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py18# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py128# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py130# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py169# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py171# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py205# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py207# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py388# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py390# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py422# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py424# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py298# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py300# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_shared_helpers.py11# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py13# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py57# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py59# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py79# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py81# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py109# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py111# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py138# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py140# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py188# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py190# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py287# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py289# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py308# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py310# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py248# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py250# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py109# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py111# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py268# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py270# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py292# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py294# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py434# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_add_by_url.py436# ---------------------------------------------------------------------------COMMENT
434 more matches not shown…
Hyper-Verbose Identifiers847 hits · 817 pts
SeverityFileLineSnippetContext
LOWtests/test_page_layout.py53 def test_figure_caption_with_colon(self):CODE
LOWtests/test_page_layout.py60 def test_figure_caption_with_period(self):CODE
LOWtests/test_page_layout.py66 def test_fig_abbreviation_with_panel_letter(self):CODE
LOWtests/test_page_layout.py78 def test_supplementary_table_caption(self):CODE
LOWtests/test_page_layout.py84 def test_extended_data_figure_caption(self):CODE
LOWtests/test_page_layout.py90 def test_in_text_reference_rejected(self):CODE
LOWtests/test_page_layout.py94 def test_sentence_starting_with_figure_rejected(self):CODE
LOWtests/test_page_layout.py104 def test_caption_is_case_insensitive(self):CODE
LOWtests/test_page_layout.py180 def test_merges_vertically_adjacent_fragments(self):CODE
LOWtests/test_page_layout.py189 def test_keeps_distant_regions_separate(self):CODE
LOWtests/test_page_layout.py197 def test_dedupes_same_area_keeping_table(self):CODE
LOWtests/test_page_layout.py221 def test_figure_caption_below_figure(self):CODE
LOWtests/test_page_layout.py231 def test_table_caption_above_table(self):CODE
LOWtests/test_page_layout.py240 def test_caption_too_far_not_attached(self):CODE
LOWtests/test_page_layout.py250 def test_two_column_caption_not_cross_attached(self):CODE
LOWtests/test_page_layout.py260 def test_caption_attaches_to_nearest_of_two_stacked_figures(self):CODE
LOWtests/test_page_layout.py706 def test_rejects_invalid_page_number(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py716 def test_requires_a_zotero_client(self, monkeypatch):CODE
LOWtests/test_page_layout.py726 def test_works_with_local_client_only(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py155 def test_drops_full_page_background(self):CODE
LOWtests/test_page_layout.py164 def test_merges_overlapping_fragments(self):CODE
LOWtests/test_page_layout.py274 def test_each_caption_attaches_to_one_region_only(self):CODE
LOWtests/test_page_layout.py287 def test_region_without_caption_gets_low_confidence(self):CODE
LOWtests/test_page_layout.py317 def test_detects_raster_image_with_caption(self):CODE
LOWtests/test_page_layout.py348 def test_detects_vector_drawing(self):CODE
LOWtests/test_page_layout.py370 def test_detects_table_keeping_table_source(self):CODE
LOWtests/test_page_layout.py400 def test_text_only_page_returns_no_regions(self):CODE
LOWtests/test_page_layout.py418 def test_page_out_of_range_returns_error(self):CODE
LOWtests/test_page_layout.py431 def test_full_page_scan_returns_warning(self):CODE
LOWtests/test_page_layout.py451 def test_missing_cluster_drawings_adds_warning(self, monkeypatch):CODE
LOWtests/test_page_layout.py471 def test_regions_have_sequential_ids_and_normalized_bboxes(self):CODE
LOWtests/test_page_layout.py496 def test_rotated_page_bboxes_stay_normalized(self):CODE
LOWtests/test_page_layout.py518 def test_cropped_page_bboxes_stay_normalized(self):CODE
LOWtests/test_page_layout.py549 def test_invalid_pdf_returns_error(self):CODE
LOWtests/test_page_layout.py611 def test_happy_path_renders_regions_table(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py648 def test_no_regions_returns_guidance(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py659 def test_warnings_are_included(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py673 def test_detection_error_is_returned(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py684 def test_rejects_non_pdf_attachment(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py695 def test_rejects_non_attachment_item(self, monkeypatch, fake_zot):CODE
LOWtests/test_identifier_fields_markdown.py61 def test_isbn_omitted_when_empty(self):CODE
LOWtests/test_identifier_fields_markdown.py66 def test_isbn_omitted_when_missing(self):CODE
LOWtests/test_identifier_fields_markdown.py78 def test_issn_omitted_when_empty(self):CODE
LOWtests/test_place_field_reads.py57 def test_place_rendered_for_book(self):CODE
LOWtests/test_place_field_reads.py63 def test_place_rendered_for_book_section(self):CODE
LOWtests/test_place_field_reads.py68 def test_place_rendered_for_thesis(self):CODE
LOWtests/test_place_field_reads.py73 def test_place_without_publisher(self):CODE
LOWtests/test_place_field_reads.py79 def test_place_omitted_when_empty(self):CODE
LOWtests/test_place_field_reads.py85 def test_place_omitted_when_missing(self):CODE
LOWtests/test_place_field_reads.py102 def test_address_rendered_for_book(self):CODE
LOWtests/test_place_field_reads.py107 def test_address_rendered_for_book_section(self):CODE
LOWtests/test_place_field_reads.py112 def test_address_omitted_when_empty(self):CODE
LOWtests/test_place_field_reads.py117 def test_address_omitted_when_missing(self):CODE
LOWtests/test_place_field_reads.py127 def test_place_in_fetch_metadata(self, monkeypatch):CODE
LOWtests/test_scite.py42def test_get_papers_batch_posts_bare_doi_array(monkeypatch):CODE
LOWtests/test_scite.py63def test_enrich_items_matches_lowercased_scite_keys(monkeypatch):CODE
LOWtests/test_scite.py98def test_check_retractions_flags_uppercase_doi(monkeypatch, dummy_ctx, fake_zot):CODE
LOWtests/test_citation_import.py90 def test_parses_single_article(self):CODE
LOWtests/test_citation_import.py141 def test_multiple_authors_split_on_and(self):CODE
LOWtests/test_citation_import.py147 def test_corporate_author_with_llc(self):CODE
787 more matches not shown…
Excessive Try-Catch Wrapping363 hits · 345 pts
SeverityFileLineSnippetContext
LOWtests/test_ollama_embedding.py70 except Exception:CODE
LOWtests/test_description_tokens.py95 except Exception:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py110 except Exception:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py134 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py178 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py232 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/better_bibtex_client.py233 print(f"Error searching for cite keys: {e}")CODE
LOWsrc/zotero_mcp/better_bibtex_client.py292 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/better_bibtex_client.py293 print(f"Error exporting BibTeX: {e}")CODE
LOWsrc/zotero_mcp/better_bibtex_client.py369 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/better_bibtex_client.py370 print(f"Error processing annotation: {e}")CODE
LOWsrc/zotero_mcp/pdf_utils.py829 except Exception:CODE
LOWsrc/zotero_mcp/client.py215 except Exception:CODE
LOWsrc/zotero_mcp/client.py386 except Exception:CODE
LOWsrc/zotero_mcp/client.py534 except Exception:CODE
LOWsrc/zotero_mcp/client.py580 except Exception as exc:CODE
LOWsrc/zotero_mcp/client.py607 except Exception as exc:CODE
LOWsrc/zotero_mcp/client.py631 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/setup_helper.py436 print(f"Error saving semantic search config: {e}")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py94 print(f"Error searching for zotero-mcp: {e}")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py469 print(f"Error: Config file at {config_path} is not valid JSON. Creating new config.")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py533 print(f"Error writing config file: {str(e)}")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py640 print("Error: Could not find zotero-mcp executable.")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py654 print("Error: Could not determine Claude Desktop config path.")CODE
LOWsrc/zotero_mcp/setup_helper.py435 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py93 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py451 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py532 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py551 except Exception:CODE
LOWsrc/zotero_mcp/setup_helper.py735 except Exception:CODE
LOWsrc/zotero_mcp/setup_helper.py781 except Exception as e:CODE
LOWsrc/zotero_mcp/pdfannots_downloader.py183 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/pdfannots_downloader.py184 print(f"Error downloading pdfannots2json: {e}")CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py416 print("Error: --openai-batch requires ZOTERO_EMBEDDING_MODEL=openai", file=sys.stderr)CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py422 print("Error: --fulltext requires local mode (ZOTERO_LOCAL=true).", file=sys.stderr)CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py432 print(f"Error: {stats['error']}", file=sys.stderr)CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py102 print(f"Error: invalid JSON in --conditions: {e}", file=sys.stderr)CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py115 print(f"Error: invalid JSON in --filters: {e}", file=sys.stderr)CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py208 print("Error: provide note text via --text TEXT or --text - (reads stdin)",CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py344 print(f"Error: invalid JSON in --creators: {e}", file=sys.stderr)CODE
MEDIUMsrc/zotero_mcp/cli_standalone.py870 print(f"Error: {e}", file=sys.stderr)CODE
LOWsrc/zotero_mcp/cli_standalone.py869 except Exception as e:CODE
LOWsrc/zotero_mcp/_app.py42 except Exception:CODE
LOWsrc/zotero_mcp/_app.py76 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/_app.py73def _background_update():CODE
LOWsrc/zotero_mcp/updater.py71 except Exception:CODE
LOWsrc/zotero_mcp/updater.py87 except Exception:CODE
LOWsrc/zotero_mcp/updater.py207 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py217 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py227 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py41 except Exception:CODE
LOWsrc/zotero_mcp/updater.py116 except Exception:CODE
LOWsrc/zotero_mcp/updater.py141 except Exception:CODE
LOWsrc/zotero_mcp/updater.py162 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py175 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py256 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py268 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py281 except Exception as e:CODE
LOWsrc/zotero_mcp/updater.py333 except Exception:CODE
LOWsrc/zotero_mcp/updater.py363 except Exception as e:CODE
303 more matches not shown…
Unused Imports150 hits · 103 pts
SeverityFileLineSnippetContext
LOWtests/test_shared_helpers.py4CODE
LOWtests/test_shared_helpers.py4CODE
LOWtests/test_add_by_url.py7CODE
LOWtests/test_delete_item.py9CODE
LOWtests/test_add_by_isbn.py8CODE
LOWtests/test_add_by_isbn.py10CODE
LOWtests/test_add_from_file.py5CODE
LOWtests/test_add_from_file.py6CODE
LOWtests/test_add_from_file.py6CODE
LOWtests/test_add_from_file.py9CODE
LOWtests/test_add_from_file.py9CODE
LOWtests/test_update_item.py3CODE
LOWtests/test_token_optimization.py4CODE
LOWtests/test_token_optimization.py6CODE
LOWtests/test_v021_fixes.py6CODE
LOWtests/test_v021_fixes.py8CODE
LOWtests/test_v021_fixes.py10CODE
LOWtests/test_tag_filter_normalization.py10CODE
LOWtests/test_add_by_doi.py4CODE
LOWtests/test_api_lock_bounded.py14CODE
LOWtests/test_search_improvements.py3CODE
LOWtests/test_search_improvements.py4CODE
LOWtests/test_search_improvements.py5CODE
LOWtests/test_zotero_ft_cache.py22CODE
LOWtests/test_pdf_cascade.py4CODE
LOWtests/test_pdf_cascade.py6CODE
LOWtests/test_pdf_cascade.py17CODE
LOWtests/test_webdav.py3CODE
LOWtests/test_item_related.py3CODE
LOWtests/test_cli_standalone.py3CODE
LOWtests/test_regression_bugs.py8CODE
LOWtests/test_duplicates.py3CODE
LOWtests/test_duplicates.py5CODE
LOWtests/test_pdf_outline.py6CODE
LOWtests/test_pdf_outline.py8CODE
LOWtests/test_pdf_outline.py8CODE
LOWsrc/zotero_mcp/webdav.py3CODE
LOWsrc/zotero_mcp/server.py13CODE
LOWsrc/zotero_mcp/server.py16CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py19CODE
LOWsrc/zotero_mcp/server.py30CODE
LOWsrc/zotero_mcp/server.py30CODE
LOWsrc/zotero_mcp/server.py30CODE
LOWsrc/zotero_mcp/server.py30CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
LOWsrc/zotero_mcp/server.py38CODE
90 more matches not shown…
Deep Nesting90 hits · 56 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/webdav.py222CODE
LOWsrc/zotero_mcp/better_bibtex_client.py113CODE
LOWsrc/zotero_mcp/better_bibtex_client.py236CODE
LOWsrc/zotero_mcp/client.py365CODE
LOWsrc/zotero_mcp/client.py467CODE
LOWsrc/zotero_mcp/setup_helper.py146CODE
LOWsrc/zotero_mcp/setup_helper.py408CODE
LOWsrc/zotero_mcp/setup_helper.py456CODE
LOWsrc/zotero_mcp/setup_helper.py582CODE
LOWsrc/zotero_mcp/pdfannots_downloader.py133CODE
LOWsrc/zotero_mcp/cli_standalone.py86CODE
LOWsrc/zotero_mcp/cli_standalone.py130CODE
LOWsrc/zotero_mcp/cli_standalone.py195CODE
LOWsrc/zotero_mcp/cli_standalone.py241CODE
LOWsrc/zotero_mcp/cli_standalone.py397CODE
LOWsrc/zotero_mcp/updater.py45CODE
LOWsrc/zotero_mcp/updater.py122CODE
LOWsrc/zotero_mcp/updater.py288CODE
LOWsrc/zotero_mcp/local_db.py565CODE
LOWsrc/zotero_mcp/local_db.py761CODE
LOWsrc/zotero_mcp/epub_utils.py469CODE
LOWsrc/zotero_mcp/epub_utils.py701CODE
LOWsrc/zotero_mcp/cli.py101CODE
LOWsrc/zotero_mcp/cli.py277CODE
LOWsrc/zotero_mcp/utils.py22CODE
LOWsrc/zotero_mcp/chroma_client.py852CODE
LOWsrc/zotero_mcp/chroma_client.py446CODE
LOWsrc/zotero_mcp/chroma_client.py537CODE
LOWsrc/zotero_mcp/chroma_client.py684CODE
LOWsrc/zotero_mcp/citation_import.py153CODE
LOWsrc/zotero_mcp/citation_import.py180CODE
LOWsrc/zotero_mcp/citation_import.py339CODE
LOWsrc/zotero_mcp/citation_import.py525CODE
LOWsrc/zotero_mcp/pdf_layout.py138CODE
LOWsrc/zotero_mcp/pdf_layout.py216CODE
LOWsrc/zotero_mcp/pdf_layout.py312CODE
LOWsrc/zotero_mcp/semantic_search.py211CODE
LOWsrc/zotero_mcp/semantic_search.py256CODE
LOWsrc/zotero_mcp/semantic_search.py756CODE
LOWsrc/zotero_mcp/semantic_search.py1380CODE
LOWsrc/zotero_mcp/semantic_search.py1505CODE
LOWsrc/zotero_mcp/semantic_search.py1851CODE
LOWsrc/zotero_mcp/semantic_search.py2153CODE
LOWsrc/zotero_mcp/semantic_search.py2218CODE
LOWsrc/zotero_mcp/tools/write.py190CODE
LOWsrc/zotero_mcp/tools/write.py378CODE
LOWsrc/zotero_mcp/tools/write.py456CODE
LOWsrc/zotero_mcp/tools/write.py709CODE
LOWsrc/zotero_mcp/tools/write.py776CODE
LOWsrc/zotero_mcp/tools/write.py891CODE
LOWsrc/zotero_mcp/tools/write.py1198CODE
LOWsrc/zotero_mcp/tools/write.py1712CODE
LOWsrc/zotero_mcp/tools/write.py2079CODE
LOWsrc/zotero_mcp/tools/write.py2209CODE
LOWsrc/zotero_mcp/tools/write.py2516CODE
LOWsrc/zotero_mcp/tools/write.py2831CODE
LOWsrc/zotero_mcp/tools/write.py3098CODE
LOWsrc/zotero_mcp/tools/discovery.py152CODE
LOWsrc/zotero_mcp/tools/discovery.py288CODE
LOWsrc/zotero_mcp/tools/retrieval.py116CODE
30 more matches not shown…
Self-Referential Comments9 hits · 27 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_regression_bugs.py193 # Create a dummy fileCOMMENT
MEDIUMsrc/zotero_mcp/client.py202 # Create a local client - library_id 0 is the default for local.COMMENT
MEDIUMsrc/zotero_mcp/pdfannots_downloader.py155 # Create a temporary directory for the downloadCOMMENT
MEDIUMsrc/zotero_mcp/_app.py86# Create an MCP server (fastmcp 2.14+ no longer accepts `dependencies`)COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py2590 # Create the metadata item. With if_exists='file' and a known DOI,COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py2604 # Create a basic itemCOMMENT
MEDIUMsrc/zotero_mcp/tools/retrieval.py368 # Create a mapping of collection IDs to their dataCOMMENT
MEDIUMsrc/zotero_mcp/tools/retrieval.py371 # Create a mapping of parent to child collectionsCOMMENT
MEDIUMsrc/zotero_mcp/tools/annotations.py1440 # Create the annotation using web clientCOMMENT
Structural Annotation Overuse12 hits · 24 pts
SeverityFileLineSnippetContext
LOWdocs/integration-test-plan.md491### Step 1: Verify all per-phase cleanups were doneCOMMENT
LOWdocs/integration-test-plan.md499### Step 2: Identify test-created itemsCOMMENT
LOWdocs/integration-test-plan.md505### Step 3: Tell the user to delete manuallyCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py251 # Step 1: Get citation key from item key. BBT's JSON-RPC expectsCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py266 # Step 2: Export BibTeX using the citation key.COMMENT
LOWsrc/zotero_mcp/tools/write.py2319 # Step 4: Consolidate collectionsCOMMENT
LOWsrc/zotero_mcp/tools/write.py2326 # Step 5: Re-parent children (skip duplicate attachments)COMMENT
LOWsrc/zotero_mcp/tools/write.py2364 # Step 6: Trash duplicates (move to Zotero Trash, NOT permanent delete)COMMENT
LOWsrc/zotero_mcp/tools/write.py2308 # Step 3: Consolidate tagsCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py664 # Step 2: Batch-fetch the grandparents (papers)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py688 # Step 3: Map attachment keys to paper titlesCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py633 # Step 1: Batch-fetch the immediate parents (attachments)COMMENT
Modern AI Meta-Vocabulary7 hits · 22 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_fulltext_web_mode.py279# --------- Integration tests: update_database orchestration ----------COMMENT
MEDIUMtests/test_trashed_collections.py23# Test scaffoldingCOMMENT
MEDIUMsrc/zotero_mcp/setup_helper.py172 # Choose embedding modelCOMMENT
MEDIUMsrc/zotero_mcp/chroma_client.py878 # Pick the embedding model. config.json is the richer, authoritative sourceCOMMENT
MEDIUMsrc/zotero_mcp/semantic_search.py1923 # Truncate to fit the configured embedding model's token limitCOMMENT
MEDIUMsrc/zotero_mcp/tools/search.py1058 # guard, but neither loads an embedding model or a Zotero client.COMMENT
MEDIUMsrc/zotero_mcp/tools/search.py1072 # Read status without loading any embedding model (fast, no network).COMMENT
Magic Placeholder Names4 hits · 20 pts
SeverityFileLineSnippetContext
HIGHREADME.md268 "ZOTERO_API_KEY": "YOUR_API_KEY",CODE
HIGHREADME.md282 - Click [here](https://www.zotero.org/settings/security#applications) to generate a Zotero API key and replace `YOUR_CODE
HIGHREADME.md353zotero-mcp setup --no-local --api-key YOUR_API_KEY --library-id YOUR_LIBRARY_IDCODE
HIGHdocs/getting-started.md45 export ZOTERO_API_KEY=your_api_keyCODE
Redundant / Tautological Comments11 hits · 18 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/pdfannots_downloader.py69 # Check if we have a URL for this platform/architectureCOMMENT
LOWsrc/zotero_mcp/updater.py62 # Check if we're in a uv-managed projectCOMMENT
LOWsrc/zotero_mcp/updater.py77 # Check if we're in a uv virtual environmentCOMMENT
LOWsrc/zotero_mcp/updater.py101 # Check if pipx is availableCOMMENT
LOWsrc/zotero_mcp/updater.py437 # Check if update is neededCOMMENT
LOWsrc/zotero_mcp/cli.py430 # Check if installed via uvCOMMENT
LOWsrc/zotero_mcp/chroma_client.py496 # Check if the stored config matches what we want; if not, recreate.COMMENT
LOWsrc/zotero_mcp/tools/write.py2774 # Check if relation already exists (match both URI prefix variants)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py167 # Check if Zotero with Better BibTeX is runningCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py1045 # Check if creation was successfulCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py1443 # Check if creation was successfulCOMMENT
Verbosity Indicators9 hits · 17 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/better_bibtex_client.py251 # Step 1: Get citation key from item key. BBT's JSON-RPC expectsCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py266 # Step 2: Export BibTeX using the citation key.COMMENT
LOWsrc/zotero_mcp/tools/write.py2319 # Step 4: Consolidate collectionsCOMMENT
LOWsrc/zotero_mcp/tools/write.py2326 # Step 5: Re-parent children (skip duplicate attachments)COMMENT
LOWsrc/zotero_mcp/tools/write.py2364 # Step 6: Trash duplicates (move to Zotero Trash, NOT permanent delete)COMMENT
LOWsrc/zotero_mcp/tools/write.py2308 # Step 3: Consolidate tagsCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py664 # Step 2: Batch-fetch the grandparents (papers)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py688 # Step 3: Map attachment keys to paper titlesCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py633 # Step 1: Batch-fetch the immediate parents (attachments)COMMENT
Modern Structural Boilerplate7 hits · 8 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/client.py100def set_active_library(library_id: str, library_type: str) -> None:CODE
LOWsrc/zotero_mcp/updater.py23logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/local_db.py20logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/chroma_client.py27logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/scite_client.py19logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/semantic_search.py35logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/tools/scite.py28logger = logging.getLogger(__name__)CODE
Fake / Example Data3 hits · 4 pts
SeverityFileLineSnippetContext
LOWtests/test_place_field_reads.py128 fake_data = {CODE
LOWtests/test_place_field_reads.py143 return {"key": key, "data": fake_data}CODE
LOWtests/test_add_by_isbn.py105 "authors": ["Jane Doe"],CODE
AI Structural Patterns6 hits · 4 pts
SeverityFileLineSnippetContext
LOWtests/test_update_item.py13CODE
LOWtests/test_update_item.py59CODE
LOWtests/test_update_item.py86CODE
LOWtests/test_update_item.py122CODE
LOWsrc/zotero_mcp/utils.py161CODE
LOWsrc/zotero_mcp/tools/write.py1712CODE
Over-Commented Block4 hits · 2 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/client.py21)COMMENT
LOWsrc/zotero_mcp/chroma_client.py161 persisted collection's config (see OpenAIEmbeddingFunction for details).COMMENT
LOWsrc/zotero_mcp/chroma_client.py181 V2_PREFIX_TOKEN_BUDGET = 20COMMENT
LOWsrc/zotero_mcp/chroma_client.py881 # The env var only fills the gap when config.json is absent or left at theCOMMENT