AI Slop Code RIsk Monitor

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.

57.0 High pattern signal View on GitHub

Maintenance and Governance Review

This report summarizes scanner evidence for 54yyyu/zotero-mcp, a Python project with 5,318 GitHub stars. SynthScan examined 134,893 lines of code across 464 source files, recording 4897 pattern matches distributed across 20 syntactic categories. The legacy adjusted pattern signal is 57.0 (High pattern signal); it is not an authorship estimate.

Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.

57.0
Adjusted Signal
57.0
Raw Pattern Score
100%
Time Factor
2026-10-08
Last Push
5.3K
Stars
Python
Language
134.9K
Lines of Code
464
Files
4.9K
Pattern Hits
2026-10-12
Scan Date
0.20
HC Hit Rate

Risk Review · v3

Use each vector to guide manual verification of the underlying findings.

Cognitive Ownership Risk 68.1/100 · HIGH

Can maintainers explain intent, assumptions, and trade-offs? 3119 finding(s).

Hallucinated Dependency & Supply Chain Risk 7.7/100 · LOW

Are imports declared and package/API names verified? 233 finding(s).

Agent Over-Engineering Ratio 93.2/100 · CRITICAL

Are wrappers, guards, and repeated structures necessary? 4439 finding(s).

PR Review Velocity Impact 93.7/100 · CRITICAL

Which changes need focused human review? 4897 finding(s).

What These Metrics Mean

Adjusted Signal
Legacy pattern score normalized per 1,000 scanned lines and multiplied by the repository-level time factor. It is not an estimate of AI authorship.
Raw Pattern Score
Sum of severity- and context-weighted pattern findings before applying the time factor.
Time Factor
A coarse multiplier based on repository last-push metadata. It does not identify when individual code was written.
Pattern Hits
Count of configured pattern findings. Review each location and surrounding code before acting.
HC Hit Rate
High- and critical-severity findings per scanned file. Severity is a configured detector weight, not proof of a vulnerability or authorship.
Lines / Files
Scan coverage denominators used by the legacy normalized score.

Pattern-Signal History

This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.

Severity Breakdown

Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.

CRITICAL 0HIGH 95MEDIUM 1037LOW 3765

Directory Score Breakdown

This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.

Pattern Findings

The scanner identified 4897 distinct pattern matches across 20 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. 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 configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.

Decorative Section Separators976 hits · 3577 pts
SeverityFileLineSnippetContext
MEDIUM⚡tests/test_page_layout.py48# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_page_layout.py50# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_page_layout.py110# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_page_layout.py112# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_page_layout.py212# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/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
MEDIUM⚡tests/test_scite.py37# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_scite.py39# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_scite.py58# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_scite.py60# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_scite.py123# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_scite.py126# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_fulltext_cache.py186# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_fulltext_cache.py188# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_citation_import.py117# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/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.py223# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py225# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py259# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py261# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py699# ---------------------------------------------------------------------------COMMENT
MEDIUMtests/test_citation_import.py701# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_citation_import.py442# ---------------------------------------------------------------------------STRING
MEDIUM⚡tests/test_citation_import.py450# ---------------------------------------------------------------------------STRING
MEDIUM⚡tests/test_citation_import.py593# ---------------------------------------------------------------------------STRING
MEDIUM⚡tests/test_citation_import.py595# ---------------------------------------------------------------------------STRING
MEDIUM⚡tests/test_citation_import.py627# ---------------------------------------------------------------------------STRING
MEDIUM⚡tests/test_citation_import.py629# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py352# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py354# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py646# ---------------------------------------------------------------------------STRING
MEDIUMtests/test_citation_import.py648# ---------------------------------------------------------------------------STRING
MEDIUM⚡tests/test_shared_helpers.py13# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py15# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py59# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py61# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py81# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py83# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py111# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py113# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py174# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py176# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py219# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py221# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py298# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py300# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py348# ---------------------------------------------------------------------------COMMENT
MEDIUM⚡tests/test_shared_helpers.py350# ---------------------------------------------------------------------------COMMENT
916 more matches not shown…
Hyper-Verbose Identifiers2882 hits · 2828 pts
SeverityFileLineSnippetContext
LOW⚡tests/test_attach_verification.py79 def test_none_when_attachment_registered(self):CODE
LOW⚡tests/test_attach_verification.py82 def test_none_for_unchanged_entry(self):CODE
LOW⚡tests/test_attach_verification.py86 def test_reports_failure_payload(self):CODE
LOW⚡tests/test_attach_verification.py91 def test_reports_empty_result(self):CODE
LOW⚡tests/test_attach_verification.py95 def test_reports_result_with_no_key(self):CODE
LOW⚡tests/test_attach_verification.py101 def test_rejects_unauthorized_local_client(self):CODE
LOW⚡tests/test_attach_verification.py108 def test_allows_authorized_local_client(self):CODE
LOWtests/test_attach_verification.py123 def test_success_passes_through_key(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py133 def test_failed_upload_falls_back_to_two_step(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py146 def test_reports_failure_when_two_step_also_fails(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py162 def test_orphan_shell_deleted_when_upload_fails(self, dummy_ctx, monkeypatch):CODE
LOWtests/test_attach_verification.py176 def test_unauthorized_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
LOW⚡tests/test_default_read_backend.py24def test_unset_follows_local_mode(unset, monkeypatch, local, expected):CODE
LOW⚡tests/test_default_read_backend.py29def test_explicit_api_opts_out_in_local_mode(unset, monkeypatch):CODE
LOW⚡tests/test_default_read_backend.py36def test_explicit_sqlite_wins(unset, monkeypatch, var):CODE
LOW⚡tests/test_default_read_backend.py67def test_unsupported_query_is_answered_by_the_api():CODE
LOW⚡tests/test_default_read_backend.py74def test_supported_query_never_builds_the_api_client():CODE
LOW⚡tests/test_default_read_backend.py82def test_a_real_failure_is_not_hidden_by_the_fallback():CODE
LOW⚡tests/test_default_read_backend.py88def test_get_library_backend_wraps_sqlite_with_the_fallback(monkeypatch):CODE
LOW⚡tests/test_page_layout.py53 def test_figure_caption_with_colon(self):CODE
LOW⚡tests/test_page_layout.py60 def test_figure_caption_with_period(self):CODE
LOW⚡tests/test_page_layout.py66 def test_fig_abbreviation_with_panel_letter(self):CODE
LOW⚡tests/test_page_layout.py78 def test_supplementary_table_caption(self):CODE
LOW⚡tests/test_page_layout.py84 def test_extended_data_figure_caption(self):CODE
LOW⚡tests/test_page_layout.py90 def test_in_text_reference_rejected(self):CODE
LOW⚡tests/test_page_layout.py94 def test_sentence_starting_with_figure_rejected(self):CODE
LOW⚡tests/test_page_layout.py104 def test_caption_is_case_insensitive(self):CODE
LOW⚡tests/test_page_layout.py180 def test_merges_vertically_adjacent_fragments(self):CODE
LOW⚡tests/test_page_layout.py189 def test_keeps_distant_regions_separate(self):CODE
LOW⚡tests/test_page_layout.py197 def test_dedupes_same_area_keeping_table(self):CODE
LOW⚡tests/test_page_layout.py221 def test_figure_caption_below_figure(self):CODE
LOW⚡tests/test_page_layout.py231 def test_table_caption_above_table(self):CODE
LOW⚡tests/test_page_layout.py240 def test_caption_too_far_not_attached(self):CODE
LOW⚡tests/test_page_layout.py250 def test_two_column_caption_not_cross_attached(self):CODE
LOW⚡tests/test_page_layout.py260 def test_caption_attaches_to_nearest_of_two_stacked_figures(self):CODE
LOW⚡tests/test_page_layout.py708 def test_rejects_invalid_page_number(self, monkeypatch, fake_zot):CODE
LOW⚡tests/test_page_layout.py718 def test_requires_a_zotero_client(self, monkeypatch):CODE
LOW⚡tests/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
2822 more matches not shown…
Excessive Try-Catch Wrapping459 hits · 383 pts
SeverityFileLineSnippetContext
LOWtests/test_stringified_params.py44 except Exception:CODE
LOW⚡tests/test_stringified_params.py117 except Exception as exc:CODE
LOW⚡tests/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
LOW⚡tests/test_ollama_embedding.py72 except Exception:CODE
LOWtests/test_embedding_function_registration.py132 except Exception:CODE
LOWtests/test_description_tokens.py109 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.py101 except Exception:CODE
LOWtests/live/conftest.py168 except Exception as exc:CODE
LOWtests/live/conftest.py173 except Exception as exc:CODE
LOWtests/live/conftest.py247 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
LOWtests/live/test_sqlite_only_reads.py72 except Exception as exc:CODE
LOWscripts/check_openai_ratelimits.py46 except Exception as e:CODE
LOWscripts/check_openai_ratelimits.py132 except Exception as e:CODE
LOWscripts/measure_read_backend.py114 except Exception as exc:CODE
LOWsrc/zotero_mcp/library.py153 except Exception:CODE
LOWsrc/zotero_mcp/library.py312 except Exception:CODE
LOWsrc/zotero_mcp/library.py336 except Exception:CODE
LOWsrc/zotero_mcp/library.py347 except Exception:CODE
LOWsrc/zotero_mcp/library.py357 except Exception:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py126 except Exception:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py150 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py194 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py248 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py322 except Exception as e:CODE
LOWsrc/zotero_mcp/better_bibtex_client.py404 except Exception as e:CODE
LOWsrc/zotero_mcp/pdf_utils.py399 except Exception:CODE
LOWsrc/zotero_mcp/pdf_utils.py789 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.py272 except Exception:CODE
LOWsrc/zotero_mcp/client.py364 except Exception:CODE
LOWsrc/zotero_mcp/client.py512 except Exception:CODE
LOWsrc/zotero_mcp/client.py836 except Exception:CODE
LOWsrc/zotero_mcp/client.py943 except Exception as e:CODE
LOWsrc/zotero_mcp/client.py1064 except Exception:CODE
LOWsrc/zotero_mcp/client.py1149 except Exception:CODE
LOWsrc/zotero_mcp/client.py1228 except Exception as exc:CODE
LOWsrc/zotero_mcp/client.py1247 except Exception as exc:CODE
LOWsrc/zotero_mcp/client.py1278 except Exception as exc:CODE
MEDIUM⚡src/zotero_mcp/setup_helper.py569 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.py613 print(f"Error: Config file at {config_path} is not valid JSON. Creating new config.")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py677 print(f"Error writing config file: {str(e)}")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py786 print("Error: Could not find zotero-mcp executable.")CODE
MEDIUMsrc/zotero_mcp/setup_helper.py799 print("Error: Could not determine Claude Desktop config path.")CODE
LOW⚡src/zotero_mcp/setup_helper.py568 except Exception as e:CODE
LOW⚡src/zotero_mcp/setup_helper.py579 except Exception:CODE
LOWsrc/zotero_mcp/setup_helper.py93 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py595 except Exception as e:CODE
LOWsrc/zotero_mcp/setup_helper.py676 except Exception as e:CODE
399 more matches not shown…
Empty Error Handlers77 hits · 378 pts
SeverityFileLineSnippetContext
HIGHtests/test_ollama_embedding.py72except Exception:CODE
HIGHtests/test_embedding_function_registration.py132except Exception:CODE
HIGHscripts/check_openai_ratelimits.py178except ValueError:CODE
HIGHscripts/check_openai_ratelimits.py185except ValueError:CODE
HIGHsrc/zotero_mcp/config.py153except (json.JSONDecodeError, OSError):CODE
HIGHsrc/zotero_mcp/library.py153except Exception:CODE
HIGHsrc/zotero_mcp/pdf_utils.py789except Exception:CODE
HIGHsrc/zotero_mcp/html_metadata.py164except Exception:CODE
HIGHsrc/zotero_mcp/client.py272except Exception:CODE
HIGHsrc/zotero_mcp/client.py1149except Exception:CODE
HIGHsrc/zotero_mcp/client.py1276except WebDAVNotConfiguredError:CODE
HIGHsrc/zotero_mcp/setup_helper.py38except OSError:CODE
HIGHsrc/zotero_mcp/setup_helper.py880except Exception:CODE
HIGHsrc/zotero_mcp/cli_standalone.py544except _cli_json.CliError:CODE
HIGHsrc/zotero_mcp/updater.py117except Exception:CODE
HIGHsrc/zotero_mcp/updater.py389except (OSError, ValueError, AttributeError):CODE
HIGHsrc/zotero_mcp/updater.py849except Exception:CODE
HIGHsrc/zotero_mcp/updater.py146except Exception:CODE
HIGHsrc/zotero_mcp/updater.py72except Exception:CODE
HIGHsrc/zotero_mcp/updater.py88except Exception:CODE
HIGHsrc/zotero_mcp/updater.py590except Exception:CODE
HIGHsrc/zotero_mcp/batch_common.py111except OSError:CODE
HIGHsrc/zotero_mcp/_context.py31except Exception:CODE
HIGHsrc/zotero_mcp/cli.py204except Exception:CODE
HIGHsrc/zotero_mcp/cli.py405except Exception:CODE
HIGHsrc/zotero_mcp/cli.py357except Exception:CODE
HIGHsrc/zotero_mcp/cli.py719except (AttributeError, ValueError, OSError):CODE
HIGHsrc/zotero_mcp/utils.py70except OSError:CODE
HIGHsrc/zotero_mcp/utils.py208except Exception:CODE
HIGHsrc/zotero_mcp/chroma_client.py138except Exception:CODE
HIGHsrc/zotero_mcp/pdf_layout.py648except Exception:CODE
HIGHsrc/zotero_mcp/pdf_layout.py711except Exception:CODE
HIGHsrc/zotero_mcp/pdf_layout.py726except Exception:CODE
HIGHsrc/zotero_mcp/pdf_layout.py661except Exception:CODE
HIGHsrc/zotero_mcp/pdf_layout.py692except Exception:CODE
HIGHsrc/zotero_mcp/fulltext_cache.py60except OSError:CODE
HIGHsrc/zotero_mcp/schema.py107except OSError:CODE
HIGHsrc/zotero_mcp/schema.py114except OSError:CODE
HIGHsrc/zotero_mcp/semantic_search.py124except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py333except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2083except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2122except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py1539except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2770except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2933except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py3076except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2118except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2779except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2811except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py3022except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py3062except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py3438except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py3472except queue.Empty:CODE
HIGHsrc/zotero_mcp/semantic_search.py1638except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py1643except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py1902except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2293except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py1720except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2688except Exception:CODE
HIGHsrc/zotero_mcp/semantic_search.py2520except Exception:CODE
17 more matches not shown…
Unused Imports218 hits · 158 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_local_note_search_scope.py12CODE
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.py6CODE
LOWtests/test_add_from_file.py7CODE
LOWtests/test_add_from_file.py7CODE
LOWtests/test_add_from_file.py10CODE
LOWtests/test_add_from_file.py10CODE
LOWtests/test_update_item.py3CODE
LOWtests/test_token_optimization.py4CODE
LOWtests/test_token_optimization.py6CODE
LOWtests/test_v021_fixes.py8CODE
LOWtests/test_v021_fixes.py11CODE
LOWtests/test_add_by_doi.py4CODE
LOWtests/test_api_lock_bounded.py14CODE
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_tool_descriptions_name_registered_tools.py13CODE
LOWtests/test_regression_bugs.py8CODE
LOWtests/test_semantic_search_filters_example.py13CODE
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
LOWscripts/measure_read_backend.py39CODE
LOWscripts/profile_recent_items.py32CODE
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
158 more matches not shown…
Deep Nesting134 hits · 84 pts
SeverityFileLineSnippetContext
LOWtests/test_chroma_client_real.py369CODE
LOWtests/test_rate_limiter.py326CODE
LOWtests/test_rate_limiter.py341CODE
LOWtests/live/_discovery.py31CODE
LOWscripts/gen_skill_reference.py67CODE
LOWsrc/zotero_mcp/webdav.py222CODE
LOWsrc/zotero_mcp/note_html.py134CODE
LOWsrc/zotero_mcp/library.py318CODE
LOWsrc/zotero_mcp/library.py363CODE
LOWsrc/zotero_mcp/library.py473CODE
LOWsrc/zotero_mcp/better_bibtex_client.py129CODE
LOWsrc/zotero_mcp/better_bibtex_client.py252CODE
LOWsrc/zotero_mcp/config_light.py57CODE
LOWsrc/zotero_mcp/client.py898CODE
LOWsrc/zotero_mcp/toolsets.py148CODE
LOWsrc/zotero_mcp/setup_helper.py110CODE
LOWsrc/zotero_mcp/setup_helper.py214CODE
LOWsrc/zotero_mcp/setup_helper.py532CODE
LOWsrc/zotero_mcp/setup_helper.py600CODE
LOWsrc/zotero_mcp/setup_helper.py727CODE
LOWsrc/zotero_mcp/pdfannots_downloader.py136CODE
LOWsrc/zotero_mcp/cli_standalone.py243CODE
LOWsrc/zotero_mcp/cli_standalone.py300CODE
LOWsrc/zotero_mcp/cli_standalone.py426CODE
LOWsrc/zotero_mcp/cli_standalone.py524CODE
LOWsrc/zotero_mcp/cli_standalone.py634CODE
LOWsrc/zotero_mcp/cli_standalone.py701CODE
LOWsrc/zotero_mcp/cli_standalone.py756CODE
LOWsrc/zotero_mcp/cli_standalone.py869CODE
LOWsrc/zotero_mcp/updater.py46CODE
LOWsrc/zotero_mcp/updater.py123CODE
LOWsrc/zotero_mcp/updater.py495CODE
LOWsrc/zotero_mcp/updater.py681CODE
LOWsrc/zotero_mcp/local_db.py755CODE
LOWsrc/zotero_mcp/local_db.py813CODE
LOWsrc/zotero_mcp/local_db.py2359CODE
LOWsrc/zotero_mcp/local_db.py2579CODE
LOWsrc/zotero_mcp/epub_utils.py471CODE
LOWsrc/zotero_mcp/epub_utils.py702CODE
LOWsrc/zotero_mcp/cli.py67CODE
LOWsrc/zotero_mcp/cli.py723CODE
LOWsrc/zotero_mcp/utils.py176CODE
LOWsrc/zotero_mcp/chroma_client.py51CODE
LOWsrc/zotero_mcp/chroma_client.py276CODE
LOWsrc/zotero_mcp/citation_import.py198CODE
LOWsrc/zotero_mcp/citation_import.py225CODE
LOWsrc/zotero_mcp/citation_import.py395CODE
LOWsrc/zotero_mcp/citation_import.py600CODE
LOWsrc/zotero_mcp/pdf_layout.py164CODE
LOWsrc/zotero_mcp/pdf_layout.py248CODE
LOWsrc/zotero_mcp/pdf_layout.py356CODE
LOWsrc/zotero_mcp/pdf_layout.py452CODE
LOWsrc/zotero_mcp/fulltext_cache.py217CODE
LOWsrc/zotero_mcp/gemini_batch.py277CODE
LOWsrc/zotero_mcp/extract.py169CODE
LOWsrc/zotero_mcp/extract.py443CODE
LOWsrc/zotero_mcp/extract.py490CODE
LOWsrc/zotero_mcp/semantic_search.py489CODE
LOWsrc/zotero_mcp/semantic_search.py873CODE
LOWsrc/zotero_mcp/semantic_search.py1210CODE
74 more matches not shown…
Modern AI Meta-Vocabulary15 hits · 46 pts
SeverityFileLineSnippetContext
MEDIUMCHANGELOG.md21- **Tables without closing tags no longer flood HTML extraction with empty cells** (#687). `html.parser` nests an untermCODE
MEDIUMCHANGELOG.md446- **`update-db` no longer accepts `chunking.enabled` in silence on the OpenAI Batch API path (#416).** The batch path buCODE
MEDIUM⚡tests/test_chroma_persist_directory.py31 "1", # default embedding modelCODE
MEDIUMtests/test_fulltext_web_mode.py344# --------- Integration tests: update_database orchestration ----------COMMENT
MEDIUM⚡tests/test_webdav.py286# _webdav_first_attach (shell + PUT orchestration)COMMENT
MEDIUM⚡tests/test_trashed_collections.py23# Test scaffoldingCOMMENT
MEDIUM⚡tests/test_identifier_lock.py217# removed (proving nothing) or deadlocked on its own scaffolding. A flaky orCOMMENT
MEDIUMtests/test_extract.py262 # Five columns is past the scaffolding run length: a header with textCOMMENT
MEDIUMsrc/zotero_mcp/setup_helper.py247 # Choose embedding modelCOMMENT
MEDIUMsrc/zotero_mcp/chroma_client.py566 # Pick the embedding model. config.json is the richer, authoritative sourceCOMMENT
MEDIUMsrc/zotero_mcp/extract.py436#: A run of four or more empty (or ``---``) table cells is layout scaffolding.COMMENT
MEDIUMsrc/zotero_mcp/semantic_search.py3204 # Truncate to fit the configured embedding model's token limitCOMMENT
MEDIUMsrc/zotero_mcp/tools/write.py1451 # the embedding model in semantic_search, which reads "<i>" as tokensCOMMENT
MEDIUMsrc/zotero_mcp/tools/search.py1670 # guard, but neither loads an embedding model or a Zotero client.COMMENT
MEDIUMsrc/zotero_mcp/tools/search.py1684 # Read status without loading any embedding model (fast, no network).COMMENT
Cross-Language Confusion7 hits · 38 pts
SeverityFileLineSnippetContext
HIGH⚡tests/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
HIGH⚡tests/test_global_search.py242 pipes = reader.search_items_sql("Paper", tag=["methods || methodology"], limit=50)CODE
HIGH⚡src/zotero_mcp/library.py277 "filter, or a boolean itemType expression like 'book || journalArticle'"CODE
HIGHsrc/zotero_mcp/tools/search.py151 or `a || b`. Returns None when a filter cannot be honoured here (a `*` orSTRING
HIGHsrc/zotero_mcp/tools/_helpers.py867 # A bare JSON scalar (int/float/bool/null) — e.g. an all-digitCOMMENT
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
Over-Commented Block41 hits · 27 pts
SeverityFileLineSnippetContext
LOWpyproject.toml21dependencies = [COMMENT
LOWpyproject.toml41 # HTML snapshots only.COMMENT
LOWtests/test_citation_import.py441COMMENT
LOWtests/test_identifier_lock.py201 t = threading.Thread(target=holder)COMMENT
LOWtests/live/conftest.py121# provider / fault-injection / Chroma-roundtrip live tests). The half above isCOMMENT
LOWplugin/src/ui/markdown.ts1// Markdown to a small node tree. PURE: no DOM, so it runs under `node --test` and the XSS corpus canCOMMENT
LOWplugin/src/ui/diagram-svg.ts1// Diagrams, the pure half: the agent's ```svg text to a small, safe element tree. No DOM, so it runs underCOMMENT
LOWplugin/src/agent/backends.ts1// Which coding agent answers: a small table of ACP bridges, one entry per vendor. An entry is aCOMMENT
LOWplugin/src/agent/session.ts1// One conversation with an agent: the ACP session on top of an AcpClient, translated into ChatEvents.COMMENT
LOWplugin/src/agent/session.ts261 #catalog: Offers;COMMENT
LOWsrc/zotero_mcp/library.py321 for start in range(0, len(keys), self._ITEMKEY_BATCH):COMMENT
LOWsrc/zotero_mcp/identifiers.py241 m = _ARXIV_EXTRA_RE.search(extra or "")COMMENT
LOWsrc/zotero_mcp/local_db.py41# the ``pdf_max_pages`` extraction config or ``ZOTERO_PDF_MAXPAGES``.COMMENT
LOWsrc/zotero_mcp/local_db.py261# ---------------------------------------------------------------------------COMMENT
LOWsrc/zotero_mcp/local_db.py281# separately since they're multi-valued).COMMENT
LOWsrc/zotero_mcp/local_db.py401 "itemType": "it.typeName",COMMENT
LOWsrc/zotero_mcp/local_db.py441 value_expr="SUBSTR(v.value, 1, 4)",COMMENT
LOWsrc/zotero_mcp/local_db.py881 )COMMENT
LOWsrc/zotero_mcp/local_db.py1861 # Restrict the corpus to the configured collections, includingCOMMENT
LOWsrc/zotero_mcp/local_db.py2661 variants = _generate_search_variants(query)COMMENT
LOWsrc/zotero_mcp/local_db.py3181 #COMMENT
LOWsrc/zotero_mcp/chroma_client.py561 file_config = json.load(f)COMMENT
LOWsrc/zotero_mcp/semantic_search.py361# one-time migration of existing documents. Version 2 (#163) added theCOMMENT
LOWsrc/zotero_mcp/semantic_search.py1561 ):COMMENT
LOWsrc/zotero_mcp/tools/write.py1441 item_data[field] = valueCOMMENT
LOWsrc/zotero_mcp/tools/write.py1821 """COMMENT
LOWsrc/zotero_mcp/tools/write.py1921 policy="thin_only" if is_batch else page_check,COMMENT
LOWsrc/zotero_mcp/tools/write.py2221 if_exists: Literal["duplicate", "file", "skip"] = "duplicate",COMMENT
LOWsrc/zotero_mcp/tools/write.py3221 item["data"] = dataCOMMENT
LOWsrc/zotero_mcp/tools/write.py4281# ---------------------------------------------------------------------------COMMENT
LOWsrc/zotero_mcp/tools/write.py4301# Child script. It imports ONLY PyMuPDF — never zotero_mcp — so the subprocessCOMMENT
LOWsrc/zotero_mcp/tools/search.py1141 return in_subtree if operation == "is" else not in_subtreeCOMMENT
LOWsrc/zotero_mcp/tools/search.py1261 if sort_field in {"date", "year", "publicationDate"}:COMMENT
LOWsrc/zotero_mcp/tools/_helpers.py61 return _client.load_zotero_mcp_config()COMMENT
LOWsrc/zotero_mcp/tools/_helpers.py241 return read_zot, write_zotCOMMENT
LOWsrc/zotero_mcp/tools/_helpers.py1361 # Measured at limit=50 a real book ('Stochastic Processes', 83COMMENT
LOWsrc/zotero_mcp/tools/_helpers.py1461# The Zotero API lock exists to protect the single-threaded local API on portCOMMENT
LOWsrc/zotero_mcp/tools/_helpers.py2321COMMENT
LOWsrc/zotero_mcp/embeddings/providers/gemini.py21 # task instruction in the prompt text itself, which empirically shiftsCOMMENT
LOWsrc/zotero_mcp/embeddings/providers/gemini.py41 # v2 models this value means "effective budget for the TEXT BODY" —COMMENT
LOWsrc/zotero_mcp/embeddings/providers/openai.py21 collides with the built-in, whose build_from_config rejects ourCOMMENT
Modern Structural Boilerplate26 hits · 26 pts
SeverityFileLineSnippetContext
LOW⚡src/zotero_mcp/config.py21logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/library.py44logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/better_bibtex_client.py14logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/config_light.py29logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/identifiers.py27__all__ = [CODE
LOWsrc/zotero_mcp/client.py45logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/client.py140def set_active_library(library_id: str, library_type: str) -> None:CODE
LOWsrc/zotero_mcp/__init__.py14__all__ = ["__version__", "mcp"]CODE
LOWsrc/zotero_mcp/pdfannots_downloader.py14logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/updater.py24logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/local_db.py38logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/chroma_client.py45logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/chroma_client.py511 def update_metadatas(self, ids: list[str], metadatas: list[dict[str, Any]]) -> None:CODE
LOWsrc/zotero_mcp/pdfannots_helper.py14logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/fulltext_cache.py49logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/gemini_batch.py46logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/extract.py32logger = logging.getLogger(__name__)CODE
LOW⚡src/zotero_mcp/scite_client.py19logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/semantic_search.py61logger = logging.getLogger(__name__)CODE
LOW⚡src/zotero_mcp/tools/scite.py28logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/embeddings/__init__.py22__all__ = ["BaseEmbeddingFunction"]CODE
LOWsrc/zotero_mcp/embeddings/ratelimit.py41logger = logging.getLogger(__name__)CODE
LOWsrc/zotero_mcp/embeddings/base.py58logger = 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
AI Slop Vocabulary7 hits · 26 pts
SeverityFileLineSnippetContext
MEDIUM⚡tests/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
MEDIUM⚡src/zotero_mcp/skill_install.py293#: Every supported harness: how to detect it, and how to install into it.COMMENT
MEDIUM⚡src/zotero_mcp/skill_install.py295#: `detect` answers "is this harness in use here?" from what is on disk. It isCOMMENT
MEDIUM⚡src/zotero_mcp/skill_install.py296#: deliberately generous — a directory or file the harness owns is enough,COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py2501 # changes. The robust fix is the same one noted in add_by_doi'sCOMMENT
MEDIUM⚡src/zotero_mcp/tools/read_pdf.py384# A line-break hyphenation ("robust-\nness") or a soft hyphen: "ness" is mid-word.COMMENT
Self-Referential Comments9 hits · 26 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_regression_bugs.py192 # Create a dummy fileCOMMENT
MEDIUMplugin/src/ui/create-skill.ts11# Create a skillCOMMENT
MEDIUMsrc/zotero_mcp/client.py349 # Create a local client - library_id 0 is the default for local.COMMENT
MEDIUMsrc/zotero_mcp/pdfannots_downloader.py158 # Create a temporary directory for the downloadCOMMENT
MEDIUMsrc/zotero_mcp/_app.py125# Create an MCP server (fastmcp 2.14+ no longer accepts `dependencies`)COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py4707 # Create the metadata item. With if_exists='file' and a known DOI,COMMENT
MEDIUMsrc/zotero_mcp/tools/write.py4724 # Create a basic itemCOMMENT
MEDIUMsrc/zotero_mcp/tools/retrieval.py450 # Create a mapping of collection IDs to their dataCOMMENT
MEDIUMsrc/zotero_mcp/tools/retrieval.py453 # Create a mapping of parent to child collectionsCOMMENT
Magic Placeholder Names3 hits · 15 pts
SeverityFileLineSnippetContext
HIGHdocs/getting-started.md56 export ZOTERO_API_KEY=your_api_keyCODE
HIGHdocs/getting-started.md86 "ZOTERO_API_KEY": "YOUR_API_KEY",CODE
HIGHdocs/configuration.md17zotero-mcp setup --no-local --api-key YOUR_API_KEY --library-id YOUR_LIBRARY_IDCODE
Redundant / Tautological Comments9 hits · 14 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/pdfannots_downloader.py72 # Check if we have a URL for this platform/architectureCOMMENT
LOW⚡src/zotero_mcp/updater.py63 # Check if we're in a uv-managed projectCOMMENT
LOW⚡src/zotero_mcp/updater.py78 # Check if we're in a uv virtual environmentCOMMENT
LOWsrc/zotero_mcp/updater.py102 # Check if pipx is availableCOMMENT
LOWsrc/zotero_mcp/updater.py721 # Check if update is needed. Only a strictly newer release counts — aCOMMENT
LOWsrc/zotero_mcp/cli.py1026 # Check if installed via uvCOMMENT
LOWsrc/zotero_mcp/chroma_client.py114 # Check if the stored config matches what we want; if not, recreate.COMMENT
LOWsrc/zotero_mcp/tools/write.py5120 # Check if relation already exists (match both URI prefix variants)COMMENT
LOWsrc/zotero_mcp/tools/annotations.py315 # Check if Zotero with Better BibTeX is runningCOMMENT
Structural Annotation Overuse6 hits · 12 pts
SeverityFileLineSnippetContext
LOW⚡docs/integration-test-plan.md551### Step 1: Verify all per-phase cleanups were doneCOMMENT
LOW⚡docs/integration-test-plan.md559### Step 2: Identify test-created itemsCOMMENT
LOW⚡docs/integration-test-plan.md565### Step 3: Tell the user to delete manuallyCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py271 # Step 1: Get citation key from item key. BBT's JSON-RPC expectsCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py289 # Step 2: Export BibTeX using the citation key.COMMENT
LOW⚡src/zotero_mcp/tools/annotations.py848 # Step 3: Map immediate parent keys to stable paper/attachment context.COMMENT
AI Structural Patterns12 hits · 8 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/semantic_search.py2525CODE
LOWsrc/zotero_mcp/tools/write.py839CODE
LOWsrc/zotero_mcp/tools/write.py4087CODE
LOWsrc/zotero_mcp/embeddings/ratelimit.py69CODE
LOWsrc/zotero_mcp/embeddings/providers/gemini.py71CODE
LOWsrc/zotero_mcp/embeddings/providers/openai.py58CODE
LOWsrc/zotero_mcp/embeddings/providers/ollama.py43CODE
Fake / Example Data5 hits · 6 pts
SeverityFileLineSnippetContext
LOW⚡tests/test_place_field_reads.py129 fake_data = {CODE
LOWtests/test_place_field_reads.py144 return {"key": key, "data": fake_data}CODE
LOWtests/test_add_by_isbn.py101 "authors": ["Jane Doe"],CODE
LOW⚡tests/test_batch_crossref.py110 monkeypatch.setenv("ZOTERO_MCP_CONTACT_EMAIL", "me@example.org")CODE
LOW⚡tests/test_batch_crossref.py115 assert calls[0]["params"]["mailto"] == "me@example.org"CODE
Verbosity Indicators3 hits · 5 pts
SeverityFileLineSnippetContext
LOWsrc/zotero_mcp/better_bibtex_client.py271 # Step 1: Get citation key from item key. BBT's JSON-RPC expectsCOMMENT
LOWsrc/zotero_mcp/better_bibtex_client.py289 # Step 2: Export BibTeX using the citation key.COMMENT
LOW⚡src/zotero_mcp/tools/annotations.py848 # Step 3: Map immediate parent keys to stable paper/attachment context.COMMENT
Docstring Block Structure1 hit · 5 pts
SeverityFileLineSnippetContext
HIGHsrc/zotero_mcp/better_bibtex_client.py253 Export BibTeX for a specific item using its item key. Args: item_key: Zotero item key to eSTRING