<?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>63 Code Review Rules Your AI Assistant Should Enforce (Python, JS, Go, Java)</title>
      <dc:creator>Will</dc:creator>
      <pubDate>Sun, 16 Aug 2026 07:14:12 +0000</pubDate>
      <link>https://dev.to/goodjobwilliam/63-code-review-rules-your-ai-assistant-should-enforce-python-js-go-java-idf</link>
      <guid>https://dev.to/goodjobwilliam/63-code-review-rules-your-ai-assistant-should-enforce-python-js-go-java-idf</guid>
      <description>&lt;h2&gt;
  
  
  AI review is only as good as the rules you give it
&lt;/h2&gt;

&lt;p&gt;An AI assistant in Claude Code, Cursor or Windsurf will happily review every diff — but by default it reviews with its own taste. One teammate's model flags style, another's flags security, and your CI stays silent.&lt;/p&gt;

&lt;p&gt;The fix is the same one human teams converged on years ago: &lt;strong&gt;shared, versioned review rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We built &lt;code&gt;aicraft-code-review&lt;/code&gt; (free, MIT) to run those rules locally as an MCP server. I'm sharing the rule set we now ship as a paid pack — 63 rules across Python, JavaScript/TypeScript, Go and Java. You can adapt the examples below for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule format
&lt;/h2&gt;

&lt;p&gt;Every rule is plain YAML in &lt;code&gt;.mcp-code-review.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;custom_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no-pickle-loads&lt;/span&gt;
    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\bpickle\.loads?\s*\('&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;security&lt;/span&gt;
    &lt;span class="na"&gt;issue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pickle.load/loads&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;can&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;execute&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;arbitrary&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;during&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;unpickling"&lt;/span&gt;
    &lt;span class="na"&gt;fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;json,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pickle&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;only&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trusted&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;data"&lt;/span&gt;

&lt;span class="na"&gt;severity_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bare_except&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
  &lt;span class="na"&gt;hardcoded_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;critical&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Severities are &lt;code&gt;critical / high / medium / info&lt;/code&gt;. The server scans every changed line and emits a structured report — nothing leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 10 rules that catch the most real bugs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\beval\s*\(&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;critical&lt;/td&gt;
&lt;td&gt;arbitrary code execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\bpickle\.loads?\s*\(&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;RCE during unpickling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shell\s*=\s*True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;command injection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;def ... (x=[])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;mutable default shared across calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yaml\.load\(&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;unsafe YAML parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  JavaScript / TypeScript
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\bnew\s+Function\s*\(&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;critical&lt;/td&gt;
&lt;td&gt;compiles strings into code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;\bv-html\s*=&lt;/code&gt; / &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;XSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;localStorage.setItem("token"...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;tokens readable by any XSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setTimeout\("string"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;dynamic code execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;await fetch(...)&lt;/code&gt; without &lt;code&gt;res.ok&lt;/code&gt; check&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;td&gt;silent non-2xx handling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;http.Get(...)&lt;/code&gt; with no timeout&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;hangs forever&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;md5.Sum&lt;/code&gt; / &lt;code&gt;sha1.Sum&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;broken hashes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;math/rand&lt;/code&gt; for tokens&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;predictable randomness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;panic(...)&lt;/code&gt; in library code&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;td&gt;crashes the host process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;defer&lt;/code&gt; inside a loop&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;td&gt;deferred callbacks pile up&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Runtime.getRuntime().exec(...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;command injection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Statement.execute*&lt;/code&gt; with concatenated SQL&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;SQL injection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MessageDigest.getInstance("MD5")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;broken hash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;new Random()&lt;/code&gt; for security&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;predictable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;double/float&lt;/code&gt; for money&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;precision loss&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Make CI enforce them too
&lt;/h2&gt;

&lt;p&gt;The server has a CLI mode with CI-friendly exit codes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;aicraft-code-review
git diff origin/main...HEAD | mcp-code-review review-diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit codes: &lt;code&gt;0&lt;/code&gt; clean · &lt;code&gt;1&lt;/code&gt; high/medium findings · &lt;code&gt;2&lt;/code&gt; critical findings. Wire &lt;code&gt;2&lt;/code&gt; to fail the pipeline and your merge button becomes the reviewer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/review.yml — the core of it&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run review&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;git diff ${{ github.event.pull_request.base.sha }}...HEAD &amp;gt; /tmp/changes.diff&lt;/span&gt;
    &lt;span class="s"&gt;mcp-code-review review-diff --git-diff /tmp/changes.diff || [ $? -lt 2 ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get the full pack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free forever&lt;/strong&gt;: &lt;code&gt;pip install aicraft-code-review&lt;/code&gt; — the server + built-in checks (OWASP patterns, N+1, race analysis) stay MIT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team Rules Pack ($49, one-time)&lt;/strong&gt;: all 63 rules as drop-in profiles for the 4 languages, a GitHub Actions workflow that comments every PR and blocks merges on critical findings, a GitLab CI gate, and 20 LLM review prompts (security sweep, N+1 hunt, race-condition hunt, test-gap analysis...). Lifetime updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pack: &lt;a href="https://aicraft.vip" rel="noopener noreferrer"&gt;aicraft.vip&lt;/a&gt; · Source: &lt;a href="https://github.com/GoodJobwilliam/aicraft" rel="noopener noreferrer"&gt;github.com/GoodJobwilliam/aicraft&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;What rule has caught the most bugs for your team? I'll add the best community suggestions to the next pack update.&lt;/p&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>codequality</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Code Review From the Terminal and CI, No MCP Client Required</title>
      <dc:creator>Will</dc:creator>
      <pubDate>Sun, 16 Aug 2026 06:17:00 +0000</pubDate>
      <link>https://dev.to/goodjobwilliam/code-review-from-the-terminal-and-ci-no-mcp-client-required-33jf</link>
      <guid>https://dev.to/goodjobwilliam/code-review-from-the-terminal-and-ci-no-mcp-client-required-33jf</guid>
      <description>&lt;p&gt;A month ago I shipped &lt;a href="https://github.com/GoodJobwilliam/aicraft/tree/main/products/mcp-code-review" rel="noopener noreferrer"&gt;aicraft-code-review&lt;/a&gt;, an MCP server that reviews code locally. This week I added a CLI mode — because not everyone wants to wire up an MCP client just to check a diff.&lt;/p&gt;

&lt;p&gt;Now the same reviewer runs three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP tools&lt;/strong&gt; — &lt;code&gt;review_code&lt;/code&gt; / &lt;code&gt;review_diff&lt;/code&gt; / &lt;code&gt;review_file&lt;/code&gt; inside Claude Code, Cursor, Cline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt; — &lt;code&gt;mcp-code-review review-file path/to/file.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI&lt;/strong&gt; — pipe &lt;code&gt;git diff&lt;/code&gt; into it and branch on the exit code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The CLI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;aicraft-code-review

&lt;span class="c"&gt;# a single file (config auto-discovered from the file's directory upward)&lt;/span&gt;
mcp-code-review review-file src/api.py

&lt;span class="c"&gt;# the current diff&lt;/span&gt;
git diff | mcp-code-review review-diff

&lt;span class="c"&gt;# a snippet&lt;/span&gt;
mcp-code-review review-code &lt;span class="s2"&gt;"import os; os.system('ls')"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit codes are CI-friendly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;clean, or only info-level findings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;high / medium issues found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;critical issues found&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What it catches out of the box
&lt;/h2&gt;

&lt;p&gt;Security (OWASP patterns), performance (N+1, unbounded growth), quality (bare excepts, TODOs, missing type hints), style (naming, line length). Real output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;### 🟠 High (2)
| Line | Issue | Category | Fix |
| 4 | Command injection risk | security | subprocess.run with args list |
| 9 | N+1 query in loop | performance | batch query / eager loading |

### 🟢 Info (2) — missing return type annotations

Verdict: Conditional Pass — address high/medium issues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Making it match YOUR rules
&lt;/h2&gt;

&lt;p&gt;The config file is the part I'd actually show a teammate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;custom_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no-console-log&lt;/span&gt;
    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;console\.log\('&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;quality&lt;/span&gt;
    &lt;span class="na"&gt;issue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Console logging left in production code&lt;/span&gt;
    &lt;span class="na"&gt;fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use a structured logger instead&lt;/span&gt;

&lt;span class="na"&gt;disabled_checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;todo_comment&lt;/span&gt;

&lt;span class="na"&gt;severity_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hardcoded_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;critical&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.mcp-code-review.yaml&lt;/code&gt; is auto-discovered from the reviewed file's directory upward&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MCP_CODE_REVIEW_CONFIG&lt;/code&gt; points a whole team at one shared profile&lt;/li&gt;
&lt;li&gt;valid severities: &lt;code&gt;critical&lt;/code&gt; / &lt;code&gt;high&lt;/code&gt; / &lt;code&gt;medium&lt;/code&gt; / &lt;code&gt;info&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;regex patterns work best in single quotes (double quotes will error on escapes like &lt;code&gt;\.&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One caveat if you're also shipping Python MCP servers
&lt;/h2&gt;

&lt;p&gt;Pin your MCP dependency. &lt;code&gt;mcp 2.0.0&lt;/code&gt; shipped breaking changes and broke fresh installs of servers that had &lt;code&gt;mcp&amp;gt;=1.6&lt;/code&gt; unpinned. Use &lt;code&gt;mcp&amp;gt;=1.6,&amp;lt;2&lt;/code&gt; until you've migrated.&lt;/p&gt;




&lt;p&gt;The server is MIT-licensed: &lt;code&gt;pip install aicraft-code-review&lt;/code&gt;, or &lt;code&gt;claude mcp add code-review -- uvx aicraft-code-review&lt;/code&gt;. Issues and feedback welcome on &lt;a href="https://github.com/GoodJobwilliam/aicraft" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>mcp</category>
      <category>codequality</category>
      <category>cicd</category>
    </item>
    <item>
      <title>The $0 Distribution Playbook for MCP Servers: 12 Channels, 30 Days, Real Numbers</title>
      <dc:creator>Will</dc:creator>
      <pubDate>Sun, 16 Aug 2026 05:34:13 +0000</pubDate>
      <link>https://dev.to/goodjobwilliam/the-0-distribution-playbook-for-mcp-servers-12-channels-30-days-real-numbers-b4o</link>
      <guid>https://dev.to/goodjobwilliam/the-0-distribution-playbook-for-mcp-servers-12-channels-30-days-real-numbers-b4o</guid>
      <description>&lt;p&gt;A month ago I shipped &lt;a href="https://github.com/GoodJobwilliam/aicraft" rel="noopener noreferrer"&gt;aicraft-code-review&lt;/a&gt; — an open-source MCP server that reviews code locally (OWASP scanning, N+1 detection, style rules) for Claude Code, Cursor and Cline. I had &lt;strong&gt;$0 marketing budget&lt;/strong&gt; and no audience.&lt;/p&gt;

&lt;p&gt;One month later: &lt;strong&gt;650+ PyPI installs, 12 Product Hunt followers, and listings in 5 directories&lt;/strong&gt; — with more pending. Zero dollars spent. Here's the exact playbook, including what didn't work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The channels, ranked by effort-to-reach
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;What it took&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PyPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;✅ 650+ installs&lt;/td&gt;
&lt;td&gt;One afternoon: &lt;code&gt;pyproject.toml&lt;/code&gt;, wheel build, &lt;code&gt;twine upload&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Smithery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;✅ Live&lt;/td&gt;
&lt;td&gt;Deploy via their CLI, quality score 52/100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;mcpservers.org&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;✅ Approved in ~1 day&lt;/td&gt;
&lt;td&gt;Simple submit form&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;cursor.directory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;✅ Live&lt;/td&gt;
&lt;td&gt;Submit plugin + MCP server + rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Product Hunt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;✅ Launched&lt;/td&gt;
&lt;td&gt;Free launch, real user feedback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Glama&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;⏳ Reviewing&lt;/td&gt;
&lt;td&gt;Submit + &lt;code&gt;glama.json&lt;/code&gt; + Dockerfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;awesome-mcp-servers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;⏳ PR open&lt;/td&gt;
&lt;td&gt;Needs Glama listing + badge first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker MCP Registry&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;⏳ PR open&lt;/td&gt;
&lt;td&gt;Root &lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;LICENSE&lt;/code&gt;, &lt;code&gt;SECURITY.md&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Official MCP Registry&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;⏳ Next&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;mcp-publisher publish&lt;/code&gt; from the PyPI package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCPFind / Cline marketplace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;⏳ PRs open&lt;/td&gt;
&lt;td&gt;YAML metadata, waiting on maintainers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hacker News&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;✅ 1 point&lt;/td&gt;
&lt;td&gt;Honest "Show HN" style post&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reddit r/mcp&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;❌ Failed&lt;/td&gt;
&lt;td&gt;See below&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What actually moved the needle
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Directory listings compound.&lt;/strong&gt; Every listing adds an install path, a backlink, and social proof for the next directory. mcpservers.org approved me in a day; that listing made the cursor.directory submission stronger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Product Hunt gave us the roadmap.&lt;/strong&gt; We only got 3 upvotes — but two comments became our next release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"Team-shared rule profiles so my whole squad syncs rules"&lt;/em&gt; → shipped &lt;code&gt;MCP_CODE_REVIEW_CONFIG&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"Custom rule sets per repo"&lt;/em&gt; → shipped &lt;code&gt;.mcp-code-review.yaml&lt;/code&gt; auto-discovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real users telling you what to build beats any amount of guessing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The awesome-mcp-servers repo is the prize.&lt;/strong&gt; It has 92k stars and its README is how most people discover MCP servers. But the bar is real: your server must be listed on Glama with a quality score badge. Budget 2 weeks for review.&lt;/p&gt;

&lt;h2&gt;
  
  
  What didn't work (so you don't waste a week)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reddit with a new account = spam filter.&lt;/strong&gt; Both my r/mcp posts got silently removed. New accounts can't message mods either. Lesson: build karma in technical subreddits &lt;em&gt;before&lt;/em&gt; you have something to promote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HN is a lottery.&lt;/strong&gt; One point, zero comments. Fine — the post is still a permanent backlink.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paid directories come early.&lt;/strong&gt; mcp.so wants $39. OpenTools is paid-only. Skip them at the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that almost sank fresh installs
&lt;/h2&gt;

&lt;p&gt;Two weeks after 0.1.0 shipped, &lt;code&gt;mcp&lt;/code&gt; 2.0.0 dropped with a breaking API change — and fresh installs of my server crashed at import. I had pinned &lt;code&gt;mcp&amp;gt;=1.6&lt;/code&gt; &lt;strong&gt;without an upper bound&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you ship a Python MCP server today: &lt;strong&gt;pin &lt;code&gt;mcp&amp;gt;=1.6,&amp;lt;2&lt;/code&gt; in your dependencies right now.&lt;/strong&gt; The 0.1.1 release with the fix went out the same week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PyPI: 650+ installs, 150/month&lt;/li&gt;
&lt;li&gt;Product Hunt: 3 upvotes, 12 followers, 7 comments (all replied)&lt;/li&gt;
&lt;li&gt;GitHub: 2 stars (yes, two)&lt;/li&gt;
&lt;li&gt;Revenue: $0 so far — distribution first, monetization is the next chapter&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The playbook in 5 steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ship on PyPI/npm first.&lt;/strong&gt; Every other channel references your package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prepare the common requirements once&lt;/strong&gt;: &lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;LICENSE&lt;/code&gt;, &lt;code&gt;SECURITY.md&lt;/code&gt;, &lt;code&gt;glama.json&lt;/code&gt;, install docs. Every directory asks for a subset of these.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Submit to free directories in parallel.&lt;/strong&gt; Fast approvals build momentum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capture feedback&lt;/strong&gt; (PH comments, issues) and ship it — then tell people you shipped it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do the two big PRs last&lt;/strong&gt;: awesome-mcp-servers and the Docker MCP Registry, once your listing quality score is in shape.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next up: the official MCP Registry publish and the Glama badge. If you're building an MCP server, steal this list — and tell me which channel I'm missing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/GoodJobwilliam/aicraft" rel="noopener noreferrer"&gt;aicraft-code-review&lt;/a&gt; is MIT-licensed and installs with &lt;code&gt;pip install aicraft-code-review&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Team-Shared Code Review Rules for Your MCP AI Assistant</title>
      <dc:creator>Will</dc:creator>
      <pubDate>Sun, 16 Aug 2026 03:26:32 +0000</pubDate>
      <link>https://dev.to/goodjobwilliam/team-shared-code-review-rules-for-your-mcp-ai-assistant-542j</link>
      <guid>https://dev.to/goodjobwilliam/team-shared-code-review-rules-for-your-mcp-ai-assistant-542j</guid>
      <description>&lt;p&gt;Last month I &lt;a href="https://dev.to/goodjobwilliam/i-built-an-mcp-server-that-reviews-code-locally-no-saas-no-uploads-568a"&gt;shipped an MCP server&lt;/a&gt; that reviews code locally — no SaaS, no uploads. Two pieces of feedback kept coming up on Product Hunt:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Can my whole team sync the same review rules?"&lt;/li&gt;
&lt;li&gt;"Can each repo have its own rule set?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I built exactly that. &lt;code&gt;aicraft-code-review&lt;/code&gt; now reads a config file from your repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  One config file per repo
&lt;/h2&gt;

&lt;p&gt;Drop a &lt;code&gt;.mcp-code-review.yaml&lt;/code&gt; in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;disabled_checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;todo_comment&lt;/span&gt;

&lt;span class="na"&gt;severity_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hardcoded_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;critical&lt;/span&gt;

&lt;span class="na"&gt;min_severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;medium&lt;/span&gt;

&lt;span class="na"&gt;custom_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no-console-log&lt;/span&gt;
    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;console\.log\('&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
    &lt;span class="na"&gt;issue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Console logging left in production code&lt;/span&gt;
    &lt;span class="na"&gt;fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use a structured logger instead&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom regex rules&lt;/strong&gt; with their own severity, message, and suggested fix&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;disabled_checks&lt;/code&gt;&lt;/strong&gt; to silence noise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;severity_overrides&lt;/code&gt;&lt;/strong&gt; to make your team's blockers actually block&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;min_severity&lt;/code&gt;&lt;/strong&gt; to keep junior devs from drowning in info-level findings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Config is auto-discovered from the reviewed file's directory upward — one file per repo works automatically.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;YAML tip:&lt;/strong&gt; put regex patterns in single quotes. Double-quoted patterns like &lt;code&gt;"console\.log\("&lt;/code&gt; can trigger YAML escape errors — single quotes keep the backslashes literal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Team-wide profiles
&lt;/h2&gt;

&lt;p&gt;For a single shared profile, point every teammate at the same file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"code-review"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uvx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"aicraft-code-review"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"MCP_CODE_REVIEW_CONFIG"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/team-repo/.mcp-code-review.yaml"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit the YAML to your repo and every machine gives identical feedback.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvx aicraft-code-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSON configs work with zero extra dependencies; YAML needs &lt;code&gt;pip install "aicraft-code-review[yaml]"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The server is MIT-licensed and reviews code snippets, git diffs, and local files with OWASP security checks, N+1 detection, and style/quality passes.&lt;/p&gt;

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

&lt;p&gt;Happy reviewing!&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>python</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <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>
