{"name":"io.github.syrian963/django-chainsaw-mcp","slug":"syrian963-django-chainsaw-mcp","title":"Django Chainsaw","description":"Finds what will hurt in a Django project: cascades, N+1, unsafe migrations, tenant leaks.","url":"https://mcp.market/server/syrian963-django-chainsaw-mcp","rating":null,"grade":"A","score":92,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":28,"stars":0,"forks":0,"downloads_week":107,"last_push_at":"2026-09-14T02:13:15.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/syrian963/django-chainsaw-mcp","website":"https://github.com/syrian963/django-chainsaw-mcp","version":"0.1.5","remotes":[],"packages":[{"registryType":"pypi","registryBaseUrl":"https://pypi.org","identifier":"django-chainsaw-mcp","version":"0.1.5","transport":{"type":"stdio"},"environmentVariables":[{"description":"Absolute path to the Django project to analyse - the directory containing manage.py, or whichever directory the settings module is importable from. This server must run in an interpreter that can import that project, so install it into the project's own environment rather than an isolated one.","isRequired":true,"name":"DJANGO_CHAINSAW_PROJECT_PATH"},{"description":"Dotted path to the settings module, for example myproject.settings. Point it at the settings the site actually runs on: a base or partial module can import cleanly and load no models, and the server says so when that happens.","isRequired":true,"name":"DJANGO_CHAINSAW_SETTINGS_MODULE"}]}],"tools":[{"name":"amplification","description":"Endpoints anyone can call that cost a great deal to answer.","write_action":false,"price_micros":0,"input_schema":null},{"name":"api_contract","description":"The shape every serializer currently promises its clients.","write_action":false,"price_micros":0,"input_schema":null},{"name":"api_contract_check","description":"What this branch changes about the API, and who it breaks.","write_action":false,"price_micros":0,"input_schema":null},{"name":"blocking_in_async","description":"Synchronous calls that run on the event loop.","write_action":false,"price_micros":0,"input_schema":null},{"name":"bypassed_effects","description":"Bulk writes that skip everything the model's save() chain promised.","write_action":false,"price_micros":0,"input_schema":null},{"name":"celery_arguments","description":"Model instances handed to Celery tasks, and calls whose arity is wrong.","write_action":false,"price_micros":0,"input_schema":null},{"name":"check","description":"Run every analysis and return one severity-sorted list.","write_action":true,"price_micros":0,"input_schema":null},{"name":"choice_typos","description":"Literals compared against a field whose `choices` will never match them.","write_action":false,"price_micros":0,"input_schema":null},{"name":"dangling_references","description":"URL names and template names that nothing will resolve.","write_action":false,"price_micros":0,"input_schema":null},{"name":"datetime_audit","description":"Naive datetimes in code, and ambiguous defaults on model fields.","write_action":false,"price_micros":0,"input_schema":null},{"name":"defeated_prefetches","description":"Relations that were prefetched and then re-queried anyway.","write_action":false,"price_micros":0,"input_schema":null},{"name":"delete_impact","description":"Show what deleting one row of a model would take with it.","write_action":true,"price_micros":0,"input_schema":null},{"name":"deploy_safety","description":"Is a pending destructive migration safe to deploy yet?","write_action":true,"price_micros":0,"input_schema":null},{"name":"endpoint_cost","description":"How many queries one request to each endpoint will cost.","write_action":false,"price_micros":0,"input_schema":null},{"name":"escaping_side_effects","description":"Calls inside a transaction whose effect cannot be rolled back.","write_action":false,"price_micros":0,"input_schema":null},{"name":"explain_model","description":"Everything known about one model, and the risks only visible combined.","write_action":false,"price_micros":0,"input_schema":null},{"name":"fastapi_exposure","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"find_n_plus_one","description":"Find relation traversals in a template that each cost a query.","write_action":false,"price_micros":0,"input_schema":null},{"name":"find_unscoped_queries","description":"Find querysets that read tenant-scoped data without scoping the query.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_models","description":"List the project's models with their fields and relations.","write_action":false,"price_micros":0,"input_schema":null},{"name":"migration_risk","description":"Rate migrations by what they do to a live database.","write_action":false,"price_micros":0,"input_schema":null},{"name":"missing_indexes","description":"Fields the code filters or sorts on that carry no index.","write_action":false,"price_micros":0,"input_schema":null},{"name":"money_precision","description":"Places where a decimal amount stops being exact.","write_action":false,"price_micros":0,"input_schema":null},{"name":"multiplied_aggregates","description":"Aggregates whose numbers are wrong because a join multiplied the rows.","write_action":false,"price_micros":0,"input_schema":null},{"name":"open_endpoints","description":"Endpoints anyone can call, crossed with what their serializer exposes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"project_info","description":"Check that the target Django project loads, and report what it is.","write_action":false,"price_micros":0,"input_schema":null},{"name":"project_profile","description":"What this project is built on, without needing Django to boot.","write_action":false,"price_micros":0,"input_schema":null},{"name":"queries_in_loops","description":"Database work written inside a loop, split by what the fix is.","write_action":false,"price_micros":0,"input_schema":null},{"name":"race_conditions","description":"Read-modify-save races, and row locks taken outside any transaction.","write_action":false,"price_micros":0,"input_schema":null},{"name":"request_impact","description":"Every finding, grouped by the entry points that actually reach it.","write_action":false,"price_micros":0,"input_schema":null},{"name":"scan_templates","description":"Run the N+1 analysis over every template in a directory.","write_action":true,"price_micros":0,"input_schema":null},{"name":"serializer_exposure","description":"What each DRF ModelSerializer exposes, and what looks unintended.","write_action":false,"price_micros":0,"input_schema":null},{"name":"serializer_nplusone","description":"N+1 queries in DRF serializers, with the queryset fix for each.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sqlalchemy_nplusone","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"suggest_fixes","description":"Findings turned into code, grouped by how safe each one is to apply.","write_action":false,"price_micros":0,"input_schema":null},{"name":"unused_eager_loading","description":"select_related and prefetch_related the serializer never reads.","write_action":false,"price_micros":0,"input_schema":null},{"name":"what_happens_on","description":"Follow the signal chain a save or delete actually triggers.","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":92,"grade":"A","scanned_at":"2026-09-19T19:11:45.510Z","report":{"scannerVersion":"0.1.5","scannedAt":"2026-09-19T19:11:45.496Z","components":{"code":{"score":25,"max":25,"notes":["51 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 6 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"pypi","identifier":"django-chainsaw-mcp","version":"0.1.5","found":true,"weeklyDownloads":107,"license":"MIT","dependencyCount":1,"publishedAt":"2026-09-10T08:05:45.167785Z","repositoryUrl":"https://github.com/syrian963/django-chainsaw-mcp"}],"repo":{"found":true,"owner":"syrian963","repo":"django-chainsaw-mcp","archived":false,"pushedAt":"2026-09-14T02:13:15Z","stars":0,"forks":0,"openIssues":7,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/197386113?v=4","ownerCreatedAt":"2025-02-01T12:54:32Z","license":"MIT"},"icon":{"url":null,"source":"none"},"presence":{"stars":0,"forks":0,"downloadsWeek":107,"license":"MIT","lastPushAt":"2026-09-14T02:13:15.000Z","score":28}}}},"grade_history":[],"reviews":[]}