<?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: Mohab Abdelkarim</title>
    <description>The latest articles on DEV Community by Mohab Abdelkarim (@mohab_karim).</description>
    <link>https://dev.to/mohab_karim</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%2F3978065%2F7fdea3fa-70f1-4ffc-8811-d1c85f85e795.jpg</url>
      <title>DEV Community: Mohab Abdelkarim</title>
      <link>https://dev.to/mohab_karim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohab_karim"/>
    <language>en</language>
    <item>
      <title>Best AI Detector APIs in 2026: A Developer's Comparison (With Working Code)</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Mon, 31 Aug 2026 23:56:18 +0000</pubDate>
      <link>https://dev.to/mohab_karim/best-ai-detector-apis-in-2026-a-developers-comparison-with-working-code-3dbo</link>
      <guid>https://dev.to/mohab_karim/best-ai-detector-apis-in-2026-a-developers-comparison-with-working-code-3dbo</guid>
      <description>&lt;p&gt;If you run a platform that accepts user-submitted text, an LMS, a publishing pipeline, a marketplace, a support system, you are already processing AI-generated content whether or not you built anything to handle it. The question stopped being whether to detect it and became which API to wire in and what to do with the response.&lt;/p&gt;

&lt;p&gt;This is a comparison of the AI detector APIs worth integrating in 2026, with real endpoints and runnable code for each. The evaluation criteria are the ones that actually matter in production: consistency across repeated scans, behavior on edited and paraphrased text, false-positive rate, and how much integration work the response format saves you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What an AI Detector API Actually Returns&lt;/li&gt;
&lt;li&gt;The Evaluation Criteria That Matter&lt;/li&gt;
&lt;li&gt;Proofademic API&lt;/li&gt;
&lt;li&gt;GPTZero API&lt;/li&gt;
&lt;li&gt;Copyleaks API&lt;/li&gt;
&lt;li&gt;Accuracy vs Consistency: The Metric Most Comparisons Get Wrong&lt;/li&gt;
&lt;li&gt;Integration Patterns That Work&lt;/li&gt;
&lt;li&gt;Handling False Positives Without Building a Support Nightmare&lt;/li&gt;
&lt;li&gt;Verdict&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What an AI Detector API Actually Returns
&lt;/h2&gt;

&lt;p&gt;An AI detector API takes text and returns a probability estimate, not a verdict. The distinction matters for how you design around it.&lt;/p&gt;

&lt;p&gt;A reasonable response looks something like this:&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;"document"&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;"ai_probability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.87&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"verdict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"likely_ai"&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;"sentences"&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="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Generative systems can produce fluent academic prose with highly predictable phrasing."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ai_probability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.94&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"signals"&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;"predictable_phrasing"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"generic_structure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sentence_variation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.22&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="nl"&gt;"words_processed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;412&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;Two things to note before you write any logic around this.&lt;/p&gt;

&lt;p&gt;The document-level float is what most people build on, and it is the least useful field in the payload. A 0.87 and a 0.99 both round to "flag it," but they are different signals, and collapsing them into a boolean on ingestion throws away information you will want later when someone disputes a flag.&lt;/p&gt;

&lt;p&gt;The sentence array is where the actual value is. A single document percentage forces an all-or-nothing decision. A sentence-level breakdown lets you build a review UI that shows a human exactly which passages triggered the score, which is the difference between a reviewer who can act on the result and one who has to take it on faith.&lt;/p&gt;

&lt;p&gt;What none of these APIs do, regardless of marketing copy: prove authorship, identify which model generated the text, see the user's prompt history, or determine intent. Every one of them estimates likelihood from statistical patterns. Build accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Evaluation Criteria That Matter
&lt;/h2&gt;

&lt;p&gt;Headline accuracy numbers are close to useless for comparing these APIs, for reasons covered in section 6. Here is what to actually check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Probability output, not binary labels.&lt;/strong&gt; An API returning a flat "AI" or "human" is manufacturing certainty it does not have and removing your ability to build tiered responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentence-level granularity.&lt;/strong&gt; Determines whether you can build a useful review interface or just a number nobody trusts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stability across edits.&lt;/strong&gt; Most real-world text is edited, paraphrased, or partially rewritten. An API whose score swings from 0.95 to 0.03 after a few sentence tweaks is not giving you a signal you can automate against. Good behavior is gradual degradation as text is modified.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;False-positive rate, with a stated methodology.&lt;/strong&gt; This is the number that will generate your support tickets. Any vendor citing a false-positive rate should tell you what set it was measured on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Response structure that saves integration work.&lt;/strong&gt; Whether you can drop the payload into a dashboard or have to build your own aggregation layer on top of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth and rate limits documented clearly.&lt;/strong&gt; Self-explanatory, and surprisingly often not the case.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Proofademic API
&lt;/h2&gt;

&lt;p&gt;Proofademic's detection suite went from early access to generally available over the course of 2026, and it is now a multi-endpoint platform rather than a single detector: AI text detection, AI image detection, plagiarism checking, and a grammar checker, with keys and usage managed at &lt;code&gt;platform.proofademic.ai&lt;/code&gt; and references at &lt;code&gt;docs.proofademic.ai&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Auth is a simple &lt;code&gt;X-API-Key&lt;/code&gt; header. Here is the image detector, which has the most publicly documented request shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  https://developer-portal.proofademic.ai/api/image-detector/predict/ &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"file=@campus.jpg"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;"prediction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"real"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9964&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"probabilities"&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;"real"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9964&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fake"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0013&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"inpainting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0022&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;The &lt;code&gt;inpainting&lt;/code&gt; class is worth calling out. Most image detectors give you a real-or-fake binary, which is not the distinction that matters most in practice. A photo that is genuine except for one edited region is a different moderation case from a fully generated image, and getting that as a separate probability rather than inferring it from a middling confidence score is a meaningful difference if you are building review workflows.&lt;/p&gt;

&lt;p&gt;For text detection, the API returns document-level confidence paired with sentence-level evidence, which is the structure section 1 argued for. Full request and response formats are in the API reference rather than reproduced on the marketing site, so check &lt;code&gt;docs.proofademic.ai/api-reference/detector&lt;/code&gt; before building against it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The false-positive number.&lt;/strong&gt; Proofademic publishes a 0.2 percent document-level false-positive rate from a March 2026 evaluation on a held-out set of 4,200 fully human-authored academic texts. That is a specific claim with a stated methodology and sample size, which puts it in a different category from an unqualified "99% accurate" banner. Worth noting the scope: it is measured on academic writing, which is what the model is calibrated for. Treat it as a strong signal for academic and editorial use rather than a universal figure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where it fits.&lt;/strong&gt; Academic calibration is the differentiator, tuned for citation-heavy essays, technical papers, and formal prose, which are exactly the writing styles that trip up general-purpose detectors. Coverage spans 23 languages and it includes Paraphrase Shield for rewritten AI text. Plans run from a free 1,000-word one-time scan up to Professional at $45/month for 600,000 words and 25,000 words per scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch out for.&lt;/strong&gt; The independent picture is more mixed than the vendor number. One third-party review found human samples scoring 13 and 19 percent AI rather than zero, and a mixed human-AI sample landing at 77 percent, which is arguably high for genuinely blended text. Neither result is disqualifying, but it is a reminder to set your own thresholds from your own data rather than inheriting the vendor's.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. GPTZero API
&lt;/h2&gt;

&lt;p&gt;GPTZero is the most widely deployed detector in education, which matters practically: if your users are already familiar with a score from somewhere, it is often this one. The API offers sentence-level highlighting, multi-language support, and mature documentation with a large installed base behind it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.gptzero.me/v2/predict/text &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "document": "Your text here",
    "multilingual": false
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Watch out for.&lt;/strong&gt; GPTZero publicly disputed a University of Chicago Booth benchmark in January 2026, arguing the researchers queried the wrong API field, and states a corrected re-run shows a 0.05 percent false-positive rate with 99.3 percent recall. Read closely, the rebuttal emphasizes recall rather than directly matching the lowest measured false-positive rates in that study, so the competing claims are not fully in conflict even though they are framed that way. Verify against your own data before treating either number as settled.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Copyleaks API
&lt;/h2&gt;

&lt;p&gt;Copyleaks is the enterprise pick, less a pure AI detector than a content authenticity platform: plagiarism and AI detection from both text and file uploads, broad language coverage, and native LMS integrations already built for Canvas, Moodle, Blackboard, Brightspace, Schoology, Sakai, and Edsby.&lt;/p&gt;

&lt;p&gt;Auth is OAuth-style rather than a static key, which is more setup but better for multi-tenant deployments:&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;# 1. Get a token&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://id.copyleaks.com/v3/account/login/api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email": "YOUR_EMAIL", "key": "YOUR_API_KEY"}'&lt;/span&gt;

&lt;span class="c"&gt;# 2. Submit a scan with the returned token&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; PUT https://api.copyleaks.com/v3/scans/submit/file/SCAN_ID &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "base64": "BASE64_ENCODED_CONTENT",
    "filename": "submission.txt",
    "properties": {
      "webhooks": { "status": "https://your-app.com/webhook/{STATUS}" }
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the webhook-first design. Copyleaks is built around async submission with callback delivery rather than synchronous responses, which is the right architecture at institutional volume but more infrastructure to stand up if you just need to score a paragraph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where it fits.&lt;/strong&gt; Universities and large publishers that need plagiarism and AI detection running through one system rather than stitching two vendors together. Overkill for most standalone products.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Accuracy vs Consistency: The Metric Most Comparisons Get Wrong
&lt;/h2&gt;

&lt;p&gt;The first question everyone asks is which API is most accurate. It is the wrong question, and understanding why will save you from picking based on a meaningless number.&lt;/p&gt;

&lt;p&gt;Accuracy assumes a clean ground truth: this text is AI, this text is human. Most real content does not sort that way. It is AI-drafted and human-edited, or human-written and AI-polished, or rewritten three times by both. There is no universal label two detectors are obligated to agree on for that text. Two APIs can return different scores on the same input and both be defensible.&lt;/p&gt;

&lt;p&gt;Consistency is the measurable property that actually predicts whether you can build on an API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same text, multiple scans, similar results&lt;/li&gt;
&lt;li&gt;Small edits produce small score changes&lt;/li&gt;
&lt;li&gt;Rewriting degrades the score gradually rather than cliff-edging&lt;/li&gt;
&lt;li&gt;No 0.95 to 0.03 swings from a two-sentence change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can test this yourself in about twenty minutes, and you should, because no vendor publishes it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.example-detector.com/v1/detect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-API-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DETECTOR_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;document&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai_probability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;consistency_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Score progressively edited versions to see how the API degrades.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;baseline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;baseline: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;baseline&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edited&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edited&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &amp;lt;-- unstable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;edit &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (delta &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Run the same text 5x to check scan-to-scan variance too
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that against a trial key for each candidate API with your own representative content. The results will tell you more than every accuracy claim on every vendor's homepage combined.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Integration Patterns That Work
&lt;/h2&gt;

&lt;p&gt;Wrap the call with a timeout and treat non-200s as first-class. If detection sits in a submission flow, a hung request must never block the user from submitting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;detectAiContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DETECTOR_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-API-Key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DETECTOR_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Detector returned &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;probability&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ai_probability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;wordsProcessed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;words_processed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fail open: log it, let the submission through, flag for later review&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Detection failed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;probability&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Failing open is deliberate. A detection outage should degrade to "unscored, review later," never to "submission rejected."&lt;/p&gt;

&lt;p&gt;Then bucket rather than threshold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unscored&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;probability&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clear&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;probability&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;needs_review&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;high_confidence_flag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three buckets give reviewers somewhere to apply judgment on the middle tier. A single cutoff produces a system that either does nothing or overreacts, and reviewers stop trusting it within a month.&lt;/p&gt;

&lt;p&gt;Store the full sentence array, not just the final percentage. When someone disputes a flag six weeks later, the document score tells you nothing and the sentence breakdown tells you everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Handling False Positives Without Building a Support Nightmare
&lt;/h2&gt;

&lt;p&gt;False positives are not evenly distributed, and knowing where they cluster lets you handle them before they become tickets.&lt;/p&gt;

&lt;p&gt;They concentrate on non-native English writing, formal and technical prose, and short submissions. The research here is consistent: a 2023 study in the journal &lt;em&gt;Patterns&lt;/em&gt; found major detectors misclassified the majority of non-native English speakers' essays as AI-generated, and follow-up work using TOEFL essays found a false-positive rate above 60 percent for Chinese students against roughly 5 percent for US students under identical conditions. Short text is also structurally unreliable, since there is less signal to work from.&lt;/p&gt;

&lt;p&gt;Practical mitigations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set a minimum word count before you score anything at all. Below roughly 300 words, the result is closer to noise than signal.&lt;/li&gt;
&lt;li&gt;Log the language and, where you have it, the writing context alongside every score, so you can audit whether your flags skew toward a particular user group.&lt;/li&gt;
&lt;li&gt;Never trigger an automatic consequence off a raw score. Route to human review.&lt;/li&gt;
&lt;li&gt;Build an appeal path before you launch, not after the first complaint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Section 6's consistency script is also your false-positive test rig: feed it known-human text from your actual user base and see what comes back.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Verdict
&lt;/h2&gt;

&lt;p&gt;There is no perfect AI detector API, and any vendor implying otherwise is selling certainty a probabilistic system cannot deliver.&lt;/p&gt;

&lt;p&gt;For academic, editorial, and institutional workloads, Proofademic is the strongest pick right now: sentence-level evidence by default, a published false-positive figure with a stated methodology, academic calibration that addresses the exact writing styles general detectors get wrong, and a straightforward API-key auth model. GPTZero is the safer choice if your users already recognize its scores and you want the largest installed base. Copyleaks is right for institutional deployments that need plagiarism and AI detection through one system with LMS integrations already built.&lt;/p&gt;

&lt;p&gt;Whichever you pick, the architecture matters more than the vendor. Probability in, buckets out, human in the loop, full sentence data stored, fail open on errors. Get that right and swapping detectors later is a config change rather than a rewrite.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can an AI detector API prove someone used ChatGPT?&lt;/strong&gt;&lt;br&gt;
No. These APIs estimate statistical likelihood. They cannot determine authorship or intent, and they have no visibility into prompt history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do two APIs return different scores on the same text?&lt;/strong&gt;&lt;br&gt;
Different models, training data, thresholds, and signal weighting. On genuinely mixed human-AI text there is often no single correct label for them to converge on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a 0% score trustworthy?&lt;/strong&gt;&lt;br&gt;
It reflects one model's interpretation of one input. Another API may score the same text meaningfully higher. Treat it as one signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do detector APIs work on humanized or paraphrased text?&lt;/strong&gt;&lt;br&gt;
Reliability drops for every detector as text is rewritten. The better ones degrade gradually rather than failing outright, which is exactly what the consistency test in section 6 measures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I auto-reject content based on an API response?&lt;/strong&gt;&lt;br&gt;
No. The defensible pattern is detection producing a risk signal, that signal routing to human review, and a contextual decision getting made from there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the minimum text length worth scoring?&lt;/strong&gt;&lt;br&gt;
Roughly 300 words as a working floor. Shorter submissions carry meaningfully higher false-positive risk across every detector.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Setting Up Walter MCP in Cursor and Windsurf: The Complete Guide</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Thu, 27 Aug 2026 23:27:58 +0000</pubDate>
      <link>https://dev.to/mohab_karim/setting-up-walter-mcp-in-cursor-and-windsurf-the-complete-guide-21lf</link>
      <guid>https://dev.to/mohab_karim/setting-up-walter-mcp-in-cursor-and-windsurf-the-complete-guide-21lf</guid>
      <description>&lt;p&gt;If you're running content operations through Cursor or Windsurf instead of a browser tab, you've probably already found yourself wanting Walter's humanizer and detector available as tools the agent can actually call, not something you paste text into separately. This guide covers both pieces of that setup: the Skills that tell the agent what to do, and the MCP connector that gives it the tools to actually do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Two Pieces, Not One&lt;/li&gt;
&lt;li&gt;Installing Walter Skills in Cursor and Windsurf&lt;/li&gt;
&lt;li&gt;Connecting the Walter MCP Server&lt;/li&gt;
&lt;li&gt;Verifying the Connection&lt;/li&gt;
&lt;li&gt;Installing a Single Skill Instead of All 12&lt;/li&gt;
&lt;li&gt;A Note on waltermcp.com&lt;/li&gt;
&lt;li&gt;Troubleshooting&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Two Pieces, Not One
&lt;/h2&gt;

&lt;p&gt;This is the single most common point of confusion, and it's worth getting straight before touching a config file.&lt;/p&gt;

&lt;p&gt;Walter Skills are markdown instruction files. Once loaded into a project, they tell your agent how to approach a task, when to humanize, when to lock keywords, what format to return. They don't do anything on their own.&lt;/p&gt;

&lt;p&gt;Walter MCP is the actual tool connector. It's what lets your agent call Walter's humanizer, detector, and keyword-preservation functions for real, rather than just knowing it's supposed to.&lt;/p&gt;

&lt;p&gt;Straight from the walter-skills repo itself: the skills give the agent instructions, but without the MCP connector, it can follow the prompts and still not be able to perform the humanization or detection steps. You need both pieces for this to actually work end to end, not just one.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Installing Walter Skills in Cursor and Windsurf
&lt;/h2&gt;

&lt;p&gt;This part is a single command, and it's the same command regardless of which editor you're using, since both are supported through the same registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add walterwritesai/walter-skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that from your project root, in either Cursor's or Windsurf's integrated terminal. It pulls all 12 Walter Skills from &lt;a href="https://skills.sh/walterwritesai/walter-skills" rel="noopener noreferrer"&gt;Skills.sh&lt;/a&gt;, Vercel's open Skills registry, and installs them for the agent to pick up automatically. This is the same install path listed directly in the &lt;a href="https://github.com/walterwritesai/walter-skills" rel="noopener noreferrer"&gt;walter-skills GitHub repo&lt;/a&gt;, which confirms Claude Code, Cursor, Windsurf, and more than 60 other agents as supported through this route.&lt;/p&gt;

&lt;p&gt;Here's what you get with that one command:&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;Skill&lt;/th&gt;
&lt;th&gt;For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SK-01&lt;/td&gt;
&lt;td&gt;SEO Content Writer&lt;/td&gt;
&lt;td&gt;General SEO content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-02&lt;/td&gt;
&lt;td&gt;Agency QC Pipeline&lt;/td&gt;
&lt;td&gt;Teams running drafts through multiple writers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-03&lt;/td&gt;
&lt;td&gt;Local SEO Machine&lt;/td&gt;
&lt;td&gt;City and service-page templates at scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-04&lt;/td&gt;
&lt;td&gt;Content Repurposer&lt;/td&gt;
&lt;td&gt;Turning one piece into threads, posts, newsletters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-05&lt;/td&gt;
&lt;td&gt;E-commerce Engine&lt;/td&gt;
&lt;td&gt;Batch product descriptions and listings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-06&lt;/td&gt;
&lt;td&gt;Newsletter Writer&lt;/td&gt;
&lt;td&gt;Weekly newsletter authoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-07&lt;/td&gt;
&lt;td&gt;Programmatic SEO&lt;/td&gt;
&lt;td&gt;Hundreds of templated pages from a CSV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-08&lt;/td&gt;
&lt;td&gt;Brand Voice Adapter&lt;/td&gt;
&lt;td&gt;Keeping tone consistent across writers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-09&lt;/td&gt;
&lt;td&gt;Content Refresh&lt;/td&gt;
&lt;td&gt;Updating old posts without losing rankings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-10&lt;/td&gt;
&lt;td&gt;Lead Magnet Writer&lt;/td&gt;
&lt;td&gt;Multi-page guides and whitepapers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-11&lt;/td&gt;
&lt;td&gt;Social Media Manager&lt;/td&gt;
&lt;td&gt;Platform-native posts from one source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SK-12&lt;/td&gt;
&lt;td&gt;Documentation Writer&lt;/td&gt;
&lt;td&gt;Technical docs, code blocks preserved exactly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If this is your first time using the Skills.sh registry in either editor, restart the editor after the install finishes. Both Cursor and Windsurf read their skill and MCP configuration at launch, so a running session won't always pick up a fresh install automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Connecting the Walter MCP Server
&lt;/h2&gt;

&lt;p&gt;This is the piece that actually gives the agent working tools, and it's a standard remote MCP server connection, which both editors support the same general way, just with slightly different config file locations and field names.&lt;/p&gt;

&lt;p&gt;Walter's MCP server address is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp-server.walterwrites.ai/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In Cursor&lt;/strong&gt;, add it to &lt;code&gt;.cursor/mcp.json&lt;/code&gt; in your project root, or your global Cursor MCP settings if you want it available across every project:&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;"walter"&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;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp-server.walterwrites.ai/mcp"&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;You can also add it through the UI directly: open Cursor Settings, go to the MCP section, and add a new server using that same URL. Cursor handles the OAuth handshake automatically if the server requires it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Windsurf&lt;/strong&gt;, the config file lives at &lt;code&gt;~/.codeium/windsurf/mcp_config.json&lt;/code&gt;, and the field name is different, which is the single most common mistake when copying a config between the two editors:&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;"walter"&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;"serverUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp-server.walterwrites.ai/mcp"&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;Windsurf uses &lt;code&gt;serverUrl&lt;/code&gt;, not &lt;code&gt;url&lt;/code&gt;. If you copy a working Cursor config straight into Windsurf without changing that field name, the server won't connect, and there's usually no obvious error message pointing you at why.&lt;/p&gt;

&lt;p&gt;A quick honest note here: this MCP server address and the Claude-specific setup instructions (Claude → Settings → Connectors) are confirmed directly from Walter's own ecosystem. The Cursor and Windsurf config shown above follows the standard, documented way both editors connect to any remote MCP server, applied to Walter's address specifically. If it doesn't connect on the first try, check &lt;a href="https://docs.walterwrites.ai/" rel="noopener noreferrer"&gt;docs.walterwrites.ai&lt;/a&gt; for the most current setup steps before assuming your config is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Verifying the Connection
&lt;/h2&gt;

&lt;p&gt;Once both pieces are in place, restart your editor and try a simple test prompt in a project where the skills are installed:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Humanize this sentence and show me the detection score before and after: "In today's rapidly evolving digital landscape, organizations must strategically leverage innovative technologies to optimize operational efficiency."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the connection is working, the agent should actually call Walter's tools and come back with a rewritten sentence plus real before-and-after scores, not just a rewritten sentence with no scoring attached. If it only rewrites without scoring anything, the Skills are loaded but the MCP connector isn't, which is exactly the two-pieces problem from the first section.&lt;/p&gt;

&lt;p&gt;In Cursor, you can also check connection status directly under Settings &amp;gt; Tools &amp;amp; MCP. In Windsurf, the MCP panel in Cascade shows connection status for each configured server.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Installing a Single Skill Instead of All 12
&lt;/h2&gt;

&lt;p&gt;If you only need one workflow, the local SEO machine for a multi-location client, say, you don't need to install all 12 at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add walterwritesai/walter-skills &lt;span class="nt"&gt;--skill&lt;/span&gt; walter-local-seo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap in any of the skill slugs from the table above (&lt;code&gt;walter-seo-writer&lt;/code&gt;, &lt;code&gt;walter-agency-qc&lt;/code&gt;, &lt;code&gt;walter-repurposer&lt;/code&gt;, and so on) to install just that one.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. A Note on waltermcp.com
&lt;/h2&gt;

&lt;p&gt;If you go looking for more Walter MCP setup material, you'll likely land on &lt;a href="https://waltermcp.com/" rel="noopener noreferrer"&gt;waltermcp.com&lt;/a&gt;, a community-run guide, not an official Walter Writes AI site. It's a genuinely useful resource, with a library of copy-paste prompts and walkthroughs for the same Skills covered here, but it's worth treating as a secondary reference rather than the source of truth.&lt;/p&gt;

&lt;p&gt;As one concrete example of why that distinction matters: at the time of writing, waltermcp.com's own FAQ states Walter currently only supports English, with other languages on the roadmap, while Walter's official product pages describe support for dozens of languages across its humanizer and detector. That's exactly the kind of gap that can happen when a community resource doesn't get updated at the same pace as the product itself. Use waltermcp.com for the prompt ideas and workflow inspiration, but check Walter's own docs for anything you're relying on to be current.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Server shows as connected but nothing happens when you ask the agent to humanize something.&lt;/strong&gt; This is almost always the two-pieces issue from section one. Confirm the Skills actually installed with &lt;code&gt;npx skills add walterwritesai/walter-skills&lt;/code&gt; and that the MCP server shows as connected in your editor's settings, not just one or the other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windsurf won't connect even though the same config works in Cursor.&lt;/strong&gt; Check the field name first. &lt;code&gt;url&lt;/code&gt; works in Cursor, Windsurf needs &lt;code&gt;serverUrl&lt;/code&gt;. This single difference causes most cross-editor config failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills don't show up after installing.&lt;/strong&gt; Restart the editor. Both Cursor and Windsurf load skill and MCP configuration at launch, not while a session is already running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON config won't save or throws an error.&lt;/strong&gt; A trailing comma after the last entry in &lt;code&gt;mcpServers&lt;/code&gt; is the most common culprit. Validate the file with a JSON linter before saving if you're editing it by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Conclusion
&lt;/h2&gt;

&lt;p&gt;The actual setup here is short: one terminal command for the Skills, one config entry for the MCP connector, and a restart in between. The part that actually trips people up isn't the technical steps, it's not realizing these are two separate systems that both need to be in place before anything works end to end. Get the connector and the Skills running together, and Cursor or Windsurf starts drafting, humanizing, and scoring content in the same agent loop you're already using for code.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need both Walter Skills and Walter MCP, or just one?&lt;/strong&gt;&lt;br&gt;
Both. Skills give the agent instructions for how to approach a task. The MCP connector gives it the actual tools to humanize and detect. Without the connector, the agent can follow the instructions but can't perform the humanization or detection steps themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the same install command work in both Cursor and Windsurf?&lt;/strong&gt;&lt;br&gt;
Yes. &lt;code&gt;npx skills add walterwritesai/walter-skills&lt;/code&gt; installs the same 12 skills through the Skills.sh registry regardless of which editor you run it in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why didn't my Windsurf config work when I copied it from Cursor?&lt;/strong&gt;&lt;br&gt;
Check the field name. Cursor uses &lt;code&gt;url&lt;/code&gt; for a remote MCP server, Windsurf uses &lt;code&gt;serverUrl&lt;/code&gt;. Copying a Cursor config into Windsurf without updating that field is the most common reason a connection silently fails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is waltermcp.com the official place to set up Walter's MCP connector?&lt;/strong&gt;&lt;br&gt;
No, it's a community-run guide, not run by Walter Writes AI. It's a useful secondary resource for prompts and workflow ideas, but check Walter's own documentation for anything setup-related that needs to be current.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I install just one Skill instead of all 12?&lt;/strong&gt;&lt;br&gt;
Yes, with the &lt;code&gt;--skill&lt;/code&gt; flag: &lt;code&gt;npx skills add walterwritesai/walter-skills --skill &amp;lt;skill-slug&amp;gt;&lt;/code&gt;, using the slug for whichever skill you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What should I test first after setting this up?&lt;/strong&gt;&lt;br&gt;
A simple before-and-after prompt, asking the agent to humanize a sentence and show the detection score on both versions. If it rewrites the text but never shows a score, the MCP connector isn't actually connected yet, even if the Skills are installed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Add AI Content Detection to Your App With an API (Developer Guide)</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Wed, 26 Aug 2026 22:57:54 +0000</pubDate>
      <link>https://dev.to/mohab_karim/how-to-add-ai-content-detection-to-your-app-with-an-api-developer-guide-32m7</link>
      <guid>https://dev.to/mohab_karim/how-to-add-ai-content-detection-to-your-app-with-an-api-developer-guide-32m7</guid>
      <description>&lt;p&gt;If your product accepts user-submitted text, an essay, a cover letter, a marketplace listing, a forum post, you're already dealing with AI-generated content whether you've built anything to handle it or not. The question isn't really whether to add detection anymore. It's how to wire it in without turning it into a multi-week project.&lt;/p&gt;

&lt;p&gt;This guide walks through adding AI content detection to a real app using Walter's AI Detector API: getting a key, making your first request, parsing the response correctly, and handling the part everyone skips, what to actually do when the score is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What You're Building&lt;/li&gt;
&lt;li&gt;Getting an API Key&lt;/li&gt;
&lt;li&gt;Making Your First Request&lt;/li&gt;
&lt;li&gt;Understanding the Response&lt;/li&gt;
&lt;li&gt;Wiring It Into Your App&lt;/li&gt;
&lt;li&gt;Handling False Positives Properly&lt;/li&gt;
&lt;li&gt;Common Integration Patterns&lt;/li&gt;
&lt;li&gt;Pricing and Scaling&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What You're Building
&lt;/h2&gt;

&lt;p&gt;By the end of this, you'll have a working function that takes a string of text, sends it to Walter's detector, and gets back a calibrated probability score you can act on, flag for review, log, or display, depending on what your app actually needs to do with it.&lt;/p&gt;

&lt;p&gt;The API scores text generated by any major model, GPT-4, Claude, Gemini, Llama, and others, and returns a probability rather than a flat yes-or-no verdict, which matters more than it sounds like once you get to the section on false positives.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Getting an API Key
&lt;/h2&gt;

&lt;p&gt;Sign up at &lt;a href="https://platform.walterwrites.ai/" rel="noopener noreferrer"&gt;platform.walterwrites.ai&lt;/a&gt; to get a key. Walter's infrastructure is SOC 2 Type I compliant, worth knowing if you're integrating this into anything that touches user data under a compliance requirement of your own, like an education product handling FERPA-covered records.&lt;/p&gt;

&lt;p&gt;Keep the key server-side. This is a backend integration, not something you call directly from client-side JavaScript, for the same reason you wouldn't expose any other secret API key in a browser bundle.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Making Your First Request
&lt;/h2&gt;

&lt;p&gt;The core endpoint is a single POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.walterwrites.ai/v1/detect &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "text": "In todays rapidly evolving digital landscape, organizations must strategically leverage innovative technologies to optimize operational efficiency.",
    "language": "en"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole request. Text in, a &lt;code&gt;language&lt;/code&gt; hint if you have one, standard bearer token auth. No batching setup, no async job queue required for a single check like this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Understanding the Response
&lt;/h2&gt;

&lt;p&gt;A successful call returns something like this:&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"det_4k2p9x1m3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"detector-v3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-12T13:45:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"output"&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;"ai_probability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.87&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"words_processed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&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;"usage"&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;"credits_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&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;&lt;code&gt;ai_probability&lt;/code&gt; is the field you'll build most of your logic around. It's a float between 0 and 1, not a binary flag, which is a deliberate design choice worth keeping intact in your own app rather than collapsing it into a boolean the first chance you get. A 0.87 and a 0.99 both round up to "flag this," but they're not the same signal, and you'll want that distinction later if you ever need to explain a decision to a user.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;credits_used&lt;/code&gt; scales with word count, so logging it per request from day one saves you from guessing where your monthly quota went once volume picks up.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Wiring It Into Your App
&lt;/h2&gt;

&lt;p&gt;Here's a minimal Node.js wrapper that handles the request, a timeout, and a couple of the error cases you'll actually hit in production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;detectAiContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.walterwrites.ai/v1/detect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WALTER_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Detector API returned &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;probability&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ai_probability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;wordsProcessed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;words_processed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;creditsUsed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credits_used&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AbortError&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Detector API request timed out&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the Python equivalent, for anyone wiring this into a Django or FastAPI backend instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;detect_ai_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.walterwrites.ai/v1/detect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;WALTER_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;language&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;probability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai_probability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;words_processed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;words_processed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;credits_used&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;usage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;credits_used&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both versions treat a timeout and a non-200 response as first-class cases, not afterthoughts. If this call sits in the middle of a submission flow, a hung request shouldn't be able to block your user from submitting anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Handling False Positives Properly
&lt;/h2&gt;

&lt;p&gt;This is the part most detection integrations get wrong, and it's the difference between a useful feature and a support ticket generator.&lt;/p&gt;

&lt;p&gt;Walter's own published data on this is worth internalizing before you write any flagging logic: false positive rates typically run 4 to 12 percent at a 50 percent confidence threshold, meaning legitimate human writing gets incorrectly flagged roughly once every 10 to 25 samples. That's not a bug to route around, it's the actual behavior of probabilistic detection, and it shows up more on non-native English writing, highly formal or technical text, anything under 100 words, and heavily edited human content, since all of those reduce the natural variation detectors use as a human signal.&lt;/p&gt;

&lt;p&gt;The practical response is a two-pass workflow, not a single hard cutoff. Flag anything above a threshold you choose based on your own risk tolerance, then have a human reviewer look specifically at the flagged cases rather than trusting the score as a final verdict. If you're building for a high-stakes context like academic integrity or hiring decisions, build in a way for the person on the other end to respond or appeal before any consequence lands, not after.&lt;/p&gt;

&lt;p&gt;Here's what that looks like as a simple threshold wrapper around the function above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reviewSubmission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;detectAiContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;probability&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clear&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;probability&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;needs_review&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;high_confidence_flag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three buckets instead of one binary cutoff gives your reviewers somewhere to actually apply judgment on the middle tier, instead of a system that either does nothing or overreacts every time.&lt;/p&gt;

&lt;p&gt;It's also worth knowing this isn't a solved problem in any permanent sense. A widely cited 2023 paper by Sadasivan et al., "Can AI-Generated Text Be Reliably Detected?", makes the case that detection evasion is theoretically unbounded as models keep improving, which is part of why Walter retrains its detection models on a regular cycle against newer model outputs rather than shipping a static classifier once and leaving it alone. Build your integration assuming accuracy today isn't a permanent guarantee, and you'll avoid having to rearchitect anything when the numbers shift.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Common Integration Patterns
&lt;/h2&gt;

&lt;p&gt;A few patterns show up repeatedly depending on what you're building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LMS and edtech platforms&lt;/strong&gt; typically score every submission automatically at upload time, surface a per-student dashboard for instructors, and route anything flagged into a review queue rather than an automatic penalty. If you're in this space, ask about Walter's education tier specifically, since it includes FERPA-aligned data handling and discounted volume pricing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content marketplaces and publishers&lt;/strong&gt; generally flag at ingestion, before content goes live, which keeps obviously low-effort AI submissions from ever reaching an editor's queue in the first place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HR and recruiting platforms&lt;/strong&gt; apply this to cover letters, take-home assignments, and written interview responses. This is the context where the two-pass review workflow matters most, since a wrongly flagged candidate is a real cost to get wrong, not just a UX annoyance.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Pricing and Scaling
&lt;/h2&gt;

&lt;p&gt;Pricing runs on monthly word quotas, which makes it straightforward to forecast against your own expected volume rather than guessing at enterprise-only pricing upfront.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Included Volume&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;300K&lt;/td&gt;
&lt;td&gt;$49/mo&lt;/td&gt;
&lt;td&gt;300,000 words&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1M&lt;/td&gt;
&lt;td&gt;$129/mo&lt;/td&gt;
&lt;td&gt;1,000,000 words&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2M&lt;/td&gt;
&lt;td&gt;$229/mo&lt;/td&gt;
&lt;td&gt;2,000,000 words&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5M&lt;/td&gt;
&lt;td&gt;$479/mo&lt;/td&gt;
&lt;td&gt;5,000,000 words&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12M&lt;/td&gt;
&lt;td&gt;$899/mo&lt;/td&gt;
&lt;td&gt;12,000,000 words&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25M&lt;/td&gt;
&lt;td&gt;$1,699/mo&lt;/td&gt;
&lt;td&gt;25,000,000 words&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Higher-volume workloads and enterprise deployment needs go through a direct sales conversation rather than a fixed public tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Conclusion
&lt;/h2&gt;

&lt;p&gt;Adding AI detection to a product is a smaller lift than it sounds like on paper, a single POST request gets you a working score. The part that actually takes engineering judgment is what happens after that response comes back: treating the probability as a probability, building a review path instead of a hard cutoff, and accounting for the specific conditions, short text, technical writing, non-native English, where false positives cluster. Get that part right and the integration itself is genuinely just a few hours of work.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need to handle async processing for single text checks?&lt;/strong&gt;&lt;br&gt;
No. A single detection request completes synchronously and returns a result directly, no polling or webhook setup required unless you're doing high-volume batch processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's a reasonable false positive rate to expect?&lt;/strong&gt;&lt;br&gt;
Walter's own published data puts it at 4 to 12 percent at a 50 percent confidence threshold. Build your review workflow around that expectation rather than assuming a flag is automatically correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I ever use the AI probability score as the sole basis for an automated decision?&lt;/strong&gt;&lt;br&gt;
Not for anything with real consequences attached. The recommended pattern is a calibrated threshold that routes borderline and high-confidence flags to a human reviewer rather than triggering an automatic penalty or rejection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this work on text from any AI model, or just ChatGPT?&lt;/strong&gt;&lt;br&gt;
The detector scores text generated by GPT-4, Claude, Gemini, Llama, and other major models, not just one vendor's output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How often are the detection models updated?&lt;/strong&gt;&lt;br&gt;
Walter retrains its detection models on a recurring basis using output from newer language models as they're released, since a static classifier trained once tends to lose accuracy as the models generating text keep changing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a free way to test this before committing to a paid plan?&lt;/strong&gt;&lt;br&gt;
Sign up at platform.walterwrites.ai to get an API key and test against your own sample text before choosing a volume tier that matches your actual usage.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Walter MCP vs. Traditional AI Humanizer Workflows: Why Developers Are Switching</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Mon, 10 Aug 2026 19:51:46 +0000</pubDate>
      <link>https://dev.to/mohab_karim/walter-mcp-vs-traditional-ai-humanizer-workflows-why-developers-are-switching-148d</link>
      <guid>https://dev.to/mohab_karim/walter-mcp-vs-traditional-ai-humanizer-workflows-why-developers-are-switching-148d</guid>
      <description>&lt;p&gt;If you've integrated a third-party AI API into a content pipeline before, you already know the pattern. Auth headers. Rate limit handling. A conditional branch to decide whether to call a second endpoint based on the first response. Retry logic for the inevitable timeout. None of that is hard, individually, but it adds up to real code you own, test, and maintain indefinitely, for a task that's conceptually simple: check this text, fix it if it needs fixing.&lt;/p&gt;

&lt;p&gt;MCP changes where that logic lives. Here's the actual before-and-after, not the marketing version.&lt;/p&gt;

&lt;h2&gt;
  
  
  The traditional workflow
&lt;/h2&gt;

&lt;p&gt;Say you're building a content pipeline that drafts text, checks it for AI-detectability, and humanizes the flagged sections before publishing. Calling a humanizer's REST API directly, the shape of that integration typically looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.example-humanizer.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/detect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;humanize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preserve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balanced&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/humanize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;preserve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;preserve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_draft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;detection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;flagged_paragraphs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;detection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;paragraphs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;flagged_paragraphs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;draft&lt;/span&gt;

    &lt;span class="c1"&gt;# Now you own the orchestration: rebuild the document from
&lt;/span&gt;    &lt;span class="c1"&gt;# flagged and unflagged sections, retry on rate limits, handle
&lt;/span&gt;    &lt;span class="c1"&gt;# partial failures, log what changed, verify preservation...
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;draft&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;flagged_paragraphs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;retries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;retries&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;humanized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;humanize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;preserve&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;humanized&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;retries&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;raise&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a simplified version. A production version needs proper logging, a real backoff strategy, preservation verification against the compliance response, and probably a queue if you're processing anything at volume. None of this is exotic engineering, it's just boilerplate that exists purely because two systems need to talk to each other, and you're the one who has to write, test, and maintain the glue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP workflow
&lt;/h2&gt;

&lt;p&gt;Here's the same task through Walter's MCP server connected to Claude:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Draft a 1,200-word article about [topic]. Detect which paragraphs read
as AI-generated. Humanize only the flagged sections, preserving these
keywords: [keyword list]. Return the final text and a summary of what
changed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No auth code, because the host manages the connection once, at setup, not per request. No conditional branching logic, because the LLM reads the detection result and decides what to humanize the same way it reads any other context. No retry logic you wrote, because that's handled at the protocol/host level, not in your application code. No manual response parsing, because the result comes back as part of the conversation, not a JSON blob you have to unpack.&lt;/p&gt;

&lt;p&gt;The setup itself is one config entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mcp_servers.walterwrites]&lt;/span&gt;
&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://mcp-server.walterwrites.ai/mcp"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, in Claude's UI, adding a custom connector with a name and a URL. Done once, used indefinitely, across every conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed, structurally
&lt;/h2&gt;

&lt;p&gt;The real shift isn't "fewer lines of code" as a vanity metric. It's where the orchestration logic lives.&lt;/p&gt;

&lt;p&gt;In the traditional model, your application is responsible for: deciding when to call detect, interpreting the response, deciding whether and what to call humanize on, handling failures at every step, and reassembling the final output. That's real application logic, specific to this integration, that has nothing to do with your actual product.&lt;/p&gt;

&lt;p&gt;In the MCP model, the LLM host owns that orchestration. It decides which tool to call based on the conversation, in what order, and how to handle the response, the same general-purpose reasoning it's already doing for everything else in the conversation. Your "integration code" is a config entry pointing at a URL. The tool-selection logic that used to live in your &lt;code&gt;if&lt;/code&gt; statements now lives in the model's reasoning, driven by your prompt instead of your source code.&lt;/p&gt;

&lt;p&gt;This is the actual point of MCP as a protocol: instead of writing custom orchestration code for every tool you want an AI system to use, you expose the tool once, in a standard format, and let the host's own reasoning handle when and how to call it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Traditional REST integration&lt;/th&gt;
&lt;th&gt;Walter MCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Auth handling&lt;/td&gt;
&lt;td&gt;Your code, per request&lt;/td&gt;
&lt;td&gt;Host-managed, once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detect-then-humanize branching&lt;/td&gt;
&lt;td&gt;Your conditional logic&lt;/td&gt;
&lt;td&gt;Model's reasoning, driven by prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry/backoff&lt;/td&gt;
&lt;td&gt;You write and maintain it&lt;/td&gt;
&lt;td&gt;Handled at host/protocol level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response parsing&lt;/td&gt;
&lt;td&gt;You unpack JSON&lt;/td&gt;
&lt;td&gt;Returned as conversational context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adding a second AI client (e.g. ChatGPT)&lt;/td&gt;
&lt;td&gt;Rewrite the integration&lt;/td&gt;
&lt;td&gt;Same server, new client config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What you maintain long-term&lt;/td&gt;
&lt;td&gt;Integration code + the pipeline logic&lt;/td&gt;
&lt;td&gt;Just the pipeline logic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last row is arguably the biggest deal for anything long-lived. A REST integration is code you own forever, it needs updating when the API changes, needs its own test coverage, needs someone who remembers why a specific retry threshold was chosen two years ago. An MCP connection is closer to infrastructure, configured once, and the burden of keeping the tool-calling logic correct shifts to the host and server maintainers rather than sitting in your repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the traditional API approach still wins
&lt;/h2&gt;

&lt;p&gt;Being straight about this, since the MCP model isn't strictly better for every case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High-throughput batch jobs outside a conversational context.&lt;/strong&gt; If you're processing 50,000 product descriptions overnight in a cron job, you want deterministic, directly-controlled API calls in a script, not an LLM conversation orchestrating tool calls. MCP is built around a host managing a conversation; a headless batch pipeline doesn't have that conversational context to begin with. Direct API access (Walter, like most serious tools in this space, still exposes one) is the right tool here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When you need guaranteed, deterministic control flow.&lt;/strong&gt; LLM-driven tool selection is reliable but not deterministic in the strict sense, the model decides when to call a tool based on reasoning over the prompt. If a compliance requirement means step B must always run after step A with zero exceptions, encoding that in your own application logic with direct API calls gives you a guarantee an LLM-orchestrated flow doesn't strictly provide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extremely latency-sensitive paths.&lt;/strong&gt; A direct API call has one network hop. An MCP-orchestrated flow goes through the host's reasoning loop first, which adds latency that matters in some real-time contexts and doesn't matter at all in others.&lt;/p&gt;

&lt;p&gt;If your workflow is genuinely conversational, iterative content drafting, an agent doing multi-step reasoning, anything where a human or another agent is in the loop deciding what to do next, MCP removes real, ongoing maintenance burden. If it's a deterministic, high-volume, headless pipeline, direct API integration is still the right call, and that's true regardless of which humanizer you're using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating an existing integration
&lt;/h2&gt;

&lt;p&gt;If you've already got a REST-based integration and want to move the conversational parts of your workflow to MCP without ripping everything out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep the direct API integration for any headless/batch paths, that use case doesn't change.&lt;/li&gt;
&lt;li&gt;For anything conversational or agent-driven, add the MCP server as a connector in whatever host you're using (Claude, ChatGPT Developer Mode, Codex) rather than routing those calls through your existing REST client.&lt;/li&gt;
&lt;li&gt;Delete the orchestration code (the detect-then-humanize branching, the retry logic specific to that flow) for the paths you've moved, that's the actual payoff, not just an additional integration option sitting next to the old one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal isn't running both forever. It's recognizing which parts of your pipeline are genuinely conversational (move to MCP, delete the glue code) and which are genuinely deterministic batch jobs (keep the direct API, it was never the wrong tool for that case).&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does Walter still offer a direct REST API alongside MCP?&lt;/strong&gt;&lt;br&gt;
Yes. MCP is the right fit for conversational, host-driven workflows. Direct API access remains the better fit for headless batch processing and pipelines requiring deterministic control flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is MCP slower than a direct API call?&lt;/strong&gt;&lt;br&gt;
There's more latency in an MCP-orchestrated flow than a single direct API call, since it goes through the host's reasoning loop first. For interactive, conversational use this is negligible. For latency-critical, high-frequency paths, direct API access is still the better choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to rewrite my whole pipeline to use MCP?&lt;/strong&gt;&lt;br&gt;
No. The two approaches are complementary, not mutually exclusive. Most teams keep direct API integration for batch/headless work and adopt MCP specifically for the conversational or agent-driven parts of their workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the actual protocol-level benefit of MCP over a custom integration?&lt;/strong&gt;&lt;br&gt;
It solves the M×N integration problem: instead of writing custom glue code for every combination of AI host and external tool, a tool is exposed once via MCP and any compliant host can use it without additional integration work on either side.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How Walter MCP Handles Keyword Preservation at Scale (With Real Prompts)</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Fri, 31 Jul 2026 00:44:18 +0000</pubDate>
      <link>https://dev.to/mohab_karim/how-walter-mcp-handles-keyword-preservation-at-scale-with-real-prompts-35n9</link>
      <guid>https://dev.to/mohab_karim/how-walter-mcp-handles-keyword-preservation-at-scale-with-real-prompts-35n9</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Generic AI humanizers have no concept of a "protected span," they rewrite everything with equal weight, which means exact-match keywords silently get paraphrased away. Walter MCP fixes this by treating preservation as an explicit constraint passed before the rewrite runs, verified afterward with a compliance report. This post covers the actual mechanism, real prompt templates for single-article and batch (up to 25 items) use, and the specific edge cases that still break if you're not precise about them.&lt;/p&gt;




&lt;p&gt;If you've ever run SEO content through a humanizer and found your target keyword quietly turned into a synonym, you've hit the core problem this post is about. It's not a bug in any specific tool, it's a structural consequence of how most humanization works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this breaks by default
&lt;/h2&gt;

&lt;p&gt;Most humanizers operate as a single, undifferentiated rewrite pass. You give them text, they give you back text that's statistically less predictable, varied sentence length, different transition words, less uniform rhythm. That's the whole mechanism. There's no concept baked into that process of "these fourteen characters must survive verbatim, everything else is fair game."&lt;/p&gt;

&lt;p&gt;So when a rewrite model decides "best CRM for small business" reads more naturally as "top CRM for small businesses," it's not malfunctioning. It's doing exactly what it was optimized to do: produce more natural, less predictable text. It just has no idea that string was your target keyword and the whole reason the article exists.&lt;/p&gt;

&lt;p&gt;This is the same class of problem as prompt injection or context leakage in other AI tooling contexts: the model has no privileged, protected region of its input unless you explicitly tell it one exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Walter's preservation mechanism actually works
&lt;/h2&gt;

&lt;p&gt;Walter MCP handles this by treating preservation as a constraint you pass explicitly before the humanization tool call runs, not something inferred from context. The flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. detect(text) → paragraph-level AI-likelihood scores
2. humanize(text, preserve=[...exact strings...], flagged_only=true)
3. compliance_report → confirms each preserved string survived
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constraint list isn't a suggestion the model weighs against naturalness. It's closer to a hard filter applied to the rewrite, exact strings you list are checked against the output, and the compliance report step exists specifically because "I told it not to change X" and "X definitely didn't change" are two different claims, and only the second one is worth trusting in an automated pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic single-article prompt
&lt;/h2&gt;

&lt;p&gt;Here's the actual prompt structure for a one-off article:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write a 1,200-word article targeting "[exact keyword]".

Then:
1. Run detection on the draft. Show me paragraph-level scores, don't
   rewrite anything yet.
2. Humanize only the paragraphs that flagged.
3. Preserve these exact strings, character for character, including
   capitalization:
   - "[exact keyword]"
   - "[Brand Name]"
   - "[Product Name]"
4. Do not touch any links or numerical data.
5. Return a compliance report confirming each preserved string survived.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The detect-first step matters as much as the preservation list. Humanizing the whole document indiscriminately increases the surface area where something you forgot to list could get touched. Scoping the rewrite to only the flagged paragraphs shrinks that risk mechanically, not just as a style preference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling it: batch preservation across many items
&lt;/h2&gt;

&lt;p&gt;Single-article preservation is straightforward. The real test is whether it holds up when you're processing 15 product descriptions or a batch of programmatic SEO pages in one pass, since that's where manual verification stops being feasible and you actually need the compliance report to be trustworthy.&lt;/p&gt;

&lt;p&gt;Walter's batch tool handles up to 25 items per call, each with its own preservation list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have 15 product descriptions. For each one:

1. Humanize the description.
2. Preserve the exact product name and price for that specific item
   (see list below, one preservation set per item).
3. Flag any item scoring above 30 on detection after humanization for
   my manual review.
4. Return a per-item compliance report.

Item 1: [description] | Preserve: "[Product Name]", "[$Price]"
Item 2: [description] | Preserve: "[Product Name]", "[$Price]"
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For programmatic SEO specifically, city-and-service landing pages being the common case, the preservation list is usually the page's exact H1 target phrase plus the service keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate 20 local landing pages from this list of [city, service] pairs.
For each page:
1. Write a 300-word page targeting "[service] in [city]".
2. Humanize it.
3. Preserve the exact phrase "[service] in [city]" in the H1 and first
   paragraph of every single page, no exceptions.
4. Confirm in the report that phrase is present and unmodified on every
   page before returning results.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last line matters more than it looks like it should. On a batch this size, "mostly correct" is a real failure mode, one page out of twenty silently losing its target phrase is exactly the kind of thing that doesn't get caught without an explicit per-item confirmation step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying preservation programmatically
&lt;/h2&gt;

&lt;p&gt;If you're wiring this into an actual pipeline rather than running it interactively, don't just trust the compliance report text, parse it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_preservation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compliance_report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required_terms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;required_terms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# crude but effective: check the term is quoted as confirmed
&lt;/span&gt;        &lt;span class="c1"&gt;# in the report text, adapt to whatever format your report returns
&lt;/span&gt;        &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compliance_report&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is intentionally simple, the actual point is: treat the compliance report as structured output you validate against your original constraint list, not prose you skim. If you're processing content at any real volume, that validation step is what turns "the tool says it worked" into something you can actually build an unattended pipeline around.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this still breaks
&lt;/h2&gt;

&lt;p&gt;Being straight about the failure modes, since pretending this is bulletproof would be more dangerous than not mentioning it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vague terms instead of exact strings.&lt;/strong&gt; "Preserve our brand name" is not the same instruction as &lt;code&gt;"Google"&lt;/code&gt;, capitalized exactly like that. The model has to infer what "our brand name" refers to, and inference is exactly the gap that produces inconsistent output. List exact strings, always.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capitalization and punctuation drift.&lt;/strong&gt; If your preservation list says &lt;code&gt;google&lt;/code&gt; and the source content uses &lt;code&gt;Google&lt;/code&gt;, you may get inconsistent casing across a batch, since you've effectively given two different targets across different items. Match the list to the source, exactly, not an approximation of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preserved terms inside a flagged paragraph that also needs structural rewriting.&lt;/strong&gt; This is the genuinely hard case. If a whole paragraph is flagged and needs rhythm/structure changes, the preserved term inside it has to survive a rewrite happening around it, not just avoid being touched directly. This is where the compliance report earns its keep, since this is the scenario most likely to produce a false sense of security without it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plural and singular mismatches.&lt;/strong&gt; Preserving "AI humanizer" doesn't guarantee "AI humanizers" (plural) is also protected, if your content actually uses both forms, list both explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reusable templates
&lt;/h2&gt;

&lt;p&gt;Copy these directly and swap in your own values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single article, SEO-focused:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write a [word count] article targeting "[keyword]". Run detection first,
humanize only flagged paragraphs, preserve "[keyword]", "[brand]", and
all links/stats exactly as written. Return a compliance report.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Batch, e-commerce:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Humanize these [N] product descriptions. Preserve each item's exact
product name and price. Flag anything scoring above [threshold] for
review. Return a per-item compliance report.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Batch, programmatic SEO:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate [N] pages from this [variable] list. Preserve "[fixed phrase
pattern]" in the H1 and first paragraph of every page. Confirm presence
on every single page in the report before returning results.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Brand-voice locked:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Apply these constraints to every piece in this conversation: always use
"[preferred term]" not "[avoided term]", always capitalize "[Term]".
After any humanization pass, confirm these rules held before returning
output.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're doing this repeatedly, these belong in a saved system prompt or a Walter Skill (a markdown file loaded into a Claude project) rather than retyped per conversation, that's a separate topic, but worth knowing the option exists once the same constraint list keeps showing up across sessions.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does keyword preservation slow down the humanization process?&lt;/strong&gt;&lt;br&gt;
Marginally, since the model has to check output against a constraint list rather than rewriting freely. In practice this is negligible compared to the time saved versus manually verifying keyword survival after the fact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if a preserved term genuinely can't fit naturally after a rewrite?&lt;/strong&gt;&lt;br&gt;
The compliance report should flag this rather than silently dropping the term or silently forcing awkward phrasing. If you see forced, unnatural insertion of a preserved term, that's a signal the surrounding paragraph needed a different rewrite approach, not just a workaround.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I preserve terms across multiple languages in one batch?&lt;/strong&gt;&lt;br&gt;
Yes, though each preserved string still needs to be listed exactly as it should appear in that specific language's version, term lists don't automatically translate or transfer between language variants in a batch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many items can be preserved and processed in a single batch call?&lt;/strong&gt;&lt;br&gt;
Up to 25 items per batch call, each with its own independent preservation list and settings.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>One MCP Server, Three Assistants: Running Walter Across Claude, ChatGPT, and Codex</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Mon, 20 Jul 2026 12:46:32 +0000</pubDate>
      <link>https://dev.to/mohab_karim/one-mcp-server-three-assistants-running-walter-across-claude-chatgpt-and-codex-156l</link>
      <guid>https://dev.to/mohab_karim/one-mcp-server-three-assistants-running-walter-across-claude-chatgpt-and-codex-156l</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; One MCP server, &lt;code&gt;https://mcp-server.walterwrites.ai/mcp&lt;/code&gt;, now works across three completely different AI clients: Claude (stable, native connector support), ChatGPT (beta, via Developer Mode), and Codex (native CLI/IDE support). Same tools, same detection and humanization logic, three different setup flows. This post covers the actual config for all three, what's different about each, and why this is a genuinely interesting case study in MCP interoperability even if you don't care about Walter specifically.&lt;/p&gt;




&lt;p&gt;Six months ago, this would've been a one-platform story. Walter's MCP server, which exposes AI text humanization and detection as callable tools, only worked inside Claude. If your team drafted in ChatGPT, or you were building internal tooling on top of Codex, you were stuck with the old copy-paste-detect-copy-paste-humanize loop that MCP exists specifically to kill.&lt;/p&gt;

&lt;p&gt;That's no longer true, and the reason it's no longer true is a good, concrete example of what the M×N integration problem MCP was built to solve actually looks like when it's solved. One server. Three clients. Zero custom integration code written on Walter's side to support any of them.&lt;/p&gt;

&lt;p&gt;Here's the setup for all three, the actual differences in how each client handles tool calling, and a few things that will save you time if you're setting this up yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is worth a post beyond "here's how to add a connector"
&lt;/h2&gt;

&lt;p&gt;If you've built or used more than one MCP server, you already know the theory: implement the spec once, any compliant host can use it. What's actually interesting here is watching that promise hold up (or not) across three hosts with meaningfully different maturity levels.&lt;/p&gt;

&lt;p&gt;Claude's MCP client implementation has been stable for a while. Tool selection is reliable, you don't need to over-specify a prompt, and the connector setup is entirely GUI-driven.&lt;/p&gt;

&lt;p&gt;ChatGPT's MCP support (branded "Developer Mode," previously part of what OpenAI called "connectors" until a December 2025 rename to "apps") is newer and still in beta. Tool selection is noticeably less reliable, meaning you have to write more explicit prompts to guarantee it reaches for the right tool instead of falling back to something built-in like web search.&lt;/p&gt;

&lt;p&gt;Codex has had MCP client support in the CLI and IDE extension for a while, configured through a shared &lt;code&gt;config.toml&lt;/code&gt;, and it's the only one of the three with zero web UI involved in setup.&lt;/p&gt;

&lt;p&gt;Same protocol. Three different levels of client maturity. If you're building your own MCP server and wondering how much you need to defensively prompt-engineer around client-side tool selection quirks, this is a useful real-world data point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The server side, briefly
&lt;/h2&gt;

&lt;p&gt;Walter's MCP server runs as a single remote, authenticated endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp-server.walterwrites.ai/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a streamable HTTP server (not stdio), which is the relevant detail for Codex config later. It exposes two main tools relevant here, &lt;code&gt;humanize&lt;/code&gt; and &lt;code&gt;detect&lt;/code&gt;, both callable the same way regardless of which client is invoking them. Same server-side logic. The differences below are entirely client-side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup 1: Claude (the baseline, simplest of the three)
&lt;/h2&gt;

&lt;p&gt;If you've set up any MCP connector in Claude before, this is nothing new.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Settings → Connectors → click &lt;strong&gt;+&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Add custom connector&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Walter Writes AI&lt;/span&gt;
&lt;span class="na"&gt;Remote MCP Server URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://mcp-server.walterwrites.ai/mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Add&lt;/strong&gt;, sign in with your Walter account, click &lt;strong&gt;Allow Access&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No further prompt engineering required, in practice Claude reliably picks the right tool from a normal, unscaffolded prompt like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Humanize this draft with Walter, then run detection on the result.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup 2: ChatGPT (beta, more moving parts)
&lt;/h2&gt;

&lt;p&gt;This is currently gated to Pro and Plus accounts on ChatGPT web (plus Business/Enterprise/Education workspaces where an admin has enabled it). A few things to know before you start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As of mid-December 2025, OpenAI renamed "connectors" to "apps." If you're looking at older docs or screenshots and can't find "Connectors" in settings, that's why.&lt;/li&gt;
&lt;li&gt;Developer Mode gives ChatGPT full MCP client support, meaning both read and write tool calls, not the older fetch-only connector model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Settings → Apps → Advanced settings&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Developer mode&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Walter Writes AI&lt;/span&gt;
&lt;span class="na"&gt;MCP Server URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://mcp-server.walterwrites.ai/mcp&lt;/span&gt;
&lt;span class="na"&gt;Authentication&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAuth&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leave the Client ID/Secret fields blank, Walter's server handles the OAuth exchange automatically once you authenticate.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check &lt;strong&gt;I trust this application&lt;/strong&gt; → Create&lt;/li&gt;
&lt;li&gt;Sign in to Walter when prompted&lt;/li&gt;
&lt;li&gt;Confirm the app shows as connected&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One more step before it's usable mid-conversation: in chat, click &lt;strong&gt;+&lt;/strong&gt; → &lt;strong&gt;More&lt;/strong&gt; → enable the Walter Writes connector.&lt;/p&gt;

&lt;h3&gt;
  
  
  The prompting gotcha
&lt;/h3&gt;

&lt;p&gt;This is the part that actually matters if you want this to work reliably. Because Developer Mode is beta, ChatGPT does not consistently infer that it should call a custom tool over falling back to something built-in. A vague prompt like "make this sound more human" might silently just get ChatGPT's own rewrite instead of an actual Walter tool call.&lt;/p&gt;

&lt;p&gt;Fix: be explicit. Name the connector, name the exact action, specify what to return, and tell it not to use web search.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Using the Walter Writes MCP connector, run the humanize action on the
draft below, then run the detect action on the result. Return the
readability score, AI score, and a short change summary. Do not use
web search.

[paste draft]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verbose, yes. Necessary right now, also yes. Check the tool call preview in the response to confirm Walter's tools are actually what got invoked, not a built-in fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup 3: Codex (fastest, zero UI)
&lt;/h2&gt;

&lt;p&gt;If you're already comfortable in a terminal, this is the quickest of the three.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A, one command:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex mcp add walterwrites &lt;span class="nt"&gt;--url&lt;/span&gt; https://mcp-server.walterwrites.ai/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option B, edit config directly.&lt;/strong&gt; Codex stores MCP server definitions in &lt;code&gt;~/.codex/config.toml&lt;/code&gt; (global) or a project-scoped &lt;code&gt;.codex/config.toml&lt;/code&gt; (only loads for directories Codex has marked trusted):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mcp_servers.walterwrites]&lt;/span&gt;
&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://mcp-server.walterwrites.ai/mcp"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Authenticate&lt;/strong&gt; (same OAuth flow as the other two, just CLI-triggered):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex mcp login walterwrites
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Verify:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex mcp list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;walterwrites&lt;/code&gt; listed as active. Inside an interactive session, &lt;code&gt;/mcp&lt;/code&gt; shows currently connected servers too.&lt;/p&gt;

&lt;p&gt;Codex will reach for Walter's tools automatically once configured. If you want that to happen without a confirmation prompt every time, set an &lt;code&gt;approval_mode&lt;/code&gt; on the tool (&lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;prompt&lt;/code&gt;, or &lt;code&gt;approve&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mcp_servers.walterwrites]&lt;/span&gt;
&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://mcp-server.walterwrites.ai/mcp"&lt;/span&gt;
&lt;span class="py"&gt;approval_mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"auto"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For consistent behavior across a whole project without repeating instructions every session, drop a line into &lt;code&gt;AGENTS.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Use Walter's humanize and detect tools automatically for any content
that needs AI-detection review or humanization before it's finalized.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters specifically for developer-facing content, README files, doc comments, CHANGELOG entries, anything written inline in a repo that might read as obviously AI-generated and would benefit from a pass before it ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  stdio vs streamable HTTP, since it comes up
&lt;/h2&gt;

&lt;p&gt;Quick clarification since this trips people up in Codex specifically: stdio servers run as a local process, spawned and piped to directly by the client. Streamable HTTP servers (what Walter uses) are remote, accessed by URL, and support OAuth or bearer token auth. That's why Walter gets added with &lt;code&gt;--url&lt;/code&gt; in Codex rather than a local command, it's not a process Codex spawns, it's a remote endpoint Codex calls over HTTP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where each one actually makes sense
&lt;/h2&gt;

&lt;p&gt;Not trying to force a false equivalence here, each of the three genuinely fits a different workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude&lt;/strong&gt; for long-form content pipelines. Tool selection just works, so it's the lowest-friction option if you're doing this regularly and don't want to think about prompt scaffolding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt; if your team is already standardized there and switching tools just for humanization isn't worth the context switch. Budget for more explicit prompts and occasional manual tool-call confirmation until Developer Mode matures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codex&lt;/strong&gt; specifically for anything developer-facing that lives inside a repo, docs, comments, generated changelogs. It's also just the fastest to set up if you're not touching a browser at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT: connector doesn't show up after creating it.&lt;/strong&gt; Start a new chat. Developer Mode changes sometimes don't reflect in an existing conversation's tool list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT: keeps using web search instead of Walter.&lt;/strong&gt; Prompt wasn't explicit enough, see the gotcha section above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT: Developer Mode isn't in Settings at all.&lt;/strong&gt; Confirm you're on web (not mobile) and on a Pro/Plus account or a workspace where an admin enabled it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex: tool call times out.&lt;/strong&gt; Default timeout is 60s. Bump &lt;code&gt;tool_timeout_sec&lt;/code&gt; in the server's config block if a specific call needs more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex: project-level config not loading.&lt;/strong&gt; Only loads for directories Codex has explicitly marked trusted, check that first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any client: OAuth won't complete.&lt;/strong&gt; Usually a pop-up blocker or browser extension eating the redirect. Check that before assuming the server's broken.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;The interesting part of this isn't really "Walter now works in three places." It's that it required zero server-side changes to get there, that's the actual point of MCP as a spec. What differs entirely is client-side maturity: Claude's implementation just works, ChatGPT's needs more explicit handholding right now because it's newer, and Codex trades a GUI for two terminal commands. If you're building your own MCP server, that maturity gap across hosts is worth planning around, because your users are going to hit it regardless of how well you've built your server.&lt;/p&gt;

&lt;p&gt;Docs for all three setups: &lt;a href="https://docs.walterwrites.ai" rel="noopener noreferrer"&gt;docs.walterwrites.ai&lt;/a&gt;. Server: &lt;a href="https://walterwrites.ai" rel="noopener noreferrer"&gt;walterwrites.ai&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does the same account work across all three?&lt;/strong&gt;&lt;br&gt;
Yes, all three authenticate against the same Walter account via OAuth. Word balance, settings, and history carry over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Codex MCP support free?&lt;/strong&gt;&lt;br&gt;
The MCP client functionality itself has no separate cost, you need an active Codex/ChatGPT account with the right access tier, plus a Walter account for the humanization credits the actual tool calls consume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a paid ChatGPT plan?&lt;/strong&gt;&lt;br&gt;
Yes, currently. Developer Mode requires Pro or Plus individually, or a Business/Enterprise/Education workspace where an admin has turned it on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does ChatGPT need more explicit prompts than Claude?&lt;/strong&gt;&lt;br&gt;
Claude's MCP implementation has been stable longer and reliably infers the right tool from context. ChatGPT's Developer Mode is newer and still beta, tool selection isn't as consistent yet, so explicit naming of the connector and action is currently required for reliable behavior.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>5 Real-World Use Cases for Walter MCP in Claude</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Fri, 26 Jun 2026 15:05:59 +0000</pubDate>
      <link>https://dev.to/mohab_karim/5-real-world-use-cases-for-walter-mcp-in-claude-1c</link>
      <guid>https://dev.to/mohab_karim/5-real-world-use-cases-for-walter-mcp-in-claude-1c</guid>
      <description>&lt;p&gt;Most MCP tool breakdowns stop at "here is what it does." This one goes further.&lt;/p&gt;

&lt;p&gt;Walter MCP is an MCP server that connects Walter Writes AI directly inside Claude, bringing AI humanization, detection, and batch processing into your conversations without switching tools. If you have seen it mentioned but never understood why someone would actually build a workflow around it, this article is for you.&lt;/p&gt;

&lt;p&gt;Below are five use cases that are working in production right now, with the logic behind each one and the prompts that make them run.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What Walter MCP Actually Adds to Claude&lt;/li&gt;
&lt;li&gt;Quick Setup&lt;/li&gt;
&lt;li&gt;Use Case 1: SEO Content Pipeline with Keyword Lock-In&lt;/li&gt;
&lt;li&gt;Use Case 2: Agency QC Before Client Delivery&lt;/li&gt;
&lt;li&gt;Use Case 3: Programmatic SEO at Scale&lt;/li&gt;
&lt;li&gt;Use Case 4: Content Repurposing Across Formats&lt;/li&gt;
&lt;li&gt;Use Case 5: Brand Voice Consistency Across a Team&lt;/li&gt;
&lt;li&gt;Adding Walter Skills for Repeatable Workflows&lt;/li&gt;
&lt;li&gt;Installing the Skills Library&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Walter MCP Actually Adds to Claude
&lt;/h2&gt;

&lt;p&gt;Before the use cases, a quick orientation on what the connector provides.&lt;/p&gt;

&lt;p&gt;When you connect Walter MCP to Claude, three tools become available in every conversation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;humanize&lt;/code&gt;&lt;/strong&gt; rewrites AI-patterned text to remove the statistical signatures that detection tools flag: uniform sentence rhythm, predictable transitions, vocabulary predictability. Keywords, links, brand names, and heading structure stay intact when you specify them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;detect&lt;/code&gt;&lt;/strong&gt; scores text from 0 to 100 and returns a verdict (&lt;code&gt;likely_human&lt;/code&gt;, &lt;code&gt;mixed&lt;/code&gt;, &lt;code&gt;likely_ai&lt;/code&gt;) with paragraph-level feedback. It tells you which specific paragraphs triggered the score and the pattern that caused it, not just a single document number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;batch_humanize&lt;/code&gt;&lt;/strong&gt; processes up to 25 items in one call, each with optional individual settings. Built for content operations running at volume.&lt;/p&gt;

&lt;p&gt;These tools run inside Claude conversations through the Model Context Protocol. Claude makes the call, the tool returns the result, and the workflow continues in the same thread. No copy-paste. No tabs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Setup
&lt;/h2&gt;

&lt;p&gt;Three minutes, no developer configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Open Claude, go to &lt;strong&gt;Settings &amp;gt; Connectors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Click &lt;strong&gt;+&lt;/strong&gt; then &lt;strong&gt;Add custom connector&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Fill in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Walter Writes AI&lt;/span&gt;
&lt;span class="err"&gt;Remote&lt;/span&gt; &lt;span class="err"&gt;MCP&lt;/span&gt; &lt;span class="err"&gt;Server&lt;/span&gt; &lt;span class="py"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://mcp-server.walterwrites.ai/mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt; Click &lt;strong&gt;Add&lt;/strong&gt;, then connect your Walter account and click &lt;strong&gt;Allow Access&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Done. Walter is now available in every Claude conversation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Use Case 1: SEO Content Pipeline with Keyword Lock-In
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; You are drafting blog posts with Claude and the output is solid structurally, but it scores 90+ on AI detection and the humanizer you use keeps paraphrasing your target keyword.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; For SEO content, the exact phrasing of your target keyword is not interchangeable. "Best CRM for small business" and "top CRM for small businesses" are different strings with different search behavior. Any humanizer that treats your content as a blob will rewrite those phrases without awareness of what it is costing you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Walter MCP approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run detection first to identify which sections are actually flagging, then humanize only those with explicit constraints.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1 — Diagnostic:
"Use Walter to detect which paragraphs in this draft are flagging as
AI-generated. Do not rewrite anything yet. Show me the paragraph-level
feedback."

Step 2 — Targeted humanization:
"Humanize only the flagged sections. Apply these constraints:
- Keep 'best CRM for small business' exactly as written in every occurrence
- Do not change any anchor text or URLs
- Preserve all statistics
- Keep the heading structure intact"

Step 3 — Verify:
"Run Walter detection on the humanized version and show me the
before/after scores."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you get:&lt;/strong&gt; A detection compliance report showing the score drop, a preservation compliance report confirming every keyword survived, and a humanized draft ready to review. All in one conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical result:&lt;/strong&gt; Raw Claude drafts that score 90 to 98 on detection consistently land in the 20 to 30 range after one targeted pass. Keyword survival rate is 100 percent when constraints are specified.&lt;/p&gt;




&lt;h2&gt;
  
  
  Use Case 2: Agency QC Before Client Delivery
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; You run an agency. Content goes through writers, gets AI-assisted, gets edited, and then goes to a QC step before client delivery. The QC step is currently manual and inconsistent: different reviewers catch different things, some keyword checks get missed, and the turnaround before delivery is longer than it should be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; An inconsistent QC process is a client relationship risk. If one client's content goes out with a paraphrased brand name or a detection score that surprises them, that is a credibility problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Walter MCP approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Load this as your QC prompt at the start of each review session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I am going to paste a client article below. Run the following QC pipeline:

1. Use Walter to detect the full article and return the score, verdict,
   and paragraph-level breakdown.
2. For any paragraph scoring above 40, humanize just that paragraph.
3. After humanizing, run detection again on the full article.
4. Return: original score, final score, list of changed paragraphs,
   and a preservation report confirming the following survived:
   [client brand name], [target keyword], [specific product names],
   [all links].

Here is the article: [paste]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you get:&lt;/strong&gt; A structured QC report for every article. Original detection score, final score after targeted humanization, list of specific changes made, and confirmation that every protected element is still intact. That report is also your documentation if a client ever asks what QC looks like on their content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reality check:&lt;/strong&gt; This workflow is faster than manual QC but it is not a replacement for a final human read. Detection and preservation are mechanical checks. Whether the article makes a good argument and is factually accurate is still on you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Use Case 3: Programmatic SEO at Scale
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; You are generating location pages, product description pages, or any other template-driven content at volume. You have 50 city pages to generate, humanize, and verify before they go live.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Programmatic SEO content produced at volume tends to have two failure modes. Either it is too uniform (detection tools treat similar pages as a pattern) or the humanization step introduces enough variation that the target keyword changes across pages. Both are problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Walter MCP approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where &lt;code&gt;batch_humanize&lt;/code&gt; becomes the key feature. One call handles up to 25 items simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I have a list of city-and-service combinations for local landing pages.
For each one:

1. Write a 300-word local landing page targeting '[service] in [city]'.
2. Humanize each page with Walter.
3. Preserve the exact phrase '[service] in [city]' in the H1 and
   first paragraph of every page.
4. Return a per-page detection score and preservation confirmation.
5. Flag any page that scores above 30 for my review.

Here are the first 25 city-service combinations: [list]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this in batches of 25. Review flagged pages individually. Export the compliant ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For developers building content pipelines:&lt;/strong&gt; The Walter MCP batch tool through Claude is a useful prototyping layer before you commit to direct API integration. You can validate your keyword constraints and output format on real content without writing any code.&lt;/p&gt;

&lt;p&gt;The SK-03 Local SEO Machine skill from the Walter Skills library automates this exact pattern as a project-level instruction, so every chat in a project runs it without re-specifying the workflow each time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Use Case 4: Content Repurposing Across Formats
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; You have a 2,000-word pillar article that took real research and effort to produce. You want to get a LinkedIn post, an email newsletter intro, a Twitter/X thread hook, and a short blog summary out of it without rewriting each format manually from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Content repurposing is one of those tasks that sounds simple and is actually tedious. Each format has different length expectations, different tone conventions, and different structural requirements. And if the source article was AI-assisted, every format you derive from it inherits those AI patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Walter MCP approach:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Take the article below and produce the following four formats:

1. LinkedIn post (200 to 250 words, professional but conversational)
2. Email newsletter intro (150 words, direct, first-person)
3. Twitter/X thread hook (first post only, under 280 characters,
   strong opening)
4. Blog summary (100 words, third-person, for a related article
   roundup)

After generating all four:
- Humanize each one with Walter independently
- Run detection on each and return the score
- Preserve these data points in every format that uses them:
  [specific stat 1], [specific stat 2]
- Preserve these brand mentions: [brand name]

Here is the source article: [paste]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you get:&lt;/strong&gt; Four formats, each humanized to the appropriate tone for its platform, with detection scores confirming each one reads as human-written. The data points and brand mentions you care about carry across all four.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note on format:&lt;/strong&gt; LinkedIn and email copy humanizes differently than blog content. The Walter humanization engine adjusts for length and register. Short-form content in particular benefits from the balanced mode rather than enhanced, which can over-engineer very short pieces.&lt;/p&gt;




&lt;h2&gt;
  
  
  Use Case 5: Brand Voice Consistency Across a Team
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; You have three writers using Claude to draft content for the same brand. Each writer prompts differently. Each gets slightly different output. The content is technically fine but does not sound like it came from the same company. The brand guidelines document exists but nobody reads it before every prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Brand voice inconsistency compounds. The longer a team produces inconsistent content, the harder it is to establish the coherent brand identity that drives recognition and trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Walter MCP approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This use case is best handled through a Walter Skill rather than a per-conversation prompt, specifically SK-08 Brand Voice Adapter. But you can also build a version of it inline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"You are writing for [Brand Name]. Apply the following brand voice rules
to every piece of content in this conversation:

Brand voice: [direct / warm / technical / casual / formal]
Always use: 'platform' not 'tool', 'team' not 'staff'
Always capitalize: [Brand Name], [Product Name]
Avoid: passive voice, hedge words like 'perhaps' and 'possibly',
       sentences longer than 25 words in CTAs

After drafting any piece of content:
1. Run Walter detection and return the score
2. Humanize if the score is above 35
3. Apply the brand voice constraints above to the humanized version
4. Confirm all capitalization rules are intact before returning output"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every writer on the team pastes this at the start of their session. Every Claude conversation in the project applies the same rules. Detection and humanization are baked in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For consistent team use:&lt;/strong&gt; Load the SK-08 Brand Voice Adapter skill into a Claude project's instructions once. Every writer who opens a chat in that project gets the brand voice rules and the Walter workflow applied automatically, without pasting anything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Adding Walter Skills for Repeatable Workflows
&lt;/h2&gt;

&lt;p&gt;All five use cases above work as one-off prompts. But if you are running any of them regularly, you do not want to re-specify the workflow every time you start a new conversation.&lt;/p&gt;

&lt;p&gt;Walter Skills solve this.&lt;/p&gt;

&lt;p&gt;A skill is a markdown file you paste once into a Claude project's instructions. Every chat in that project then applies the full workflow automatically. No re-prompting. No forgotten constraints. No inconsistent output because someone used a slightly different version of the prompt.&lt;/p&gt;

&lt;p&gt;The full library has 12 skills:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SK-01&lt;/strong&gt; SEO Content Writer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-02&lt;/strong&gt; Agency QC Pipeline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-03&lt;/strong&gt; Local SEO Machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-04&lt;/strong&gt; Content Repurposer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-05&lt;/strong&gt; E-commerce Engine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-06&lt;/strong&gt; Newsletter Writer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-07&lt;/strong&gt; Programmatic SEO&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-08&lt;/strong&gt; Brand Voice Adapter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-09&lt;/strong&gt; Documentation Writer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-10&lt;/strong&gt; Lead Magnet Creator&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-11&lt;/strong&gt; Social Media Suite&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SK-12&lt;/strong&gt; Content Refresh Engine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo is at: &lt;a href="https://github.com/walterwritesai/walter-skills" rel="noopener noreferrer"&gt;github.com/walterwritesai/walter-skills&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing the Skills Library
&lt;/h2&gt;

&lt;p&gt;The Walter Skills library is on the skills.sh registry, Vercel Labs' npx CLI ecosystem for agent skills.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add walterwritesai/walter-skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That installs the full library. Each install also counts toward the leaderboard ranking on skills.sh, which drives discovery in the registry. If you are building with Claude Code or another agent environment, this is the fastest way to get the skills locally.&lt;/p&gt;

&lt;p&gt;For a community-maintained guide covering all 65 prompts across 12 workflow categories, &lt;a href="https://waltermcp.com" rel="noopener noreferrer"&gt;waltermcp.com&lt;/a&gt; is the most comprehensive reference available (community-run, not an official Walter resource).&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;MCP connectors are only useful if there are real workflows to run through them. These five cover the use cases that show up most often in production content operations: SEO pipelines with strict keyword requirements, agency QC before client delivery, programmatic SEO at volume, multi-format content repurposing, and brand voice consistency across teams.&lt;/p&gt;

&lt;p&gt;The common thread across all of them is that the workflow runs inside one Claude conversation. Detection, humanization, keyword protection, and compliance reporting all happen in the same thread where the draft was written.&lt;/p&gt;

&lt;p&gt;If you are already using Claude for content work and spending time on the manual cleanup afterward, the connector is worth the three-minute setup. Start at &lt;a href="https://walterwrites.ai" rel="noopener noreferrer"&gt;walterwrites.ai&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is Walter MCP?&lt;/strong&gt;&lt;br&gt;
Walter MCP is the MCP server for Walter Writes AI. It exposes humanization, AI detection, and batch processing as callable tools inside Claude through the Model Context Protocol. Workflows that previously required multiple separate tools run inside a single Claude conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need coding experience to set this up?&lt;/strong&gt;&lt;br&gt;
No. Setup is three steps in Claude's Settings panel: add the connector URL, sign in to Walter, click Allow Access. No API keys, no configuration files, no terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;detect&lt;/code&gt; and &lt;code&gt;humanize&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;detect&lt;/code&gt; is the diagnostic. It scans text and returns a score with paragraph-level feedback on what is flagging and why. &lt;code&gt;humanize&lt;/code&gt; is the fix. It rewrites the flagged patterns. Running detect first, then humanizing only the flagged sections, produces better results than running humanize blindly on the full document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can Walter MCP preserve exact keyword phrases?&lt;/strong&gt;&lt;br&gt;
Yes, when you specify them as constraints before the humanization runs. You name the exact phrases, brand names, links, and data that must survive. Walter returns a preservation compliance report confirming every protected element made it through the rewrite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is batch_humanize and when should I use it?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;batch_humanize&lt;/code&gt; processes up to 25 items in a single call, each with optional individual settings. Use it for programmatic SEO pages, product description catalogs, or any workflow where you are processing multiple pieces of content simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are Walter Skills and how do they relate to MCP?&lt;/strong&gt;&lt;br&gt;
Walter Skills are markdown files you paste into a Claude project's instructions once. They encode the workflow: which detection threshold to use, which humanization mode, how to handle keyword constraints, what the output format should be. The MCP connector provides the tools. The skill provides the workflow logic so you do not re-specify it every conversation. Install them with &lt;code&gt;npx skills add walterwritesai/walter-skills&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What detection scores should I expect?&lt;/strong&gt;&lt;br&gt;
Raw Claude drafts typically score 90 to 98. After one targeted Walter humanization pass using the detect-first approach, scores consistently land in the 10 to 20 range, classified as &lt;code&gt;likely_human&lt;/code&gt;. Word limits per call depend on your Walter plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where can I find more prompts for these workflows?&lt;/strong&gt;&lt;br&gt;
The community guide at &lt;a href="https://waltermcp.com" rel="noopener noreferrer"&gt;waltermcp.com&lt;/a&gt; covers 65 prompts across 12 workflow categories. Community-maintained, not an official Walter resource, but comprehensive and regularly updated.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>mcp</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Walter Writes AI Humanizer MCP in Claude: How to Set It Up</title>
      <dc:creator>Mohab Abdelkarim</dc:creator>
      <pubDate>Thu, 11 Jun 2026 23:40:03 +0000</pubDate>
      <link>https://dev.to/mohab_karim/walter-writes-ai-humanizer-mcp-in-claude-how-to-set-it-up-2oj5</link>
      <guid>https://dev.to/mohab_karim/walter-writes-ai-humanizer-mcp-in-claude-how-to-set-it-up-2oj5</guid>
      <description>&lt;p&gt;If you use Claude to draft content, you probably know the annoying part.&lt;/p&gt;

&lt;p&gt;Claude can write fast.&lt;/p&gt;

&lt;p&gt;But when the draft is done, you still end up doing the same manual loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the text.&lt;/li&gt;
&lt;li&gt;Paste it into a humanizer.&lt;/li&gt;
&lt;li&gt;Check it with an AI detector.&lt;/li&gt;
&lt;li&gt;Go back to Claude.&lt;/li&gt;
&lt;li&gt;Edit again.&lt;/li&gt;
&lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is not really a workflow. It is tab-switching.&lt;/p&gt;

&lt;p&gt;This is where Walter MCP is interesting.&lt;/p&gt;

&lt;p&gt;Walter Writes connects to Claude through MCP, so you can humanize AI text, run AI detection, and batch-process content without leaving the same Claude conversation.&lt;/p&gt;

&lt;p&gt;In this guide, I’ll walk through how to set it up, how to test it, how to use it with Walter Skills, and how I would structure a real content workflow around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Walter MCP lets Claude call Walter Writes directly as a tool.&lt;/p&gt;

&lt;p&gt;Once connected, Claude can use Walter to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;humanize AI-generated drafts&lt;/li&gt;
&lt;li&gt;run AI detection&lt;/li&gt;
&lt;li&gt;process multiple pieces of content&lt;/li&gt;
&lt;li&gt;preserve important keywords and entities&lt;/li&gt;
&lt;li&gt;reduce copy-paste between tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers, agencies, and SEO teams, the main benefit is not just “better rewriting.”&lt;/p&gt;

&lt;p&gt;The real benefit is workflow control.&lt;/p&gt;

&lt;p&gt;Instead of treating humanization and detection as separate browser steps, you can make them part of the Claude workflow itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;MCP stands for Model Context Protocol.&lt;/p&gt;

&lt;p&gt;The simple explanation:&lt;/p&gt;

&lt;p&gt;MCP is a standard way for AI assistants to connect to external tools.&lt;/p&gt;

&lt;p&gt;Instead of every tool needing a custom integration with every AI app, MCP gives tools a more standard way to expose functions that an assistant can call.&lt;/p&gt;

&lt;p&gt;So in this case:&lt;/p&gt;

&lt;p&gt;Claude is the AI assistant.&lt;br&gt;
Walter Writes is the external tool.&lt;br&gt;
MCP is the bridge between them.&lt;/p&gt;

&lt;p&gt;Once Walter is connected, Claude can call Walter’s tools when your prompt needs them.&lt;/p&gt;

&lt;p&gt;That is the difference between asking Claude:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Make this sound more human.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and asking Claude to use a dedicated humanization/detection workflow through Walter.&lt;/p&gt;

&lt;p&gt;The second approach is more repeatable.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Walter Adds Inside Claude
&lt;/h2&gt;

&lt;p&gt;Walter’s MCP connector adds three useful actions inside Claude:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Humanize&lt;/strong&gt;&lt;br&gt;
This rewrites AI-patterned text into more natural writing while trying to preserve the meaning, structure, keywords, links, and important entities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detect&lt;/strong&gt;&lt;br&gt;
This checks text for AI-writing patterns and gives feedback on where the text still looks too AI-generated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Batch Humanize&lt;/strong&gt;&lt;br&gt;
This is for processing multiple pieces at once, which is useful for agencies, content teams, and programmatic SEO workflows.&lt;/p&gt;

&lt;p&gt;The important part is that these tools live inside the same Claude workflow.&lt;/p&gt;

&lt;p&gt;You can draft in Claude, humanize with Walter, detect the result, and revise again without copying the text between multiple apps.&lt;/p&gt;
&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;p&gt;You will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Claude account&lt;/li&gt;
&lt;li&gt;Access to Claude connectors&lt;/li&gt;
&lt;li&gt;A Walter Writes account&lt;/li&gt;
&lt;li&gt;The Walter MCP server URL&lt;/li&gt;
&lt;li&gt;A draft or sample text to test with&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Walter MCP server URL is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp-server.walterwrites.ai/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would also keep these open while setting things up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Official Walter Claude/MCP guide:
https://walterwrites.ai/humanize-ai-text-inside-claude/

Walter Skills GitHub repo:
https://github.com/walterwritesai/walter-skills

Community guide, not official:
https://waltermcp.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important note: WalterMCP.com should be treated as a community guide, not the official Walter documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Open Claude Connectors
&lt;/h2&gt;

&lt;p&gt;In Claude, go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Settings → Connectors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where you manage external tools that Claude can connect to.&lt;/p&gt;

&lt;p&gt;Look for the option to add a custom connector.&lt;/p&gt;

&lt;p&gt;Depending on your Claude interface, this may appear as a plus button or an “Add custom connector” option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Add Walter as a Custom Connector
&lt;/h2&gt;

&lt;p&gt;Create a new connector with a clear name.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Walter Writes AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then paste the MCP server URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp-server.walterwrites.ai/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the connector.&lt;/p&gt;

&lt;p&gt;Claude should now know that Walter exists as an external MCP tool.&lt;/p&gt;

&lt;p&gt;If Claude asks for permissions or approval when using the connector, approve the relevant actions when you actually want Walter to run.&lt;/p&gt;

&lt;p&gt;That approval step is a good thing. MCP tools can perform actions, so you should stay aware of what Claude is calling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Test the Connection
&lt;/h2&gt;

&lt;p&gt;Do not start with a full article.&lt;/p&gt;

&lt;p&gt;Start with a small test.&lt;/p&gt;

&lt;p&gt;Paste a short AI-written paragraph into Claude and ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use Walter to detect whether this text sounds AI-generated.

Text:
[Paste your paragraph here]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the connector is working, Claude should call Walter’s detection tool and return a result.&lt;/p&gt;

&lt;p&gt;Then test humanization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use Walter to humanize this paragraph while preserving the meaning and keeping the keyword "AI image detector" unchanged.

Text:
[Paste your paragraph here]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test matters because it checks three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude can access Walter.&lt;/li&gt;
&lt;li&gt;Walter can process your text.&lt;/li&gt;
&lt;li&gt;Claude understands your constraints.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not skip this step.&lt;/p&gt;

&lt;p&gt;A lot of MCP setups technically connect but fail when you ask the tool to do real work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Try a Full Draft Workflow
&lt;/h2&gt;

&lt;p&gt;Once the basic test works, try a real workflow.&lt;/p&gt;

&lt;p&gt;Here is a prompt I would use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I’m writing an article for Medium.

Please do this workflow:

1. Review the draft for AI-sounding sections.
2. Use Walter to humanize the sections that feel too robotic.
3. Preserve all keywords, brand names, links, headings, and factual claims.
4. Run detection again after humanizing.
5. Give me a short summary of what changed.

Draft:
[Paste draft here]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where Walter MCP becomes useful.&lt;/p&gt;

&lt;p&gt;You are not just asking Claude to rewrite everything.&lt;/p&gt;

&lt;p&gt;You are asking Claude to run a process.&lt;/p&gt;

&lt;p&gt;That is a big difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Use Walter Skills for Repeatable Workflows
&lt;/h2&gt;

&lt;p&gt;The Walter Skills repo is useful if you do not want to rewrite the same workflow prompt every time.&lt;/p&gt;

&lt;p&gt;A Claude Skill is basically a reusable instruction file.&lt;/p&gt;

&lt;p&gt;Instead of telling Claude the same rules in every chat, you add the skill once to a Claude project. After that, the project knows how to behave for that type of work.&lt;/p&gt;

&lt;p&gt;The Walter Skills repo includes skills for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SEO content writing&lt;/li&gt;
&lt;li&gt;agency QC&lt;/li&gt;
&lt;li&gt;local SEO&lt;/li&gt;
&lt;li&gt;content repurposing&lt;/li&gt;
&lt;li&gt;e-commerce product writing&lt;/li&gt;
&lt;li&gt;newsletters&lt;/li&gt;
&lt;li&gt;programmatic SEO&lt;/li&gt;
&lt;li&gt;brand voice adaptation&lt;/li&gt;
&lt;li&gt;content refreshes&lt;/li&gt;
&lt;li&gt;lead magnets&lt;/li&gt;
&lt;li&gt;social media&lt;/li&gt;
&lt;li&gt;docs writing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic install flow is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Walter Skills GitHub repo.&lt;/li&gt;
&lt;li&gt;Pick the skill folder that matches your workflow.&lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;SKILL.md&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Copy the full markdown.&lt;/li&gt;
&lt;li&gt;Paste it into your Claude project instructions.&lt;/li&gt;
&lt;li&gt;Make sure Walter MCP is connected so Claude can actually call Walter’s tools.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, if you are producing SEO articles, start with the SEO content skill.&lt;/p&gt;

&lt;p&gt;If you are reviewing content for clients, the agency QC skill may be a better starting point.&lt;/p&gt;

&lt;p&gt;If you are updating old articles, use the content refresh skill.&lt;/p&gt;

&lt;p&gt;The skill gives Claude the repeatable workflow.&lt;br&gt;
The MCP connector gives Claude the tool access.&lt;/p&gt;

&lt;p&gt;You need both if you want the workflow to feel automatic.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Simple Developer Mental Model
&lt;/h2&gt;

&lt;p&gt;I think about it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude = reasoning layer
Walter MCP = tool layer
Walter Skills = workflow layer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude decides what needs to happen.&lt;/p&gt;

&lt;p&gt;Walter performs the humanization and detection actions.&lt;/p&gt;

&lt;p&gt;Walter Skills tell Claude how to behave in a specific workflow.&lt;/p&gt;

&lt;p&gt;That combination is more powerful than a one-off prompt.&lt;/p&gt;

&lt;p&gt;Without a skill, you have to explain the workflow every time.&lt;/p&gt;

&lt;p&gt;Without MCP, Claude can only rewrite with its own general writing ability.&lt;/p&gt;

&lt;p&gt;With both, you can create a more repeatable process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Draft → detect → humanize → preserve keywords → detect again → final review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the workflow most SEO teams and content teams actually want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: SEO Article Workflow
&lt;/h2&gt;

&lt;p&gt;Here is a practical prompt for SEO content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are helping me prepare an SEO article for publishing.

Use Walter where needed.

Workflow:
1. Check the draft for AI-sounding paragraphs.
2. Humanize only the sections that need it.
3. Keep the target keyword exactly as written.
4. Preserve all internal links, brand names, headings, and statistics.
5. Do not change the search intent.
6. After humanizing, run detection again.
7. Give me the final version plus a short change summary.

Target keyword:
[insert keyword]

Draft:
[paste draft]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is better than saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Make this sound human.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That prompt is too vague.&lt;/p&gt;

&lt;p&gt;The better prompt gives Claude constraints and tells it when to use Walter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Batch Humanization Workflow
&lt;/h2&gt;

&lt;p&gt;For agencies, batch processing is where this becomes more interesting.&lt;/p&gt;

&lt;p&gt;Imagine you have 10 short product descriptions or 20 local SEO pages.&lt;/p&gt;

&lt;p&gt;Instead of processing each one manually, you can ask Claude to use Walter’s batch flow.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have a batch of short AI-generated descriptions.

Use Walter Batch Humanize to process them.

Rules:
- Keep product names unchanged.
- Keep location names unchanged.
- Keep all prices and specifications unchanged.
- Do not add new claims.
- Return the results in the same order.
- After processing, flag any description that still sounds too AI-generated.

Items:
1. [text]
2. [text]
3. [text]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For programmatic SEO or e-commerce, this can save a lot of repetitive work.&lt;/p&gt;

&lt;p&gt;The main thing is to be strict about preservation rules.&lt;/p&gt;

&lt;p&gt;Any workflow that touches SEO content should protect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;target keywords&lt;/li&gt;
&lt;li&gt;product names&lt;/li&gt;
&lt;li&gt;brand names&lt;/li&gt;
&lt;li&gt;locations&lt;/li&gt;
&lt;li&gt;URLs&lt;/li&gt;
&lt;li&gt;prices&lt;/li&gt;
&lt;li&gt;statistics&lt;/li&gt;
&lt;li&gt;factual claims&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Humanization is useful only if it does not break the information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Detection-Only Workflow
&lt;/h2&gt;

&lt;p&gt;Sometimes you do not need to humanize immediately.&lt;/p&gt;

&lt;p&gt;You just need to check what needs work.&lt;/p&gt;

&lt;p&gt;For that, use a detection-first prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use Walter to detect AI-writing patterns in this draft.

Do not rewrite yet.

Return:
1. Overall detection result
2. The sections most likely to be flagged
3. What writing patterns caused the issue
4. A recommended edit plan

Draft:
[paste draft]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I like this approach because it avoids over-editing.&lt;/p&gt;

&lt;p&gt;Not every paragraph needs to be rewritten. Sometimes only the intro, conclusion, or transition-heavy sections are the problem.&lt;/p&gt;

&lt;p&gt;Detection first helps you edit more carefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Setup Issues
&lt;/h2&gt;

&lt;p&gt;Here are the problems I would check first if Walter does not work in Claude.&lt;/p&gt;

&lt;h3&gt;
  
  
  The connector URL is wrong
&lt;/h3&gt;

&lt;p&gt;Double-check the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp-server.walterwrites.ai/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small typo is enough to break the connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude has not been restarted or refreshed
&lt;/h3&gt;

&lt;p&gt;After adding a connector, refresh Claude or start a new conversation.&lt;/p&gt;

&lt;p&gt;Sometimes the connector is added, but the current chat does not pick it up cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  You are asking Claude too vaguely
&lt;/h3&gt;

&lt;p&gt;This prompt may not trigger the tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Make this better.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use Walter to humanize this text and then run AI detection on the result.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be direct.&lt;/p&gt;

&lt;h3&gt;
  
  
  You forgot the preservation rules
&lt;/h3&gt;

&lt;p&gt;If you care about exact keywords or entities, say that.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Preserve the exact keyword "AI image detector" and do not change brand names, URLs, or statistics.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The text is too long for the workflow
&lt;/h3&gt;

&lt;p&gt;If you are testing for the first time, start small.&lt;/p&gt;

&lt;p&gt;Use one paragraph first. Then one section. Then a full article.&lt;/p&gt;

&lt;p&gt;Debugging a 3,000-word article is annoying if you do not know whether the connector works yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Notes for MCP
&lt;/h2&gt;

&lt;p&gt;MCP is powerful because it lets AI assistants call external tools.&lt;/p&gt;

&lt;p&gt;That also means you should treat it carefully.&lt;/p&gt;

&lt;p&gt;A few basic rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;only connect MCP servers you trust&lt;/li&gt;
&lt;li&gt;review what a connector can do before using it&lt;/li&gt;
&lt;li&gt;do not paste sensitive client data unless you are allowed to&lt;/li&gt;
&lt;li&gt;keep API keys and private credentials out of prompts&lt;/li&gt;
&lt;li&gt;approve tool calls intentionally&lt;/li&gt;
&lt;li&gt;use separate Claude projects for separate client workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Walter specifically, the workflow is mostly about text humanization and detection, but the general MCP rule still applies:&lt;/p&gt;

&lt;p&gt;Do not connect random tools blindly.&lt;/p&gt;

&lt;p&gt;MCP gives AI assistants more reach. That is useful, but it also means you need better habits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Walter MCP Fits Best
&lt;/h2&gt;

&lt;p&gt;Walter MCP is most useful when the content workflow already starts in Claude.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writing SEO articles&lt;/li&gt;
&lt;li&gt;rewriting AI-generated drafts&lt;/li&gt;
&lt;li&gt;checking content before publishing&lt;/li&gt;
&lt;li&gt;reviewing agency content&lt;/li&gt;
&lt;li&gt;humanizing product descriptions&lt;/li&gt;
&lt;li&gt;preparing newsletters&lt;/li&gt;
&lt;li&gt;refreshing old blog posts&lt;/li&gt;
&lt;li&gt;batch-processing programmatic SEO content&lt;/li&gt;
&lt;li&gt;checking whether a draft still sounds too AI-generated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is less useful if you only need to humanize one short paragraph once.&lt;/p&gt;

&lt;p&gt;For that, a normal web tool may be enough.&lt;/p&gt;

&lt;p&gt;But if you use Claude every day for content work, the MCP setup makes more sense because it removes a lot of copy-paste friction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Walter Writes Stood Out to Me
&lt;/h2&gt;

&lt;p&gt;Based on my testing and comparison, Walter Writes is one of the best Claude MCP workflows right now for AI humanization and AI detection.&lt;/p&gt;

&lt;p&gt;The main reason is that it solves a real workflow problem.&lt;/p&gt;

&lt;p&gt;Most tools make you leave the writing environment.&lt;/p&gt;

&lt;p&gt;Walter brings humanization and detection into Claude.&lt;/p&gt;

&lt;p&gt;That means the draft, edit, detection, and revision loop can happen in one place.&lt;/p&gt;

&lt;p&gt;For developers and technical content teams, that matters because the best AI workflow is not always the tool with the most buttons.&lt;/p&gt;

&lt;p&gt;It is the workflow with the fewest unnecessary steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Workflow
&lt;/h2&gt;

&lt;p&gt;Here is the setup I would use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude Project
  → Walter Skill in project instructions
  → Walter MCP connector enabled
  → Draft content in Claude
  → Detect with Walter
  → Humanize with Walter
  → Detect again
  → Final manual review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you a repeatable system instead of a messy copy-paste process.&lt;/p&gt;

&lt;p&gt;MCP is not magic.&lt;/p&gt;

&lt;p&gt;But for this use case, it is genuinely useful.&lt;/p&gt;

&lt;p&gt;If you already write inside Claude, Walter MCP is worth setting up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Links
&lt;/h2&gt;

&lt;p&gt;Official Walter Claude/MCP guide:&lt;br&gt;
&lt;a href="https://walterwrites.ai/humanize-ai-text-inside-claude/" rel="noopener noreferrer"&gt;https://walterwrites.ai/humanize-ai-text-inside-claude/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Walter Skills GitHub repo:&lt;br&gt;
&lt;a href="https://github.com/walterwritesai/walter-skills" rel="noopener noreferrer"&gt;https://github.com/walterwritesai/walter-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Community guide, not official:&lt;br&gt;
&lt;a href="https://waltermcp.com/" rel="noopener noreferrer"&gt;https://waltermcp.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Walter Writes:&lt;br&gt;
&lt;a href="https://walterwrites.ai/" rel="noopener noreferrer"&gt;https://walterwrites.ai/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
