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.

52.3 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,829 GitHub stars. SynthScan v2.0 examined 112,248 lines of code across 391 source files, recording 3739 pattern matches distributed across 20 syntactic categories. The overall adjusted score of 52.3 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).

52.3
Adjusted Score
52.3
Raw Score
100%
Time Factor
2026-08-25
Last Push
4.8K
Stars
Python
Language
112.2K
Lines of Code
391
Files
3.7K
Pattern Hits
2026-08-29
Scan Date
0.04
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 17MEDIUM 859LOW 2863

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 3739 distinct pattern matches across 20 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 Separators788 hits · 2920 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_scite.py123# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_scite.py126# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_fulltext_cache.py186# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_fulltext_cache.py188# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py117# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py119# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py48# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py50# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py160# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py162# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py201# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py203# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py237# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py239# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py677# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py679# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py420# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py428# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py571# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py573# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py605# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py607# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py330# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py332# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py624# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py626# ---------------------------------------------------------------------------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.py313# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_shared_helpers.py315# ---------------------------------------------------------------------------COMMENT
728 more matches not shown…
Hyper-Verbose Identifiers2043 hits · 2036 pts
SeverityFileLineSnippetContext
LOWtests/test_attach_verification.py79 def test_none_when_attachment_registered(self):CODE
LOWtests/test_attach_verification.py82 def test_none_for_unchanged_entry(self):CODE
LOWtests/test_attach_verification.py86 def test_reports_failure_payload(self):CODE
LOWtests/test_attach_verification.py91 def test_reports_empty_result(self):CODE
LOWtests/test_attach_verification.py95 def test_reports_result_with_no_key(self):CODE
LOWtests/test_attach_verification.py101 def test_rejects_local_client(self):CODE
LOWtests/test_attach_verification.py114 def test_success_passes_through_key(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py124 def test_failed_upload_falls_back_to_two_step(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py137 def test_reports_failure_when_two_step_also_fails(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py153 def test_orphan_shell_deleted_when_upload_fails(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py167 def test_local_client_fails_fast(self, dummy_ctx):CODE
LOWtests/test_set_item_parent.py18def test_schema_requires_an_explicit_nullable_parent_key():CODE
LOWtests/test_set_item_parent.py72def test_sends_minimal_versioned_parent_update(CODE
LOWtests/test_set_item_parent.py94def test_surfaces_api_exception(monkeypatch):CODE
LOWtests/test_set_item_parent.py105def test_reports_unsuccessful_response(monkeypatch):CODE
LOWtests/test_set_item_parent.py114def test_surfaces_item_fetch_error_without_writing(monkeypatch):CODE
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.py708 def test_rejects_invalid_page_number(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py718 def test_requires_a_zotero_client(self, monkeypatch):CODE
LOWtests/test_page_layout.py728 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.py650 def test_no_regions_returns_guidance(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py661 def test_warnings_are_included(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py675 def test_detection_error_is_returned(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py686 def test_rejects_non_pdf_attachment(self, monkeypatch, fake_zot):CODE
LOWtests/test_page_layout.py697 def test_rejects_non_attachment_item(self, monkeypatch, fake_zot):CODE
LOWtests/test_gemini_batch.py38def test_split_embedding_records_respects_request_limit():CODE
LOWtests/test_gemini_batch.py48def test_parse_embedding_output_matches_by_key():CODE
LOWtests/test_gemini_batch.py59def test_parse_embedding_output_falls_back_to_positional_order():CODE
LOWtests/test_gemini_batch.py70def test_submit_embedding_batches_writes_manifest_and_jsonl(tmp_path):CODE
1983 more matches not shown…
Excessive Try-Catch Wrapping451 hits · 414 pts
SeverityFileLineSnippetContext
LOWexperiments/library-graph-validation/01_build_corpus.py114 except Exception as e:STRING
MEDIUMexperiments/library-graph-validation/01_build_corpus.py111def main():CODE
LOWtests/test_stringified_params.py44 except Exception:CODE
LOWtests/test_stringified_params.py117 except Exception as exc:CODE
LOWtests/test_stringified_params.py132 except Exception as exc:CODE
LOWtests/test_issue_431_server_wedge.py302 except Exception as exc: # pragma: no cover - failure detailCODE
MEDIUMtests/test_issue_431_server_wedge.py296def worker(delay):CODE
LOWtests/test_ollama_embedding.py72 except Exception:CODE
LOWtests/test_embedding_function_registration.py132 except Exception:CODE
LOWtests/test_description_tokens.py103 except Exception:CODE
MEDIUMtests/test_rate_limiter.py341def worker():CODE
LOWtests/test_rate_limiter.py349 except Exception as exc: # pragma: no cover - failure pathCODE
LOWtests/live/conftest.py96 except Exception:CODE
LOWtests/live/conftest.py163 except Exception as exc:CODE
LOWtests/live/conftest.py168 except Exception as exc:CODE
LOWtests/live/conftest.py242 except Exception:CODE
LOWtests/live/generate_sentinels.py63 except Exception:CODE
LOWtests/live/generate_sentinels.py106 except Exception as exc:CODE
LOWtests/live/_discovery.py39 except Exception:CODE
LOWtests/live/_discovery.py107 except Exception:CODE
LOWscripts/check_openai_ratelimits.py46 except Exception as e:CODE
LOWscripts/check_openai_ratelimits.py132 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py123 except Exception:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py147 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py191 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py245 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/better_bibtex_client.py246 print(f"Error searching for cite keys: {e}")CODE
LOWsrc/zotero_mcp/better_bibtex_client.py319 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py401 except Exception as e:CODE
MEDIUMsrc/zotero_mcp/better_bibtex_client.py402 print(f"Error processing annotation: {e}")CODE
LOWsrc/zotero_mcp/pdf_utils.py829 except Exception:CODE
LOWsrc/zotero_mcp/config_light.py52 except Exception as e:CODE
LOWsrc/zotero_mcp/config_light.py110 except Exception as e:CODE
LOWsrc/zotero_mcp/config_light.py137 except Exception:CODE
LOWsrc/zotero_mcp/html_metadata.py164 except Exception:CODE
LOWsrc/zotero_mcp/client.py264 except Exception:CODE
LOWsrc/zotero_mcp/client.py399 except Exception:CODE
LOWsrc/zotero_mcp/client.py506 except Exception as e:CODE
LOWsrc/zotero_mcp/client.py626 except Exception:CODE
LOWsrc/zotero_mcp/client.py711 except Exception:CODE
LOWsrc/zotero_mcp/client.py793 except Exception as exc:CODE
LOWsrc/zotero_mcp/client.py812 except Exception as exc:CODE
LOWsrc/zotero_mcp/client.py843 except Exception as exc:CODE
MEDIUMsrc/zotero_mcp/setup_helper.py557 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.py601 print(f"Error: Config file at {config_path} is not valid JSON. Creating new config.")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py665 print(f"Error writing config file: {str(e)}")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py773 print("Error: Could not find zotero-mcp executable.")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py786 print("Error: Could not determine Claude Desktop config path.")CODE
LOWsrc/zotero_mcp/setup_helper.py556 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py567 except Exception:CODE
LOWsrc/zotero_mcp/setup_helper.py93 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py583 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py664 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py683 except Exception:CODE
LOWsrc/zotero_mcp/setup_helper.py867 except Exception:CODE
LOWsrc/zotero_mcp/setup_helper.py934 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.py936 print(f"Error: {message}", file=sys.stderr)CODE
391 more matches not shown…
Unused Imports198 hits · 144 pts
SeverityFileLineSnippetContext
LOWtests/test_set_item_parent.py3CODE
LOWtests/test_shared_helpers.py4CODE
LOWtests/test_shared_helpers.py4CODE
LOWtests/test_toolsets.py13CODE
LOWtests/test_add_by_url.py7CODE
LOWtests/test_include_subcollections.py18CODE
LOWtests/test_delete_item.py9CODE
LOWtests/test_add_by_isbn.py8CODE
LOWtests/test_add_by_isbn.py10CODE
LOWtests/test_stringified_params.py31CODE
LOWtests/test_batch_adapter_compat.py20CODE
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.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_item_related.py3CODE
LOWtests/test_regression_bugs.py8CODE
LOWtests/test_duplicates.py6CODE
LOWtests/test_duplicates.py8CODE
LOWtests/_search_corpus.py21CODE
LOWtests/test_search_parity_offline.py22CODE
LOWtests/test_generic_batch_flags.py177CODE
LOWtests/test_generic_batch_flags.py178CODE
LOWtests/test_pdf_outline.py3CODE
LOWtests/test_pdf_outline.py5CODE
LOWtests/test_pdf_outline.py5CODE
LOWtests/live/generate_sentinels.py42CODE
LOWtests/live/test_embedding_sentinels.py25CODE
LOWtests/live/test_fault_injection.py19CODE
LOWtests/live/test_chroma_roundtrip_live.py19CODE
LOWscripts/measure_context_cost.py25CODE
LOWscripts/measure_context_cost.py100CODE
LOWscripts/gen_basefield_map.py21CODE
LOWsrc/zotero_mcp/webdav.py3CODE
LOWsrc/zotero_mcp/server.py14CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
LOWsrc/zotero_mcp/server.py18CODE
138 more matches not shown…
Deep Nesting118 hits · 71 pts
SeverityFileLineSnippetContext
LOW…eriments/library-graph-validation/04_build_subgraph.py47CODE
LOWtests/test_chroma_client_real.py363CODE
LOWtests/test_rate_limiter.py326CODE
LOWtests/test_rate_limiter.py341CODE
LOWtests/live/_discovery.py31CODE
LOWscripts/gen_skill_reference.py60CODE
LOWsrc/zotero_mcp/webdav.py222CODE
LOWsrc/zotero_mcp/better_bibtex_client.py126CODE
LOWsrc/zotero_mcp/better_bibtex_client.py249CODE
LOWsrc/zotero_mcp/config_light.py57CODE
LOWsrc/zotero_mcp/client.py461CODE
LOWsrc/zotero_mcp/toolsets.py148CODE
LOWsrc/zotero_mcp/setup_helper.py110CODE
LOWsrc/zotero_mcp/setup_helper.py207CODE
LOWsrc/zotero_mcp/setup_helper.py521CODE
LOWsrc/zotero_mcp/setup_helper.py588CODE
LOWsrc/zotero_mcp/setup_helper.py714CODE
LOWsrc/zotero_mcp/pdfannots_downloader.py133CODE
LOWsrc/zotero_mcp/cli_standalone.py193CODE
LOWsrc/zotero_mcp/cli_standalone.py250CODE
LOWsrc/zotero_mcp/cli_standalone.py363CODE
LOWsrc/zotero_mcp/cli_standalone.py413CODE
LOWsrc/zotero_mcp/cli_standalone.py473CODE
LOWsrc/zotero_mcp/cli_standalone.py636CODE
LOWsrc/zotero_mcp/updater.py45CODE
LOWsrc/zotero_mcp/updater.py122CODE
LOWsrc/zotero_mcp/updater.py319CODE
LOWsrc/zotero_mcp/local_db.py1754CODE
LOWsrc/zotero_mcp/epub_utils.py471CODE
LOWsrc/zotero_mcp/epub_utils.py703CODE
LOWsrc/zotero_mcp/cli.py54CODE
LOWsrc/zotero_mcp/cli.py105CODE
LOWsrc/zotero_mcp/cli.py434CODE
LOWsrc/zotero_mcp/utils.py79CODE
LOWsrc/zotero_mcp/utils.py114CODE
LOWsrc/zotero_mcp/chroma_client.py48CODE
LOWsrc/zotero_mcp/chroma_client.py265CODE
LOWsrc/zotero_mcp/citation_import.py192CODE
LOWsrc/zotero_mcp/citation_import.py219CODE
LOWsrc/zotero_mcp/citation_import.py378CODE
LOWsrc/zotero_mcp/citation_import.py583CODE
LOWsrc/zotero_mcp/pdf_layout.py140CODE
LOWsrc/zotero_mcp/pdf_layout.py218CODE
LOWsrc/zotero_mcp/pdf_layout.py314CODE
LOWsrc/zotero_mcp/fulltext_cache.py218CODE
LOWsrc/zotero_mcp/gemini_batch.py267CODE
LOWsrc/zotero_mcp/semantic_search.py331CODE
LOWsrc/zotero_mcp/semantic_search.py671CODE
LOWsrc/zotero_mcp/semantic_search.py1015CODE
LOWsrc/zotero_mcp/semantic_search.py1302CODE
LOWsrc/zotero_mcp/semantic_search.py1980CODE
LOWsrc/zotero_mcp/semantic_search.py2155CODE
LOWsrc/zotero_mcp/semantic_search.py2776CODE
LOWsrc/zotero_mcp/semantic_search.py2903CODE
LOWsrc/zotero_mcp/semantic_search.py3115CODE
LOWsrc/zotero_mcp/semantic_search.py3138CODE
LOWsrc/zotero_mcp/semantic_search.py3249CODE
LOWsrc/zotero_mcp/semantic_search.py3521CODE
LOWsrc/zotero_mcp/semantic_search.py3598CODE
LOWsrc/zotero_mcp/semantic_search.py2960CODE
58 more matches not shown…
Modern AI Meta-Vocabulary12 hits · 38 pts
SeverityFileLineSnippetContext
MEDIUMCHANGELOG.md92- **`update-db` no longer accepts `chunking.enabled` in silence on the OpenAI Batch API path (#416).** The batch path buCODE
MEDIUM…ents/library-graph-validation/data/graph_contexts.json3 "C": "### AlphaFold Meets Flow Matching for Generating Protein Ensembles [via-traversal]\n- [claim] Score-matching CODE
MEDIUM…ents/library-graph-validation/data/graph_contexts.json49 "C": "### Protein Conformation Generation via Force-Guided SE(3) Diffusion Models [SEED]\n- [claim] MD simulations CODE
MEDIUMtests/test_fulltext_web_mode.py320# --------- Integration tests: update_database orchestration ----------COMMENT
MEDIUMtests/test_webdav.py286# _webdav_first_attach (shell + PUT orchestration)COMMENT
MEDIUMtests/test_trashed_collections.py23# Test scaffoldingCOMMENT
MEDIUMtests/test_identifier_lock.py217# removed (proving nothing) or deadlocked on its own scaffolding. A flaky orCOMMENT
MEDIUMsrc/zotero_mcp/setup_helper.py240 # Choose embedding modelCOMMENT
MEDIUMsrc/zotero_mcp/chroma_client.py542 # Pick the embedding model. config.json is the richer, authoritative sourceCOMMENT
MEDIUMsrc/zotero_mcp/semantic_search.py2861 # Truncate to fit the configured embedding model's token limitCOMMENT
MEDIUMsrc/zotero_mcp/tools/search.py1519 # guard, but neither loads an embedding model or a Zotero client.COMMENT
MEDIUMsrc/zotero_mcp/tools/search.py1533 # Read status without loading any embedding model (fast, no network).COMMENT
Cross-File Repetition7 hits · 35 pts
SeverityFileLineSnippetContext
HIGHtests/test_issue_372_pdf_tools.py0create table items ( itemid integer primary key, itemtypeid int, dateadded text, datemodified text, clientdatemodified tSTRING
HIGHtests/test_fulltext_sync_watermark.py0create table items ( itemid integer primary key, itemtypeid int, dateadded text, datemodified text, clientdatemodified tSTRING
HIGHtests/test_collection_scope_expansion.py0create table items ( itemid integer primary key, itemtypeid int, dateadded text, datemodified text, clientdatemodified tSTRING
HIGHtests/test_linked_file_attachment_download.py0create table items ( itemid integer primary key, itemtypeid int, dateadded text, datemodified text, clientdatemodified tSTRING
HIGHsrc/zotero_mcp/openai_batch.py0submit ``adapter``'s pending chunks while they fit the enqueued-token budget. returns the number of newly submitted chunSTRING
HIGHsrc/zotero_mcp/gemini_batch.py0submit ``adapter``'s pending chunks while they fit the enqueued-token budget. returns the number of newly submitted chunSTRING
HIGHsrc/zotero_mcp/batch_common.py0submit ``adapter``'s pending chunks while they fit the enqueued-token budget. returns the number of newly submitted chunSTRING
AI Slop Vocabulary11 hits · 31 pts
SeverityFileLineSnippetContext
MEDIUM…ents/library-graph-validation/data/graph_contexts.json3 "C": "### AlphaFold Meets Flow Matching for Generating Protein Ensembles [via-traversal]\n- [claim] Score-matching CODE
MEDIUM…ents/library-graph-validation/data/graph_contexts.json49 "C": "### Protein Conformation Generation via Force-Guided SE(3) Diffusion Models [SEED]\n- [claim] MD simulations CODE
MEDIUM…ents/library-graph-validation/data/graph_contexts.json89 "C": "### Diffusion Schr\u00f6dinger Bridge Matching [SEED]\n- [claim] Unlike DDMs and Flow Matching Models, which CODE
MEDIUM…ents/library-graph-validation/data/graph_contexts.json133 "C": "### A DNA language model based on multispecies alignment predicts the effects of genome-wide variants [SEED]\CODE
MEDIUM…ents/library-graph-validation/data/graph_contexts.json133 "C": "### A DNA language model based on multispecies alignment predicts the effects of genome-wide variants [SEED]\CODE
MEDIUMtests/test_rate_limiter.py317 """on_success must be robust to missing, empty, non-numeric, or zero-limit headers."""STRING
MEDIUMsrc/zotero_mcp/skill_install.py243 # The command reference does NOT go in the rules directory. A harness thatCOMMENT
MEDIUMsrc/zotero_mcp/skill_install.py293#: Every supported harness: how to detect it, and how to install into it.COMMENT
MEDIUMsrc/zotero_mcp/skill_install.py295#: `detect` answers "is this harness in use here?" from what is on disk. It isCOMMENT
MEDIUMsrc/zotero_mcp/skill_install.py296#: deliberately generous — a directory or file the harness owns is enough,COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py2193 # changes. The robust fix is the same one noted in add_by_doi'sCOMMENT
Cross-Language Confusion5 hits · 28 pts
SeverityFileLineSnippetContext
HIGHtests/test_sql_search_backend.py218 result = reader.search_items_sql("quantum", item_type="book || journalArticle", group_id=0)CODE
HIGHtests/test_better_bibtex_client.py150 """BBT answers ``{"KEY": null}`` — a *successful* RPC carrying no key —STRING
HIGHtests/test_bibtex_never_empty.py9``{"KGBSSZ3W": null}`` — a successful RPC carrying no key. ``export_bibtex``STRING
HIGHtests/test_global_search.py242 pipes = reader.search_items_sql("Paper", tag=["methods || methodology"], limit=50)CODE
HIGHsrc/zotero_mcp/tools/_helpers.py457 # A bare JSON scalar (int/float/bool/null) — e.g. an all-digitCOMMENT
Self-Referential Comments9 hits · 27 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_regression_bugs.py192 # Create a dummy fileCOMMENT
MEDIUMsrc/zotero_mcp/client.py251 # 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.py113# Create an MCP server (fastmcp 2.14+ no longer accepts `dependencies`)COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py4348 # Create the metadata item. With if_exists='file' and a known DOI,COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py4362 # Create a basic itemCOMMENT
MEDIUMsrc/zotero_mcp/tools/retrieval.py389 # Create a mapping of collection IDs to their dataCOMMENT
MEDIUMsrc/zotero_mcp/tools/retrieval.py392 # Create a mapping of parent to child collectionsCOMMENT
MEDIUMsrc/zotero_mcp/tools/annotations.py1732 # Create the annotation using web clientCOMMENT
Modern Structural Boilerplate21 hits · 22 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/config.py21logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/config_light.py29logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/identifiers.py24__all__ = ["normalize_doi"]CODE
LOWsrc/zotero_mcp/client.py39logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/client.py134def set_active_library(library_id: str, library_type: str) -> None:CODE
LOWsrc/zotero_mcp/__init__.py14__all__ = ["__version__", "mcp"]CODE
LOWsrc/zotero_mcp/updater.py23logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/local_db.py32logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/chroma_client.py42logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/chroma_client.py487 def update_metadatas(self, ids: list[str], metadatas: list[dict[str, Any]]) -> None:CODE
LOWsrc/zotero_mcp/fulltext_cache.py47logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/gemini_batch.py46logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/extract.py27logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/scite_client.py19logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/semantic_search.py50logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/tools/scite.py28logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/embeddings/__init__.py22__all__ = ["BaseEmbeddingFunction"]CODE
LOWsrc/zotero_mcp/embeddings/base.py54logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/embeddings/providers/__init__.py32logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/embeddings/providers/__init__.py34__all__ = [CODE
LOWsrc/zotero_mcp/embeddings/providers/huggingface.py11logger = logging.getLogger(__name__)CODE
Magic Placeholder Names4 hits · 20 pts
SeverityFileLineSnippetContext
HIGHREADME.md335 "ZOTERO_API_KEY": "YOUR_API_KEY",CODE
HIGHREADME.md349 - Click [here](https://www.zotero.org/settings/security#applications) to generate a Zotero API key and replace `YOUR_CODE
HIGHREADME.md420zotero-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
Over-Commented Block28 hits · 18 pts
SeverityFileLineSnippetContext
LOWpyproject.toml21dependencies = [COMMENT
LOWtests/test_identifier_lock.py201 t = threading.Thread(target=holder)COMMENT
LOWtests/live/conftest.py121# server, or a paid provider API using the machine's production config)COMMENT
LOWsrc/zotero_mcp/client.py41# Load environment variablesCOMMENT
LOWsrc/zotero_mcp/setup_helper.py481 extraction_config = dict(COMMENT
LOWsrc/zotero_mcp/local_db.py41# therefore does not widen what the index sees; it only stops extractionCOMMENT
LOWsrc/zotero_mcp/local_db.py221#COMMENT
LOWsrc/zotero_mcp/local_db.py281# returning it) — so a condition needs a DIFFERENT substring depending on theCOMMENT
LOWsrc/zotero_mcp/local_db.py1301COMMENT
LOWsrc/zotero_mcp/cli.py1161 # Ensure environment is initialized (Claude config or standalone config)COMMENT
LOWsrc/zotero_mcp/chroma_client.py541COMMENT
LOWsrc/zotero_mcp/semantic_search.py201 max_chars = max_tokens * 2COMMENT
LOWsrc/zotero_mcp/semantic_search.py1361 # is safe to write: it extracts under the *indexing* pageCOMMENT
LOWsrc/zotero_mcp/semantic_search.py2361 # (_prepare_index_records) and has no chunking step, so a configCOMMENT
LOWsrc/zotero_mcp/tools/write.py1581 # held the lock across the ENTIRE recursive multi-DOI loop, one PDFCOMMENT
LOWsrc/zotero_mcp/tools/write.py1681 # holding several of them at once deadlock-free.COMMENT
LOWsrc/zotero_mcp/tools/write.py1921 create_missing_collections: bool = False,COMMENT
LOWsrc/zotero_mcp/tools/write.py2281 # arXiv always has a free PDF — try to attach it. Outside the lock: theCOMMENT
LOWsrc/zotero_mcp/tools/write.py3921COMMENT
LOWsrc/zotero_mcp/tools/write.py3941# prints — is noise to be discarded (#455).COMMENT
LOWsrc/zotero_mcp/tools/search.py1001 # SQLite backend evaluates the identical rules — see that module'sCOMMENT
LOWsrc/zotero_mcp/tools/search.py1041 "and global search has no fallback — the client-side path "COMMENT
LOWsrc/zotero_mcp/tools/_helpers.py21from zotero_mcp import client as _clientCOMMENT
LOWsrc/zotero_mcp/tools/_helpers.py841 # failure here degrades to "no match" and the caller creates the item,COMMENT
LOWsrc/zotero_mcp/tools/_helpers.py921# fetch now sits between the dedup check and the create, so two callers canCOMMENT
LOWsrc/zotero_mcp/embeddings/providers/gemini.py21 # task instruction in the prompt text itself, which empirically shiftsCOMMENT
LOWsrc/zotero_mcp/embeddings/providers/gemini.py41 # prefix tokens are reserved separately (see V2_PREFIX_TOKEN_BUDGET).COMMENT
LOWsrc/zotero_mcp/embeddings/providers/openai.py21 """COMMENT
Redundant / Tautological Comments11 hits · 17 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.py468 # Check if update is needed. Only a strictly newer release counts — aCOMMENT
LOWsrc/zotero_mcp/cli.py711 # Check if installed via uvCOMMENT
LOWsrc/zotero_mcp/chroma_client.py103 # Check if the stored config matches what we want; if not, recreate.COMMENT
LOWsrc/zotero_mcp/tools/write.py4757 # Check if relation already exists (match both URI prefix variants)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py257 # Check if Zotero with Better BibTeX is runningCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py1299 # Check if creation was successfulCOMMENT
LOWsrc/zotero_mcp/tools/annotations.py1735 # Check if creation was successfulCOMMENT
Structural Annotation Overuse8 hits · 16 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.py268 # Step 1: Get citation key from item key. BBT's JSON-RPC expectsCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py286 # Step 2: Export BibTeX using the citation key.COMMENT
LOWsrc/zotero_mcp/tools/annotations.py799 # Step 2: Batch-fetch the grandparents (papers)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py823 # Step 3: Map immediate parent keys to stable paper/attachment context.COMMENT
LOWsrc/zotero_mcp/tools/annotations.py768 # Step 1: Batch-fetch the immediate parents (attachments)COMMENT
AI Structural Patterns13 hits · 9 pts
SeverityFileLineSnippetContext
LOWtests/test_update_item.py13CODE
LOWtests/test_update_item.py59CODE
LOWtests/test_update_item.py86CODE
LOWtests/test_update_item.py122CODE
LOWtests/test_remote_embedding_base.py142CODE
LOWsrc/zotero_mcp/utils.py450CODE
LOWsrc/zotero_mcp/semantic_search.py2155CODE
LOWsrc/zotero_mcp/tools/write.py831CODE
LOWsrc/zotero_mcp/tools/write.py3730CODE
LOWsrc/zotero_mcp/embeddings/ratelimit.py62CODE
LOWsrc/zotero_mcp/embeddings/providers/gemini.py70CODE
LOWsrc/zotero_mcp/embeddings/providers/openai.py56CODE
LOWsrc/zotero_mcp/embeddings/providers/ollama.py43CODE
Verbosity Indicators5 hits · 9 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/better_bibtex_client.py268 # Step 1: Get citation key from item key. BBT's JSON-RPC expectsCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py286 # Step 2: Export BibTeX using the citation key.COMMENT
LOWsrc/zotero_mcp/tools/annotations.py799 # Step 2: Batch-fetch the grandparents (papers)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py823 # Step 3: Map immediate parent keys to stable paper/attachment context.COMMENT
LOWsrc/zotero_mcp/tools/annotations.py768 # Step 1: Batch-fetch the immediate parents (attachments)COMMENT
Fake / Example Data5 hits · 6 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.py104 "authors": ["Jane Doe"],CODE
LOWtests/test_batch_crossref.py110 monkeypatch.setenv("ZOTERO_MCP_CONTACT_EMAIL", "me@example.org")CODE
LOWtests/test_batch_crossref.py115 assert calls[0]["params"]["mailto"] == "me@example.org"CODE
Docstring Block Structure1 hit · 5 pts
SeverityFileLineSnippetContext
HIGHsrc/zotero_mcp/better_bibtex_client.py250 Export BibTeX for a specific item using its item key. Args: item_key: Zotero item key to eSTRING
Dead Code1 hit · 2 pts
SeverityFileLineSnippetContext
MEDIUMsrc/zotero_mcp/local_db.py1039CODE