<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Will</title>
    <description>The latest articles on DEV Community by Will (@goodjobwilliam).</description>
    <link>https://dev.to/goodjobwilliam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4079261%2F36f8582c-1e8b-44b7-8a11-f0547fcae96c.png</url>
      <title>DEV Community: Will</title>
      <link>https://dev.to/goodjobwilliam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/goodjobwilliam"/>
    <language>en</language>
    <item>
      <title>I Built an MCP Server That Reviews Code Locally — No SaaS, No Uploads</title>
      <dc:creator>Will</dc:creator>
      <pubDate>Sat, 15 Aug 2026 16:51:10 +0000</pubDate>
      <link>https://dev.to/goodjobwilliam/i-built-an-mcp-server-that-reviews-code-locally-no-saas-no-uploads-568a</link>
      <guid>https://dev.to/goodjobwilliam/i-built-an-mcp-server-that-reviews-code-locally-no-saas-no-uploads-568a</guid>
      <description>&lt;p&gt;AI coding assistants ship code fast. But someone still has to review it. I wanted that "senior engineer second pair of eyes" to live inside my editor, run entirely on my machine, and work with whatever assistant I'm using today. So I built &lt;strong&gt;MCP Code Review Server&lt;/strong&gt; — a Model Context Protocol (MCP) server that connects to Claude Code, Cursor, Cline, or any MCP client.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;It exposes three tools to your AI assistant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;review_code&lt;/code&gt; — paste any snippet and get a structured review&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;review_diff&lt;/code&gt; — review a git diff before you merge&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;review_file&lt;/code&gt; — point it at a local file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each review returns findings with severity ratings (Critical / High / Medium / Low), file locations, and concrete fix suggestions.&lt;/p&gt;

&lt;p&gt;The checks are the ones I kept catching my own assistants missing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OWASP Top 10 security scanning&lt;/strong&gt; — injection, broken auth patterns, crypto misuse, unsafe deserialization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bug detection&lt;/strong&gt; — None handling, exception swallowing, mutable default arguments, race conditions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;N+1 query detection&lt;/strong&gt; — the classic ORM performance killer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance profiling&lt;/strong&gt; — repeated work in loops, blocking I/O, memory hotspots&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style and complexity&lt;/strong&gt; — long functions, deep nesting, configurable rule thresholds&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation is one command
&lt;/h2&gt;

&lt;p&gt;No signup, no API keys. It's on PyPI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Claude Code&lt;/span&gt;
claude mcp add code-review &lt;span class="nt"&gt;--&lt;/span&gt; uvx aicraft-code-review

&lt;span class="c"&gt;# Cursor / Claude Desktop — add to ~/.cursor/mcp.json&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"mcpServers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"code-review"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"command"&lt;/span&gt;: &lt;span class="s2"&gt;"uvx"&lt;/span&gt;,
      &lt;span class="s2"&gt;"args"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"aicraft-code-review"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Or pip&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;aicraft-code-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Your assistant now has a review tool it can call whenever you ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP instead of another SaaS tool
&lt;/h2&gt;

&lt;p&gt;I tried the hosted code-review tools first. They're good, but three things kept bothering me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; My review tool never needs to see the rest of my codebase. Uploading proprietary code to yet another vendor felt wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; Per-seat subscriptions for something that runs fine on the laptop in front of me.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lock-in.&lt;/strong&gt; I switch between Claude Code, Cursor, and Cline depending on the task. MCP is the common denominator — build once, run everywhere.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The server runs over stdio as a local process. Your code never leaves your machine. The only cost is the electricity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design decisions worth stealing
&lt;/h2&gt;

&lt;p&gt;A few things I'd do the same way again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python + stdio.&lt;/strong&gt; Simple, zero-dependency-at-runtime design, works on macOS/Linux/Windows. &lt;code&gt;uvx&lt;/code&gt; means users never even install it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured output.&lt;/strong&gt; Severity ratings + file/line references instead of prose. Agents consume structured data far more reliably than paragraphs, and humans can triage by severity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static-first, then heuristic.&lt;/strong&gt; It combines AST walking (Python) with regex/pattern rules for other languages, so it catches both structural issues (N+1 patterns) and localized smells (unsafe string formatting into SQL).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git-native.&lt;/strong&gt; &lt;code&gt;review_diff&lt;/code&gt; slots right into the "review before commit" habit that agents already have.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I learned about MCP distribution
&lt;/h2&gt;

&lt;p&gt;Getting a server &lt;em&gt;working&lt;/em&gt; is the easy part. Getting it &lt;em&gt;found&lt;/em&gt; is the real work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PyPI&lt;/strong&gt; is where the install commands live, but almost nobody discovers tools there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Directories&lt;/strong&gt; (Smithery, Glama, mcp.so, cursor.directory, awesome lists) are the actual discovery surface. Each has its own submission flow, quality bar, and wait time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI agents&lt;/strong&gt; now install MCP servers directly from directories — the distribution channel is increasingly &lt;em&gt;agents themselves&lt;/em&gt;, not just humans.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's why I've been submitting the server to every directory with a review process, and keeping the repo metadata (&lt;code&gt;glama.json&lt;/code&gt;, &lt;code&gt;.mcp.json&lt;/code&gt;, &lt;code&gt;smithery.yaml&lt;/code&gt;, a &lt;code&gt;Dockerfile&lt;/code&gt;) in shape for their automated checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/GoodJobwilliam/aicraft" rel="noopener noreferrer"&gt;GoodJobwilliam/aicraft&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyPI&lt;/strong&gt;: &lt;a href="https://pypi.org/project/aicraft-code-review/" rel="noopener noreferrer"&gt;aicraft-code-review&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Site&lt;/strong&gt;: &lt;a href="https://aicraft.vip" rel="noopener noreferrer"&gt;aicraft.vip&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it and hit a case it misses, open an issue — the rules are all configurable, and new checks are the fastest way this thing gets better.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What would you want an in-editor code reviewer to catch that yours currently misses?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
