Skip to main content
Glama
syrian963

django-chainsaw-mcp

by syrian963

defeated_prefetches

Read-onlyIdempotent

Detect Django prefetch_related queries that re-query the database due to filters or other operations, exposing hidden N+1 costs.

Instructions

Relations that were prefetched and then re-queried anyway.

A prefetched related manager answers `.count()`, `.exists()`, `.all()` and
a slice from its cache. Anything else goes back to the database, once per
parent object, with the prefetch query already paid for on top:

    orders = Order.objects.prefetch_related("lines")
    for order in orders:
        for line in order.lines.filter(active=True):   # one query per order

That costs more than never prefetching at all, and it reads like an
optimisation, which is why it survives review.

Reported only where the prefetch and the accessor are provably the same
object - bound in the same scope, or the loop variable iterating it.
`nplusone` finds the neighbouring problem, an eager load nothing touches,
at runtime; `unused_eager_loading` answers that one statically for DRF.

Args:
    search_path: directory to scan. Defaults to the configured project.
    include_tests: also report inside test files.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
search_pathNo
include_testsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv0.1.4

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description does not contradict them. The description adds valuable context about the tool's behavior: it is static analysis, it only reports when the prefetch and accessor are provably the same object (conservative), and it does not execute code. It also mentions the tool is scoped to a directory search_path registry. However, it doesn't detail output schema or performance characteristics, but that is acceptable given the annotations and output schema presence.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is thorough but somewhat long; it includes a code example and a paragraph distinguishing from sibling tools. The purpose is front-loaded, and the parameters are summarized. It is appropriately structured but could be tightened; the code example, while helpful, adds length. A score of 4 reflects that every sentence earns its place, but it is longer than strictly necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool is a static analyzer with an output schema (not shown but present), the description sufficiently explains the purpose, usage, scope, and parameters. It covers behavior, limitations (provably same object), and distinguishes from neighboring tools. The output schema likely describes return structure, so the description doesn't need to detail that. It is complete for an agent to decide when to use and what parameters to pass.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema describes `search_path` as a string with default null and `include_tests` as a boolean. The description elaborates on what these parameters do: 'directory to scan' and 'also report inside test files', which goes beyond the schema's minimal titles. However, with 0% schema description coverage, the description carries the full burden for parameter meaning; it does a decent job but could be more explicit about how `search_path` is resolved when null (defaults to project). Overall, it adds value but not full depth.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies this as a static analysis tool that reports 'defeated prefetches' – specific inefficient query patterns in Django ORM code. It uses specific verb ('reports') and a precise resource ('relations that were prefetched and then re-queried' builds on the tool's name but adds concrete meaning). It distinguishes itself from sibling tools like `sqlalchemy_nplusone` and `unused_eager_loading`, explicitly noting differences.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description includes a code example that illustrates the exact scenario, making it clear when this tool is appropriate. It explicitly contrasts with `nplusone` (runtime) and `unused_eager_loading` (static, for DRF), providing clear alternatives and conditions. The description also lists parameters and their defaults, implying when to use them (e.g., `include_tests`).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.