<?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: Stephen Phillips</title>
    <description>The latest articles on DEV Community by Stephen Phillips (@sphillips1337).</description>
    <link>https://dev.to/sphillips1337</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%2F3818444%2F35de90af-d488-4f0e-9ad2-8195836098b7.jpeg</url>
      <title>DEV Community: Stephen Phillips</title>
      <link>https://dev.to/sphillips1337</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sphillips1337"/>
    <language>en</language>
    <item>
      <title>Your Small Business Agent Does Not Need Every Tool</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sun, 16 Aug 2026 16:41:02 +0000</pubDate>
      <link>https://dev.to/sphillips1337/your-small-business-agent-does-not-need-every-tool-5fc6</link>
      <guid>https://dev.to/sphillips1337/your-small-business-agent-does-not-need-every-tool-5fc6</guid>
      <description>&lt;p&gt;A small business usually does not need a smarter agent first. It needs an agent with fewer ways to get lost.&lt;/p&gt;

&lt;p&gt;That sounds backwards when the default pitch is “connect everything”: email, CRM, database, website, accounting, calendars, search, social, and a dozen specialist services. MCP makes those connections easier. A client can discover tools from servers instead of shipping a custom integration for each one.&lt;/p&gt;

&lt;p&gt;The temptation is to expose the whole toolbox and let the model choose.&lt;/p&gt;

&lt;p&gt;For a five-person business, that is the wrong default. The first useful agent should see a small, task-specific set of tools. It should prepare work before it performs side effects. When the tool list changes, that change should be visible and reviewable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with a giant toolbox
&lt;/h2&gt;

&lt;p&gt;Tool descriptions sit in the agent’s working context. A large catalogue costs tokens. The bigger cost is ambiguity. If an agent can search five systems, update three records, send messages, and edit a workflow, every request becomes a routing problem before it becomes a business problem.&lt;/p&gt;

&lt;p&gt;Familiar failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent picks a tool that is technically valid but operationally wrong.&lt;/li&gt;
&lt;li&gt;A read-only request shares context with write-capable tools.&lt;/li&gt;
&lt;li&gt;Similarly named tools point at the wrong account or environment.&lt;/li&gt;
&lt;li&gt;A server update adds a tool and quietly changes the agent’s choices.&lt;/li&gt;
&lt;li&gt;Nobody can reconstruct why a particular action was selected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MCP tools specification supports discovery through &lt;code&gt;tools/list&lt;/code&gt; and lets a server notify clients when the tool list changes. That is useful for growth. It also means the action surface is not static. Treat tool exposure as configuration, not a one-time onboarding step.&lt;/p&gt;

&lt;p&gt;The question is not “Can this agent access the system?” It is “Which two or three capabilities does this job need right now?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Route by job, not by vendor
&lt;/h2&gt;

&lt;p&gt;Imagine a local company that receives quote requests through a WordPress form. The owner wants an assistant to sort them each morning and prepare replies.&lt;/p&gt;

&lt;p&gt;A broad setup might expose WordPress, email, CRM, calendar, files, web search, and accounting. Plenty of options for the model. Plenty of permissions for the owner to worry about.&lt;/p&gt;

&lt;p&gt;A routed setup gives the quote-triage task only:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;read_new_quote_requests&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lookup_customer_record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prepare_quote_reply&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;queue_reply_for_approval&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The underlying services can stay the same. A routing layer presents a narrow contract for this task. Email-send is not available while the agent is classifying requests. Accounting tools are not in context at all.&lt;/p&gt;

&lt;p&gt;This is not a claim that models stop making mistakes. It makes the mistakes smaller. A wrong choice from four tools is easier to inspect than a wrong choice from forty.&lt;/p&gt;

&lt;p&gt;A useful router can select by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user’s task (“triage today’s enquiries”)&lt;/li&gt;
&lt;li&gt;data sensitivity&lt;/li&gt;
&lt;li&gt;whether the next step is read-only or changes state&lt;/li&gt;
&lt;li&gt;business hours or approval policy&lt;/li&gt;
&lt;li&gt;how complete the request is&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The router should return a tool set plus a short reason. That reason becomes part of the run record: &lt;code&gt;quote_triage -&amp;gt; read_quotes, lookup_customer, prepare_reply&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep read and write paths separate
&lt;/h2&gt;

&lt;p&gt;The cleanest first boundary is between gathering information and changing something.&lt;/p&gt;

&lt;p&gt;A read path can collect a form submission, retrieve the matching customer record, and draft a response. A write path can create a CRM task or send an email, but only after a person approves the proposed action or a clearly defined policy allows it.&lt;/p&gt;

&lt;p&gt;That separation matters more than a clever system prompt. A prompt can say “do not send email without approval.” A permission boundary can make sending unavailable until approval exists.&lt;/p&gt;

&lt;p&gt;In an MCP system that can mean separate servers, separate credentials, or a proxy that filters tools based on workflow state. Implementation varies. The operating rule does not: do not give a classification step the ability to perform the final action.&lt;/p&gt;

&lt;p&gt;n8n’s human-in-the-loop tool patterns are a practical model here. The workflow can pause at a sensitive tool call, ask for approval in Slack/Telegram/chat, then resume with the approved action. That bridges “assistant only drafts” and “assistant runs unattended.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Make tool changes boring and visible
&lt;/h2&gt;

&lt;p&gt;Dynamic discovery is useful when a business adds a service. It becomes dangerous when the tool list changes and nobody notices.&lt;/p&gt;

&lt;p&gt;Put the exposed tool set in a versioned config file, even if the underlying MCP servers are dynamic. For each workflow, record something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;morning-quote-triage&lt;/span&gt;
&lt;span class="na"&gt;allowed_tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;read_new_quote_requests&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;lookup_customer_record&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;prepare_quote_reply&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;queue_reply_for_approval&lt;/span&gt;
&lt;span class="na"&gt;blocked_tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;send_email&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edit_wordpress&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;create_invoice&lt;/span&gt;
&lt;span class="na"&gt;policy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;approval-required-for-external-messages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a tool is added, removed, or renamed, write a small change record. Test the workflow with a fixture, then ship the new set. Ordinary release hygiene. An agent’s tool catalogue is part of its application surface.&lt;/p&gt;

&lt;p&gt;The same applies with a local model. Ollama supports tool calling, but a local model does not remove the need for boundaries. It can make the data path more private and cost more predictable. It cannot decide whether &lt;code&gt;send_customer_email&lt;/code&gt; is appropriate just because the schema is valid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store a receipt for every route
&lt;/h2&gt;

&lt;p&gt;A useful run record does not need private customer content. Store the operational facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;workflow name and version&lt;/li&gt;
&lt;li&gt;request category&lt;/li&gt;
&lt;li&gt;tools made available&lt;/li&gt;
&lt;li&gt;selected tool and redacted arguments&lt;/li&gt;
&lt;li&gt;approval state&lt;/li&gt;
&lt;li&gt;duration and result status&lt;/li&gt;
&lt;li&gt;final human or system outcome&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That record answers the questions an owner eventually asks: Why that action? Which tools were available? Did a person approve it? Was the failure in the model, the router, or the downstream service?&lt;/p&gt;

&lt;p&gt;Do not log full email threads or customer records by default. Prefer identifiers, hashes, and small redacted summaries. Debug the workflow without creating a second copy of the business’s sensitive data.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small pilot you can finish in a week
&lt;/h2&gt;

&lt;p&gt;Start with one repetitive workflow that has a clear finish line. Quote triage, appointment requests, or a daily content queue beat “run the business.”&lt;/p&gt;

&lt;p&gt;Day one: write the desired outcome and the actions that stay human-approved.&lt;br&gt;&lt;br&gt;
Day two: expose only read and draft tools; run a few representative examples.&lt;br&gt;&lt;br&gt;
Day three: add the approval queue and a receipt record.&lt;br&gt;&lt;br&gt;
Then measure the boring things: time saved, wrong classifications, approval turnaround, failed tool calls.&lt;/p&gt;

&lt;p&gt;If the workflow is reliable, add one capability at a time. If it is not, shrink the tool set before you change the model.&lt;/p&gt;

&lt;p&gt;That last step is easy to skip. People often respond to bad choices with another instruction, another retrieval step, or a larger model. Sometimes the fix is removing seven tools the task never needed.&lt;/p&gt;

&lt;p&gt;MCP makes connected tools easier to build. Good routing makes them easier to operate. For a small business, the practical win is not an agent that can do everything. It is an assistant with just enough access to finish one job, that asks before it crosses a boundary, and leaves evidence when something goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/server/tools" rel="noopener noreferrer"&gt;MCP tools specification&lt;/a&gt; — discovery, invocation, &lt;code&gt;notifications/tools/list_changed&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices" rel="noopener noreferrer"&gt;MCP security best practices&lt;/a&gt; — least privilege, consent, tool access&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ollama.com/blog/tool-support" rel="noopener noreferrer"&gt;Ollama tool support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.n8n.io/advanced-ai/human-in-the-loop-tools/" rel="noopener noreferrer"&gt;n8n human-in-the-loop tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Distinct from HappyMonkey drafts on approval gates, receipts/observability, and draft-queue-first workflows: this piece is about routing and versioning the available tool surface before invocation&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>automation</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>The Safest First MCP Workflow Is a Draft Queue, Not an Autonomous Agent</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sun, 16 Aug 2026 16:40:58 +0000</pubDate>
      <link>https://dev.to/sphillips1337/the-safest-first-mcp-workflow-is-a-draft-queue-not-an-autonomous-agent-1jbf</link>
      <guid>https://dev.to/sphillips1337/the-safest-first-mcp-workflow-is-a-draft-queue-not-an-autonomous-agent-1jbf</guid>
      <description>&lt;p&gt;Most small businesses do not need an autonomous agent.&lt;/p&gt;

&lt;p&gt;They need the next customer reply drafted, the right product notes found, and a human who can still sleep knowing nothing weird went out overnight.&lt;/p&gt;

&lt;p&gt;That is how I would start the first useful MCP project.&lt;/p&gt;

&lt;p&gt;The tempting demo wires the agent to CRM, inbox, calendar, WordPress, analytics, and payments. It looks powerful. It also creates a large surface for wrong tool choices, accidental writes, duplicate sends, and questions nobody can answer later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tool did the model call?&lt;/li&gt;
&lt;li&gt;What information did it use?&lt;/li&gt;
&lt;li&gt;What would it have changed if nobody stepped in?&lt;/li&gt;
&lt;li&gt;Can we replay the decision without dumping the whole customer record into a log?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a small team, the safer start is a &lt;strong&gt;draft queue&lt;/strong&gt;. The agent researches and prepares a proposed action. A person approves it. Only then does a narrow workflow perform the side effect.&lt;/p&gt;

&lt;p&gt;Less spectacular than an autonomous agent. More likely to survive a real Monday.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP makes the boundary easier to define
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol gives apps a standard way to expose tools to language models. A tool has a name, description, and input schema. It can query a database, call an API, or run a computation.&lt;/p&gt;

&lt;p&gt;That standardisation helps. It does not decide which tools an agent should see, or which calls may change state. Those are application decisions.&lt;/p&gt;

&lt;p&gt;Treat every MCP tool as one of two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read or prepare&lt;/strong&gt; — search the knowledge base, look up an order, summarise a policy, draft a reply, assemble a WordPress post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Side effect&lt;/strong&gt; — send email, publish content, issue a refund, update a CRM record, delete something.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Category one is a good pilot surface. Category two stays behind an explicit approval boundary until the workflow has earned trust.&lt;/p&gt;

&lt;p&gt;The protocol can make integrations interoperable. It cannot make a sloppy permission model safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete first workflow: enquiries to approved replies
&lt;/h2&gt;

&lt;p&gt;Imagine a five-person agency receiving enquiries from a website form.&lt;/p&gt;

&lt;p&gt;The first agent version needs only four tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;search_services&lt;/code&gt; — read the approved service catalogue&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;find_faq&lt;/code&gt; — retrieve answers from maintained FAQs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lookup_enquiry&lt;/code&gt; — read one enquiry by internal ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_reply_draft&lt;/code&gt; — write a proposed reply into an approval queue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice what is missing: no send-email tool, no unrestricted filesystem tool, no “read every customer,” no inventing prices from a private spreadsheet.&lt;/p&gt;

&lt;p&gt;A worker can follow a boring, inspectable sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive an enquiry ID, not a pasted customer dump.&lt;/li&gt;
&lt;li&gt;Read the enquiry and the relevant approved service notes.&lt;/li&gt;
&lt;li&gt;Draft a reply with links to the source notes it used.&lt;/li&gt;
&lt;li&gt;Store the draft with status &lt;code&gt;needs_review&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Notify a human reviewer.&lt;/li&gt;
&lt;li&gt;After approval, a separate deterministic workflow sends the exact approved text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The model earns its keep by removing repetitive search and first-draft work. Approval is a state transition, not a polite line in the system prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use shadow mode before the agent writes
&lt;/h2&gt;

&lt;p&gt;A useful intermediate stage is &lt;strong&gt;shadow mode&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The agent runs on real or representative requests but cannot create even a draft in production. It writes proposed tool calls and outputs to a review log. A human compares that with what they would have done.&lt;/p&gt;

&lt;p&gt;For two weeks, track simple measures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How often did it choose the right source?&lt;/li&gt;
&lt;li&gt;How often did the draft need a factual correction?&lt;/li&gt;
&lt;li&gt;Which requests were ambiguous?&lt;/li&gt;
&lt;li&gt;Did it ask for information it should not have needed?&lt;/li&gt;
&lt;li&gt;How many proposed actions would have been unsafe if executed automatically?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives evidence instead of vibes. It also surfaces missing business rules. Repeated edits often mean a documentation problem, not a model problem.&lt;/p&gt;

&lt;p&gt;Only after shadow results look acceptable should the workflow create &lt;code&gt;needs_review&lt;/code&gt; drafts. Automatic side effects come later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The approval queue is a product feature
&lt;/h2&gt;

&lt;p&gt;Do not bury approval in a chat transcript. Give it a small, durable record.&lt;/p&gt;

&lt;p&gt;A draft queue entry might look like:&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;"reply-2026-0713-0042"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"request_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;"enquiry-1842"&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;"needs_review"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"proposed_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"send_email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recipient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer@example.test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A human-readable draft goes here"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_refs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"services/websites"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"faq/migrations"&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_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"approved_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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-07-13T09:30:00Z"&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;Schemas will vary. The fields that matter are action, scope, source references, and state. Approval should mean “approve this exact proposed action,” not “the agent may now freestyle with email.”&lt;/p&gt;

&lt;p&gt;When a reviewer edits the draft, record that too. Edits are feedback and audit trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the side-effect tool deliberately dull
&lt;/h2&gt;

&lt;p&gt;The final send step should be a narrow integration with boring validation. It accepts a queue ID, loads the approved record, checks status is &lt;code&gt;approved&lt;/code&gt;, confirms recipient and body have not changed, and sends once.&lt;/p&gt;

&lt;p&gt;It should reject:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unapproved records&lt;/li&gt;
&lt;li&gt;expired approvals&lt;/li&gt;
&lt;li&gt;changed recipients&lt;/li&gt;
&lt;li&gt;duplicate queue IDs&lt;/li&gt;
&lt;li&gt;missing source or audit metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Idempotency matters. If a network timeout hits after the provider accepted the email, a blind retry can double-send. Store a provider message ID or another durable operation key and resolve the previous attempt before sending again.&lt;/p&gt;

&lt;p&gt;This is ordinary workflow engineering. That is the point. MCP should connect the agent to a workflow; it should not replace the workflow’s invariants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where local AI fits
&lt;/h2&gt;

&lt;p&gt;A local model (for example via Ollama) can be a good fit for drafting and classification when you want less data movement or lower recurring API cost. Ollama’s tool-calling support makes structured tools practical, and its MCP examples point the same way: reason over a controlled tool surface.&lt;/p&gt;

&lt;p&gt;“Local” is not the same as “private by default.” The moment a tool hits a cloud CRM, email provider, hosted observability service, or external search API, selected data leaves the machine. Logs can leak data too.&lt;/p&gt;

&lt;p&gt;The useful question is not “is the model local?” It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the minimum information this step needs, and which system is allowed to receive it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pass an enquiry ID rather than an export. Return the relevant FAQ paragraphs rather than the whole document store. Redact secrets before logging model input. Keep high-risk tools out of the worker’s catalogue entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 30-day pilot plan
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Week 1: define the boundary.&lt;/strong&gt; One repetitive workflow. List read tools, draft output, approval owner, and unacceptable actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 2: build shadow mode.&lt;/strong&gt; Capture proposed tool calls and drafts without writing to production. Build a small evaluation set from representative, sanitised requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 3: add the approval queue.&lt;/strong&gt; Let the agent create reviewable drafts. Add source references, statuses, expiry, and an audit record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 4: automate one narrow side effect.&lt;/strong&gt; Lowest-risk approved action only. Validate exact inputs, add idempotency, measure failures as carefully as successes.&lt;/p&gt;

&lt;p&gt;At the end, the question is not whether the agent looked clever. It is whether staff trust the queue enough to use it, whether corrections are falling, and whether every side effect can be explained afterwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring path is the scalable path
&lt;/h2&gt;

&lt;p&gt;MCP is interesting because it gives agents real capabilities. That means the first design decision should be about control, not tool count.&lt;/p&gt;

&lt;p&gt;A draft queue is a useful middle ground: the agent does tedious preparation; people keep authority over irreversible changes. Shadow mode creates evidence before risk. Narrow tools and durable state make failures diagnosable.&lt;/p&gt;

&lt;p&gt;If that workflow becomes reliable, add one capability at a time. If it does not, you learned something without handing an untrusted process the keys to the business.&lt;/p&gt;

&lt;p&gt;The best first MCP workflow is rarely an autonomous agent.&lt;/p&gt;

&lt;p&gt;It is a well-labelled queue of work a human can understand, approve, reject, and replay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCP specification: &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2025-11-25&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MCP security best practices: &lt;a href="https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MCP tools: &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/server/tools" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2025-11-25/server/tools&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ollama tool support: &lt;a href="https://ollama.com/blog/tool-support" rel="noopener noreferrer"&gt;https://ollama.com/blog/tool-support&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Related HappyMonkey pieces: local Ollama/MCP fit; n8n + MCP workflows; approval gates&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>automation</category>
      <category>smallbusiness</category>
    </item>
    <item>
      <title>The night four MCP servers started acting like one system</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sun, 19 Jul 2026 16:17:48 +0000</pubDate>
      <link>https://dev.to/sphillips1337/the-night-four-mcp-servers-started-acting-like-one-system-243c</link>
      <guid>https://dev.to/sphillips1337/the-night-four-mcp-servers-started-acting-like-one-system-243c</guid>
      <description>&lt;p&gt;Last weekend I watched an agent workflow do something I had been waiting to see outside a demo.&lt;/p&gt;

&lt;p&gt;Hermes needed to hand a detailed review to another coding agent, start a fairly heavy Codex job, avoid overloading the local server, and leave enough evidence for me to check what happened afterwards.&lt;/p&gt;

&lt;p&gt;It did not call one giant "run the swarm" function. It used four small MCP services in sequence.&lt;/p&gt;

&lt;p&gt;That was the interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  The run
&lt;/h2&gt;

&lt;p&gt;The project was an evidence-first book-writing system. Hermes had reviewed its claim and citation engine and found a list of engineering problems that needed a coding pass.&lt;/p&gt;

&lt;p&gt;The trace looked roughly 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;find the development agent
send the review to its durable mailbox
confirm that the message arrived
create a durable implementation task
request capacity for the Codex workload
start Codex after the lease is admitted
append working and completion events
verify the resulting code and tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resource request declared an estimated 2.2 GB of memory and CPU weight 45. Resource Sentinel admitted it under a time-limited lease. Hermes then launched Codex and recorded the process against the same durable task.&lt;/p&gt;

&lt;p&gt;The task history later contained submitted, working and completed events, plus artifact references and verification notes. One completion event recorded 18 passing tests, clean lint modes, compile checks and an independent review.&lt;/p&gt;

&lt;p&gt;The workflow was imperfect. More edge cases appeared later and reopened the work. That is a feature, not an embarrassment: durable state made it possible to preserve the real history instead of flattening everything into a cheerful "done" message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four MCP servers, four jobs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Agent Communication MCP
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/HappyMonkeyAI/AgentCommunicationMCP" rel="noopener noreferrer"&gt;Agent Communication MCP&lt;/a&gt; owns agent identities, cards, durable messages, task records, lifecycle events and artifact references.&lt;/p&gt;

&lt;p&gt;Hermes used it to find the development agent, deliver the review, verify the mailbox, create the implementation task and record progress.&lt;/p&gt;

&lt;p&gt;The review therefore survived beyond one Slack message or model context window. Another agent could retrieve the same instructions later.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Resource Sentinel MCP
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/HappyMonkeyAI/Resource-Sentinel-MCP" rel="noopener noreferrer"&gt;Resource Sentinel MCP&lt;/a&gt; handles local telemetry and admission control.&lt;/p&gt;

&lt;p&gt;A workload supplies an estimated memory requirement, CPU priority and lease duration. The server admits it or queues it according to deterministic host policy. Expiring leases prevent abandoned jobs from holding capacity forever.&lt;/p&gt;

&lt;p&gt;Resource Sentinel does not run arbitrary shell commands. It decides whether work may start. Hermes and the coding CLI still own execution.&lt;/p&gt;

&lt;p&gt;That boundary matters. A resource monitor should not quietly become a remote command runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Agent Coordination MCP
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/HappyMonkeyAI/agent-coordination-mcp" rel="noopener noreferrer"&gt;Agent Coordination MCP&lt;/a&gt; is a narrow control plane for discovering installed CLI agents, inspecting file-based project boards and recording assignments.&lt;/p&gt;

&lt;p&gt;The project files remain the source of truth. Codex and other CLIs keep their own sandbox and approval behaviour. The MCP layer records intent and ownership rather than pretending every coding agent has an identical lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Launcher Project Registry
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/HappyMonkeyAI/launcher-project-registry" rel="noopener noreferrer"&gt;Launcher Project Registry&lt;/a&gt; maps project slugs to local paths, ports, URLs, technology stacks, MCP commands and project context.&lt;/p&gt;

&lt;p&gt;Its role was smaller in this run, but still useful. It also exposed a real gap: the book project did not yet have a registry slug, so the task fell back to an absolute local path.&lt;/p&gt;

&lt;p&gt;That is exactly the kind of weakness an operational trace should reveal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why separate servers worked better
&lt;/h2&gt;

&lt;p&gt;The stack worked because no server tried to own the whole workflow.&lt;/p&gt;

&lt;p&gt;Each one returned structured state that Hermes could use in the next decision:&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="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;communication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dev-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;communication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;findings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request_execution_slot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;workload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;codex-review-fixes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;estimated_memory_mb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_weight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;45&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="n"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admitted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;communication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;launch_codex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;communication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;working&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That snippet is illustrative rather than a copy of the actual implementation, but the contract shape is the point.&lt;/p&gt;

&lt;p&gt;The orchestrator did not need hidden knowledge of every service. It read tool descriptions, called one bounded operation, inspected the result and chose the next tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  This was not "agent swarm intelligence"
&lt;/h2&gt;

&lt;p&gt;It is tempting to describe any multi-agent trace as spontaneous collaboration. I do not think that helps.&lt;/p&gt;

&lt;p&gt;MCP did not make the coding output correct. The agents did not vote their way to truth. The reliable parts were ordinary engineering controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;durable task and message IDs;&lt;/li&gt;
&lt;li&gt;explicit state transitions;&lt;/li&gt;
&lt;li&gt;expiring resource leases;&lt;/li&gt;
&lt;li&gt;project-owned artifacts;&lt;/li&gt;
&lt;li&gt;deterministic tests and lint gates;&lt;/li&gt;
&lt;li&gt;independent review that could reopen the work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The coding agent still needed supervision. A later review found flaws in backup retention and API validation in a related repository. Those findings were fixed, tested and pushed instead of being waved away because an earlier agent had declared success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design rules I would reuse
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keep each MCP server narrow
&lt;/h3&gt;

&lt;p&gt;A mailbox server should not edit repositories. A resource server should not execute caller-supplied commands. A registry should resolve project context without becoming a secrets store.&lt;/p&gt;

&lt;p&gt;Smaller contracts make failures easier to locate and permissions easier to reason about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make state durable before adding more agents
&lt;/h3&gt;

&lt;p&gt;Adding a second model is easy. Preserving task ownership, evidence, artifacts and failure history is harder and more useful.&lt;/p&gt;

&lt;p&gt;If a handoff only exists in chat history, it is not much of a handoff.&lt;/p&gt;

&lt;h3&gt;
  
  
  Treat host capacity as policy
&lt;/h3&gt;

&lt;p&gt;Local agents share memory, CPU, databases and inference services. Starting every available CLI at once can make all of them slower or take down the services they need.&lt;/p&gt;

&lt;p&gt;Admission control belongs in the orchestration path, before process launch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verification must be able to reverse "done"
&lt;/h3&gt;

&lt;p&gt;A completion event is a claim. Tests, source checks and independent review decide whether that claim holds up.&lt;/p&gt;

&lt;p&gt;The system should preserve a clean way to move from completed back to working when new evidence appears.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;The immediate work is practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;register projects that still fall back to absolute paths;&lt;/li&gt;
&lt;li&gt;make lease renewal and release visible beside task history;&lt;/li&gt;
&lt;li&gt;improve recovery for interrupted processes and stale tasks;&lt;/li&gt;
&lt;li&gt;put agent, task and resource state in one control-centre view;&lt;/li&gt;
&lt;li&gt;keep tightening the policy around what an agent may call complete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This stack is still early, and the coordination server is explicitly experimental. But it has now handled useful work on a real project with a trace that survived the agents involved.&lt;/p&gt;

&lt;p&gt;That is a better milestone than another polished swarm demo.&lt;/p&gt;




&lt;p&gt;The original case study, including sanitized screenshots, is on &lt;a href="https://happymonkey.ai/hermes-mcp-servers-working-as-a-system/" rel="noopener noreferrer"&gt;HappyMonkey.ai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The four projects are open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/HappyMonkeyAI/Resource-Sentinel-MCP" rel="noopener noreferrer"&gt;Resource Sentinel MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HappyMonkeyAI/AgentCommunicationMCP" rel="noopener noreferrer"&gt;Agent Communication MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HappyMonkeyAI/agent-coordination-mcp" rel="noopener noreferrer"&gt;Agent Coordination MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/HappyMonkeyAI/launcher-project-registry" rel="noopener noreferrer"&gt;Launcher Project Registry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>aiagents</category>
      <category>opensource</category>
    </item>
    <item>
      <title>GOSafe: location-based disaster risk intelligence for real places and dates</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sat, 18 Jul 2026 12:13:40 +0000</pubDate>
      <link>https://dev.to/sphillips1337/gosafe-location-based-disaster-risk-intelligence-for-real-places-and-dates-4dib</link>
      <guid>https://dev.to/sphillips1337/gosafe-location-based-disaster-risk-intelligence-for-real-places-and-dates-4dib</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1504608524841-42fe6f032b4b%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1504608524841-42fe6f032b4b%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" width="1600" height="2000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GOSafe&lt;/strong&gt; (live at &lt;a href="http://gosafe.happymonkey.ai" rel="noopener noreferrer"&gt;gosafe.happymonkey.ai&lt;/a&gt;) is our prototype for location-based disaster risk intelligence. It combines current events, official forecasts, and carefully bounded AI interpretation to answer a practical question: &lt;em&gt;what should I watch around this place during these dates?&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Product boundary:&lt;/strong&gt; the current UI is a prototype with illustrative signals. It is &lt;em&gt;not&lt;/em&gt; a live warning service and must not replace official emergency guidance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The wedge
&lt;/h2&gt;

&lt;p&gt;People plan trips, events, and moves with weather tabs, news tabs, and half-remembered map apps. GOSafe’s first slice is a location/date risk checker covering severe weather, flooding, wildfire/smoke awareness, and seismic/tsunami context — framed as situational awareness, not prediction theatre.&lt;/p&gt;

&lt;h2&gt;
  
  
  What “bounded AI” means here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prefer official forecasts and structured feeds where they exist&lt;/li&gt;
&lt;li&gt;Use models to interpret and summarise evidence, not invent certainty&lt;/li&gt;
&lt;li&gt;Refuse unreliable claims such as precise earthquake prediction&lt;/li&gt;
&lt;li&gt;Keep the product honest about prototype vs operational warning systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it is built
&lt;/h2&gt;

&lt;p&gt;GOSafe sits in the disaster-intelligence stack as a modern Next.js app with a clear documentation spine (CONTEXT, ADRs, plans, research). Infrastructure pieces include nginx vhosts for the public hostname and process management for the live prototype.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we are building in public
&lt;/h2&gt;

&lt;p&gt;Disaster-adjacent products attract hype and liability. Publishing the prototype boundary early is part of the product: show the architecture, show the limits, and iterate with source-backed signals rather than fear marketing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live prototype:&lt;/strong&gt; &lt;a href="http://gosafe.happymonkey.ai" rel="noopener noreferrer"&gt;gosafe.happymonkey.ai&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Theme:&lt;/strong&gt; evidence-first risk awareness for travel and everyday planning.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://happymonkey.ai/gosafe-location-based-disaster-risk-intelligence-for-real-places-and-dates/" rel="noopener noreferrer"&gt;HappyMonkey.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>safety</category>
    </item>
    <item>
      <title>OpenUKPublicDataMCP: one MCP endpoint for useful UK public data</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sat, 18 Jul 2026 12:13:03 +0000</pubDate>
      <link>https://dev.to/sphillips1337/openukpublicdatamcp-one-mcp-endpoint-for-useful-uk-public-data-5ai4</link>
      <guid>https://dev.to/sphillips1337/openukpublicdatamcp-one-mcp-endpoint-for-useful-uk-public-data-5ai4</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1524661135-423995f22d0b%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1524661135-423995f22d0b%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" width="1600" height="1063"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agents are only as good as the facts they can reach. &lt;strong&gt;OpenUKPublicDataMCP&lt;/strong&gt; is a no-key-first Model Context Protocol server that gives Claude, Hermes, Cursor, and other MCP clients one reliable place to ask common UK public-data questions — with sources attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why public data needs an MCP layer
&lt;/h2&gt;

&lt;p&gt;UK public APIs are powerful and fragmented: postcodes, GOV.UK search, flood monitoring, ONS statistics, carbon intensity, planning applications, Parliament lookups, and more. Each has its own quirks, pagination, and auth story. Agents should not re-learn that glue in every chat session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design principles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No-key-first&lt;/strong&gt; — core tools work without signup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source-cited&lt;/strong&gt; — every tool returns upstream source metadata and retrieval time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official-first&lt;/strong&gt; — prefer official UK public-sector APIs; label community sources explicitly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thin adapters&lt;/strong&gt; — normalise useful fields, keep upstream payloads available&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional enrichments&lt;/strong&gt; — Companies House, OS Places, Met Office, TfL only when keys exist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-only by default&lt;/strong&gt; — no public-sector write operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What shipped in the MVP
&lt;/h2&gt;

&lt;p&gt;23+ MCP tools, a FastAPI explorer API, and a React map UI under &lt;code&gt;web/&lt;/code&gt;. Example capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postcode lookup, bank holidays, National Grid carbon intensity&lt;/li&gt;
&lt;li&gt;GOV.UK search and data.gov.uk dataset search&lt;/li&gt;
&lt;li&gt;Environment Agency flood warnings and areas&lt;/li&gt;
&lt;li&gt;ONS datasets/observations and CPIH headline inflation&lt;/li&gt;
&lt;li&gt;Planning applications, police street crime near a point&lt;/li&gt;
&lt;li&gt;MP / constituency lookups via Parliament APIs&lt;/li&gt;
&lt;li&gt;Optional: Met Office forecast, Companies House profile, OS Places, TfL line status&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How we use it
&lt;/h2&gt;

&lt;p&gt;Register the stdio MCP server with Hermes (or any MCP client). Agents can plan research, pull a cited answer, and save notes without inventing numbers. A public explorer host also exists for human browsing when the stack is deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sister project
&lt;/h2&gt;

&lt;p&gt;The same pattern is expanding to the US via &lt;a href="https://github.com/HappyMonkeyAI/OpenUSPublicDataMCP" rel="noopener noreferrer"&gt;OpenUSPublicDataMCP&lt;/a&gt; — federal-first, no-key-first access to high-value public sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/HappyMonkeyAI/OpenUKPublicDataMCP" rel="noopener noreferrer"&gt;github.com/HappyMonkeyAI/OpenUKPublicDataMCP&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://happymonkey.ai/openukpublicdatamcp-one-mcp-endpoint-for-useful-uk-public-data/" rel="noopener noreferrer"&gt;HappyMonkey.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>opensource</category>
      <category>api</category>
      <category>python</category>
    </item>
    <item>
      <title>miso-tts-docker: local Miso TTS 8B on Windows, Docker Desktop, and RTX 50-series</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sat, 18 Jul 2026 12:12:21 +0000</pubDate>
      <link>https://dev.to/sphillips1337/miso-tts-docker-local-miso-tts-8b-on-windows-docker-desktop-and-rtx-50-series-41j3</link>
      <guid>https://dev.to/sphillips1337/miso-tts-docker-local-miso-tts-8b-on-windows-docker-desktop-and-rtx-50-series-41j3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1478737270239-2f02b77fc618%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1478737270239-2f02b77fc618%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" width="1600" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;High-quality local speech is finally useful for agents and demos — if you can get the GPU stack to boot. &lt;strong&gt;miso-tts-docker&lt;/strong&gt; is our unofficial Docker Compose pack for running &lt;a href="https://github.com/MisoLabsAI/MisoTTS" rel="noopener noreferrer"&gt;Miso TTS 8B&lt;/a&gt; on NVIDIA GPUs, with a special focus on Windows, Docker Desktop, and RTX 50-series (Blackwell) cards.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not affiliated with Miso Labs&lt;/em&gt; — we wrap upstream inference with GPU-ready containers, Hugging Face caching, and Windows-friendly launchers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we packaged it
&lt;/h2&gt;

&lt;p&gt;Raw research repos rarely survive first contact with Docker Desktop on Windows or brand-new GPU arch flags. Builders hit tokenizer gatekeeping, torchcodec gaps, cache churn, and “works on my Linux box” launch scripts. We wanted a clone-and-run path that still respects the upstream model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker Compose with NVIDIA GPU passthrough&lt;/li&gt;
&lt;li&gt;PyTorch 2.11 + CUDA 12.8 oriented at RTX 5090 / Blackwell (&lt;code&gt;sm_120&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Full bfloat16 Miso path by default (~24&amp;nbsp;GB VRAM recommended)&lt;/li&gt;
&lt;li&gt;Persistent Hugging Face cache volumes&lt;/li&gt;
&lt;li&gt;Preflight checks for gated Llama 3.2 tokenizer access&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;soundfile&lt;/code&gt; audio I/O patch so PyTorch 2.11 does not depend on torchcodec&lt;/li&gt;
&lt;li&gt;Windows &lt;code&gt;.cmd&lt;/code&gt; launchers (no PowerShell execution-policy drama)&lt;/li&gt;
&lt;li&gt;Web voice demo: Whisper STT, optional LLM replies, dual TTS backends&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast mode&lt;/strong&gt; via Pocket TTS on CPU for low-latency replies&lt;/li&gt;
&lt;li&gt;HTTPS via Caddy for mic access from phones/tablets on the LAN&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Two speeds of voice
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Quality mode&lt;/strong&gt; runs Miso 8B on GPU for the high-end voice. &lt;strong&gt;Fast mode&lt;/strong&gt; runs Pocket TTS on CPU so demos stay snappy without monopolising VRAM. You can also run both and A/B engines in the web UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;≥24&amp;nbsp;GB VRAM recommended for quality mode&lt;/li&gt;
&lt;li&gt;~40&amp;nbsp;GB disk for first-run downloads&lt;/li&gt;
&lt;li&gt;Hugging Face token + accepted Llama 3.2-1B license for the gated tokenizer path&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why it fits HappyMonkey
&lt;/h2&gt;

&lt;p&gt;Voice is becoming a first-class agent interface. Packaging local TTS well is the difference between a LinkedIn demo and something staff can actually use on a desk GPU without a research internship.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/HappyMonkeyAI/miso-tts-docker" rel="noopener noreferrer"&gt;github.com/HappyMonkeyAI/miso-tts-docker&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://happymonkey.ai/miso-tts-docker-local-miso-tts-8b-on-windows-docker-desktop-and-rtx-50-series/" rel="noopener noreferrer"&gt;HappyMonkey.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>docker</category>
      <category>tts</category>
      <category>gpu</category>
    </item>
    <item>
      <title>Resource Sentinel MCP: stop local AI agents from melting the host</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sat, 18 Jul 2026 12:12:17 +0000</pubDate>
      <link>https://dev.to/sphillips1337/resource-sentinel-mcp-stop-local-ai-agents-from-melting-the-host-2hhb</link>
      <guid>https://dev.to/sphillips1337/resource-sentinel-mcp-stop-local-ai-agents-from-melting-the-host-2hhb</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1558494949-ef010cbdcc31%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1558494949-ef010cbdcc31%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you run many coding agents, tests, and models on one machine, the failure mode is boring and expensive: OOM kills, thrashing disks, and mysterious hangs. &lt;strong&gt;Resource Sentinel MCP&lt;/strong&gt; is our answer — telemetry plus lease-based admission control that agents can request before heavy work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent host problem
&lt;/h2&gt;

&lt;p&gt;LLM agents are great at starting work and terrible at knowing when the box is already full. Parallel pytest runs, Docker builds, and subagents stacked on a shared laptop or lab server will happily oversubscribe memory and CPU until everything is slow.&lt;/p&gt;

&lt;p&gt;We wanted a control plane that is &lt;strong&gt;deterministic&lt;/strong&gt;, not another model guessing mood from vibes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Resource Sentinel does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Observes the Linux host (psutil-based telemetry)&lt;/li&gt;
&lt;li&gt;Lets workloads request an execution slot with estimated memory and CPU weight&lt;/li&gt;
&lt;li&gt;Issues &lt;strong&gt;expiring leases&lt;/strong&gt; (and queues when the host is full)&lt;/li&gt;
&lt;li&gt;Persists tickets/leases in SQLite WAL&lt;/li&gt;
&lt;li&gt;Exposes FastMCP tools for agents and a read-only HTTP projection for dashboards&lt;/li&gt;
&lt;li&gt;Feeds Glitch-compatible telemetry so the “cyber pet” reacts to real host state&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How agents use it
&lt;/h2&gt;

&lt;p&gt;Typical pattern for a heavy local job:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call &lt;code&gt;request_execution_slot&lt;/code&gt; with a workload id, estimated MB, and CPU weight&lt;/li&gt;
&lt;li&gt;If granted, heartbeating/extend the lease while work runs&lt;/li&gt;
&lt;li&gt;Always release on completion so others can proceed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hermes registers it as MCP server name &lt;code&gt;resource_sentinel&lt;/code&gt; (same name under DynamicMCPProxy).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;MCP:  http://127.0.0.1:8800/mcp
Health: http://127.0.0.1:8800/healthz
Glitch: http://127.0.0.1:8800/api/resource-state
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Boundaries that keep it honest
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Policy is pure and fail-closed on invalid requests&lt;/li&gt;
&lt;li&gt;It does &lt;em&gt;not&lt;/em&gt; execute caller-supplied shell commands&lt;/li&gt;
&lt;li&gt;MVP does not enforce cgroups — admission is cooperative via leases&lt;/li&gt;
&lt;li&gt;Dashboards consume factual telemetry rather than caller-selected “moods”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this is a product story, not just ops glue
&lt;/h2&gt;

&lt;p&gt;Local multi-agent stacks only become practical when the host has a traffic light. Resource Sentinel is that traffic light — small, testable, and agent-native via MCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/HappyMonkeyAI/Resource-Sentinel-MCP" rel="noopener noreferrer"&gt;github.com/HappyMonkeyAI/Resource-Sentinel-MCP&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://happymonkey.ai/resource-sentinel-mcp-stop-local-ai-agents-from-melting-the-host/" rel="noopener noreferrer"&gt;HappyMonkey.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>devops</category>
      <category>python</category>
    </item>
    <item>
      <title>PromptOS: an AI-first Linux installer that never builds the same machine twice</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sat, 18 Jul 2026 12:11:29 +0000</pubDate>
      <link>https://dev.to/sphillips1337/promptos-an-ai-first-linux-installer-that-never-builds-the-same-machine-twice-f4f</link>
      <guid>https://dev.to/sphillips1337/promptos-an-ai-first-linux-installer-that-never-builds-the-same-machine-twice-f4f</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1518770660439-4636190af475%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1518770660439-4636190af475%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80" width="1600" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most installers ship a fixed menu of packages. &lt;strong&gt;PromptOS&lt;/strong&gt; is different: a minimal live bootstrap that asks high-level questions, talks to your LLM provider, and generates a hardware-aware installation blueprint on the fly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with static install media
&lt;/h2&gt;

&lt;p&gt;Traditional distro ISOs are frozen in time. Drivers lag, desktop profiles age, and “recommended packages” become a one-size-fits-none compromise. Maintaining a full custom distro is worse: you inherit package churn, security patches, and endless edge cases.&lt;/p&gt;

&lt;p&gt;PromptOS keeps the maintenance burden where it belongs — upstream package managers and the models that already track modern stacks — while the installer itself stays small and focused.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TUI wizard&lt;/strong&gt; in Go + Bubble Tea for a static binary on a tiny live environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pluggable LLM client&lt;/strong&gt; for OpenAI, Anthropic, Gemini, or local Ollama&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured JSON blueprints&lt;/strong&gt; validated before execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Executor path&lt;/strong&gt; for partitioning, chroot bootstrap (archinstall / debootstrap / pacstrap), and config drops&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closed-action install triage&lt;/strong&gt;, bounded auto-heal, boot-time rescue, and explicit disk-wipe confirmation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI that matters&lt;/strong&gt;: GitHub Actions builds the real image and boots it in QEMU through GRUB into OpenRC&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the flow feels
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Boot the minimal live image&lt;/li&gt;
&lt;li&gt;Pick a provider and enter your key&lt;/li&gt;
&lt;li&gt;Answer preference questions in a conversational wizard&lt;/li&gt;
&lt;li&gt;The model scans hardware context and drafts a blueprint&lt;/li&gt;
&lt;li&gt;The executor applies the plan; if boot fails, AI triage has a rescue path&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;p&gt;PromptOS is not a full distro, custom kernel, or package repository. It is an intelligent orchestrator. Optional “AI desktop profile” ideas stay later-phase design work; the present focus is a trustworthy installer spine and guest readiness verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters for builders
&lt;/h2&gt;

&lt;p&gt;If you care about local-first AI desktops, self-healing recovery, and reproducible-but-personal machines, the interesting product is not another ISO flavour. It is a bootstrap that can reason about &lt;em&gt;your&lt;/em&gt; hardware and intent without trapping you in forever-forked packages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/HappyMonkeyAI/prompt-os" rel="noopener noreferrer"&gt;github.com/HappyMonkeyAI/prompt-os&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want more build-in-public notes?&lt;/strong&gt; Follow the series on &lt;a href="https://happymonkey.ai" rel="noopener noreferrer"&gt;happymonkey.ai&lt;/a&gt; and the org at &lt;a href="https://github.com/HappyMonkeyAI" rel="noopener noreferrer"&gt;HappyMonkeyAI&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://happymonkey.ai/promptos-an-ai-first-linux-installer-that-never-builds-the-same-machine-twice/" rel="noopener noreferrer"&gt;HappyMonkey.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>linux</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>You've Never Sent a Single Word to an AI. Here's What Actually Happens.</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Wed, 08 Jul 2026 11:39:39 +0000</pubDate>
      <link>https://dev.to/sphillips1337/youve-never-sent-a-single-word-to-an-ai-heres-what-actually-happens-1o8j</link>
      <guid>https://dev.to/sphillips1337/youve-never-sent-a-single-word-to-an-ai-heres-what-actually-happens-1o8j</guid>
      <description>&lt;p&gt;You've never sent a single word to an AI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmxzh1mqus1se5qwtxlim.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmxzh1mqus1se5qwtxlim.jpg" alt=" " width="680" height="272"&gt;&lt;/a&gt;&lt;br&gt;
Every time you hit send on ChatGPT, Claude, or Gemini, your words get shredded before the model ever sees them. The process is called &lt;strong&gt;tokenization&lt;/strong&gt;. Once you understand it, you'll never think about AI the same way again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a token?
&lt;/h2&gt;

&lt;p&gt;A token is the actual unit your AI reads — not a word, not a sentence. Sometimes it's a whole word. Sometimes just a fragment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"ChatGPT" is 2 tokens.&lt;/li&gt;
&lt;li&gt;"Unbelievable" is 3 ("un", "believ", "able").&lt;/li&gt;
&lt;li&gt;A single emoji can cost 3 tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rough rule:&lt;/strong&gt; 1 token ≈ 4 characters ≈ 0.75 words.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fei85wxq9g6ta65ojo3f1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fei85wxq9g6ta65ojo3f1.png" alt=" " width="576" height="169"&gt;&lt;/a&gt;&lt;br&gt;
This is what your message actually looks like to an AI. Not words. Colored chunks of subwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does this matter?
&lt;/h2&gt;

&lt;p&gt;The model never sees language. It sees &lt;strong&gt;numbers&lt;/strong&gt;. Every token gets converted into a vector — a list of hundreds of values that places it in mathematical space.&lt;/p&gt;

&lt;p&gt;"King" and "Queen" sit close together in that space. "King" and "pizza" are far apart. The model understands meaning the same way a map understands geography — through distances, not definitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fitczdjgosbdhvc41255x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fitczdjgosbdhvc41255x.jpg" alt=" " width="680" height="328"&gt;&lt;/a&gt;&lt;br&gt;
This is how AI understands the word "Queen". Not by reading it. By knowing where it sits relative to everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Strawberry Problem
&lt;/h2&gt;

&lt;p&gt;Ask any LLM how many R's are in "strawberry." Most get it wrong.&lt;/p&gt;

&lt;p&gt;Not because it's stupid — because it never sees the full word. It sees "straw" and "berry" as two separate tokens and tries to count letters inside chunks it can't see into.&lt;/p&gt;

&lt;p&gt;This is the gap between what AI &lt;em&gt;feels&lt;/em&gt; like and what it actually &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xdtd810brlv9p1bzk3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xdtd810brlv9p1bzk3t.png" alt=" " width="514" height="160"&gt;&lt;/a&gt;&lt;br&gt;
"Straw" + "berry". Two tokens. This is why it can't count the R's.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in 2026?
&lt;/h2&gt;

&lt;p&gt;Tokens aren't just text anymore.&lt;/p&gt;

&lt;p&gt;Every major model (GPT-5.5, Claude Opus 4.7, Gemini 3.1 Pro…) now handles a million tokens in a single conversation. Images cost tokens. Audio costs tokens. Video costs tokens. Your entire prompt — text, files, screenshots — becomes one long river of numbers the model processes simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one thing to remember
&lt;/h2&gt;

&lt;p&gt;Your prompt is not a command. It's a &lt;strong&gt;statistical context&lt;/strong&gt; — a sequence of numbers that nudges the model toward the most probable next output.&lt;/p&gt;

&lt;p&gt;Better context = better predictions. That's the whole game.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the AI actually build its token vocabulary?
&lt;/h2&gt;

&lt;p&gt;This is the part nobody explains and everyone should know.&lt;/p&gt;

&lt;p&gt;The algorithm behind almost every major AI model (GPT, Claude, Llama, Mistral) is called &lt;strong&gt;Byte Pair Encoding&lt;/strong&gt;, or &lt;strong&gt;BPE&lt;/strong&gt;. It was originally invented in 1994 as a data compression algorithm. OpenAI repurposed it for AI in 2019.&lt;/p&gt;

&lt;p&gt;Nobody designed it for language. It just happened to work extraordinarily well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here's how BPE actually works (in plain English):
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Start with every single character in the alphabet. "h", "e", "l", "l", "o" — each is its own token.&lt;/li&gt;
&lt;li&gt;Now scan through billions of words and find the two characters that appear next to each other most frequently. Merge them into a single token.&lt;/li&gt;
&lt;li&gt;Repeat. Over and over. Thousands of times.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is a vocabulary of subword units — chunks that are bigger than single characters but smaller than full words — that perfectly balances handling rare words and common ones simultaneously.&lt;/p&gt;

&lt;p&gt;By the end, your vocabulary might look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"ing" is one token (because it appears everywhere)&lt;/li&gt;
&lt;li&gt;"un" is one token (prefix of thousands of words)&lt;/li&gt;
&lt;li&gt;"2026" is one token (appears enough to earn its own slot)&lt;/li&gt;
&lt;li&gt;"xylophone" gets split (rare enough that it never earned a merge)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final vocabulary of most modern LLMs sits between 32,000 and 128,000 tokens. GPT-4o uses around 100,000.&lt;/p&gt;

&lt;p&gt;Every prompt you send gets mapped into this fixed vocabulary and nothing outside it can exist.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjn6gbmfuimmnacyo6b9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjn6gbmfuimmnacyo6b9.jpg" alt=" " width="680" height="284"&gt;&lt;/a&gt;&lt;br&gt;
This is how AI builds its vocabulary. Not by learning words. By learning which letter combinations appear together most often and merging them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hidden bias nobody talks about
&lt;/h2&gt;

&lt;p&gt;Here's something that will make you genuinely uncomfortable.&lt;/p&gt;

&lt;p&gt;The training data for most LLMs is heavily skewed toward English. Llama 2, for example, was trained on &lt;strong&gt;89.7% English&lt;/strong&gt; content.&lt;/p&gt;

&lt;p&gt;This means the tokenizer learned English patterns extremely well and everything else poorly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result is a hidden inequality baked into every AI interaction:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processing the same sentence in German or Italian costs about &lt;strong&gt;50% more tokens&lt;/strong&gt; than in English.&lt;/li&gt;
&lt;li&gt;In languages like Burmese or Tibetan, the same text can cost &lt;strong&gt;up to 15 times more tokens&lt;/strong&gt; than the equivalent in English.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why does this matter?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because tokens = cost. Tokens = speed. Tokens = how much of your context window gets used up.&lt;/p&gt;

&lt;p&gt;If you're using AI in Hindi, Tamil, Arabic, or any non-English language, you are paying more, getting slower responses, and fitting less into each conversation.&lt;/p&gt;

&lt;p&gt;Not because the AI is worse. Because the tokenizer was never built with your language in mind.&lt;/p&gt;

&lt;p&gt;A developer described this perfectly: &lt;em&gt;"My agent works great in French or English. But if a user asks in Darija, it crashes in quality and becomes unusable."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's not a bug. That's tokenization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flwxp3hbhh7a921vajqkb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flwxp3hbhh7a921vajqkb.jpg" alt=" " width="680" height="265"&gt;&lt;/a&gt;&lt;br&gt;
This is one of the most underreported fairness issues in all of AI right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tokens are no longer just text
&lt;/h2&gt;

&lt;p&gt;This is where 2026 changes everything.&lt;/p&gt;

&lt;p&gt;Tokens aren't just words anymore. Every major frontier model now processes images, audio, and video as tokens too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An image tile costs tokens.&lt;/li&gt;
&lt;li&gt;A second of audio costs tokens.&lt;/li&gt;
&lt;li&gt;A video frame costs tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What this means in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you send Claude a screenshot, it doesn't "see" it the way you do. It converts the image into a grid of tiles, encodes each tile into numerical vectors, and feeds those vectors into the same token stream as your text.&lt;/p&gt;

&lt;p&gt;Your image. Your voice note. Your PDF. Your video. All of it — one long river of numbers. Processed the same way.&lt;/p&gt;

&lt;p&gt;The model has no concept of "this is a picture" versus "this is a sentence." It's all just tokens in a sequence.&lt;/p&gt;

&lt;p&gt;This is what people mean when they say AI is becoming truly multimodal. It's not that the model learned to see. It's that vision got tokenized.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feo9zq6c7kl3npq4fjk5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feo9zq6c7kl3npq4fjk5l.png" alt=" " width="680" height="363"&gt;&lt;/a&gt;&lt;br&gt;
Text. Image. Audio. Video. It all becomes the same thing before the model sees it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for how you use AI (starting today)
&lt;/h2&gt;

&lt;p&gt;Understanding tokenization isn't just academic. It directly changes how you should prompt.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Front-load your important information&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The model processes tokens left to right. The beginning of your prompt carries the most weight. Put your most critical instructions first — not buried in paragraph three.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be concise — you're paying per token&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Every word you type is tokens. Every word the model generates is tokens. Verbose prompts with filler phrases waste your context window and cost more on paid APIs. Trim everything that doesn't add meaning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;If you're coding, name things clearly&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Code files often exceed the token limit of a single embedding and they have to be chunked. Variable names and function names become individual tokens. Clear, common naming patterns tokenize more efficiently than cryptic abbreviations. &lt;code&gt;"getUserData"&lt;/code&gt; tokenizes better than &lt;code&gt;"gtUsrDt."&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Switch to English for complex reasoning tasks&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This is uncomfortable but true. For tasks requiring deep multi-step reasoning, especially on smaller models, English prompts will outperform non-English prompts because the tokenizer was trained primarily on English. On frontier models this gap is shrinking. On smaller local models, it's still significant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't trust AI with character-level tasks&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Spelling backwards. Counting specific letters. Rhyming on a specific syllable. Anagrams. These all require character-level processing that tokenization makes structurally difficult. Use AI for meaning-level tasks. Use code for character-level tasks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The future of tokenization
&lt;/h2&gt;

&lt;p&gt;Tokenization is not a solved problem. It's actively being reinvented right now.&lt;/p&gt;

&lt;p&gt;Researchers are exploring &lt;strong&gt;byte-level transformer models&lt;/strong&gt; that process raw bytes instead of subword tokens entirely. This would mean no vocabulary, no BPE merges, no tokenization bias against non-English languages. Every byte is treated equally.&lt;/p&gt;

&lt;p&gt;The tradeoff is sequence length. Bytes are much smaller than subwords, so the same text becomes a much longer sequence, which is expensive computationally.&lt;/p&gt;

&lt;p&gt;Other researchers are working on &lt;strong&gt;multilingual tokenizers with "language plasticity"&lt;/strong&gt; — the ability to adapt post-training to new languages without retraining the entire model from scratch.&lt;/p&gt;

&lt;p&gt;The goal is simple: an AI that processes every language on earth with equal efficiency, equal cost, and equal quality.&lt;/p&gt;

&lt;p&gt;We're not there yet. But tokenization is exactly where that battle is being fought.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Every time you type a message to an AI, a silent, high-speed assembly line starts moving.&lt;/p&gt;

&lt;p&gt;Your words get shredded.&lt;br&gt;&lt;br&gt;
Assigned numbers.&lt;br&gt;&lt;br&gt;
Converted into vectors.&lt;br&gt;&lt;br&gt;
Fed into a model that has never read a single word in its life.&lt;/p&gt;

&lt;p&gt;And somehow on the other side it answers like it understood everything.&lt;/p&gt;

&lt;p&gt;That gap between what's actually happening and what it &lt;em&gt;feels&lt;/em&gt; like is the most fascinating thing in technology right now.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source:&lt;/strong&gt; Adapted from the excellent thread by &lt;a href="https://x.com/Oishaaniii/status/2063859538407911635" rel="noopener noreferrer"&gt;Shiny (@Oishaaniii) on X&lt;/a&gt;. Original post contains additional visuals and examples.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>tokenization</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Stop letting AI agents click the expensive buttons</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sun, 05 Jul 2026 11:04:58 +0000</pubDate>
      <link>https://dev.to/sphillips1337/stop-letting-ai-agents-click-the-expensive-buttons-247f</link>
      <guid>https://dev.to/sphillips1337/stop-letting-ai-agents-click-the-expensive-buttons-247f</guid>
      <description>&lt;p&gt;A small business does not usually need a fully autonomous AI employee.&lt;/p&gt;

&lt;p&gt;It needs something less glamorous and much more useful: an agent that can prepare the work, explain its reasoning, show the exact action it wants to take, and then stop before it does anything expensive, public, or hard to undo.&lt;/p&gt;

&lt;p&gt;That sounds conservative until you watch an agent connected to real tools. Reading a calendar is harmless. Drafting a reply is useful. Sending that reply to a customer is different. Looking up an invoice is helpful. Issuing a refund, changing a price, publishing a blog post, deleting a record, or promising a delivery date is where the risk changes shape.&lt;/p&gt;

&lt;p&gt;This is the line small teams should design around.&lt;/p&gt;

&lt;p&gt;The current agent conversation is finally moving past "can it call tools?" and toward "which tools should it be allowed to call without a person?" MCP gives us a common way to expose tools and resources to AI clients. n8n and similar workflow tools give us the plumbing to pause, route, approve, and log decisions. The missing piece is a simple operating model a business owner can understand.&lt;/p&gt;

&lt;p&gt;I use this one: &lt;strong&gt;let the agent drive the forklift, but keep a human hand on the keys to the warehouse door.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The approval gate is not a failure mode
&lt;/h2&gt;

&lt;p&gt;Developers sometimes treat human approval as a sign that the automation is incomplete. For small businesses, it is often the feature that makes automation deployable.&lt;/p&gt;

&lt;p&gt;An approval gate says:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the agent can do the boring research;&lt;/li&gt;
&lt;li&gt;the agent can draft the action;&lt;/li&gt;
&lt;li&gt;the agent can collect supporting evidence;&lt;/li&gt;
&lt;li&gt;the agent can recommend a next step;&lt;/li&gt;
&lt;li&gt;but the final irreversible step needs a human yes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is safer, and it is easier to sell internally: owners can trust the agent to prepare three clean options without handing it final authority on day one.&lt;/p&gt;

&lt;p&gt;This is why n8n's human-in-the-loop tool-call pattern matters. Its docs describe an AI Agent that pauses when it wants to use a tool with human review enabled, then sends an approval request through a configured channel such as Slack, Telegram, or n8n Chat. That is the right mental model: the approval gate lives around specific tools, not around the whole workflow.&lt;/p&gt;

&lt;p&gt;The agent should not need permission to summarize a support ticket. It probably should need permission to close it with a refund.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sort tools by blast radius
&lt;/h2&gt;

&lt;p&gt;Before connecting an agent to business systems, write down the tools it can call and sort them into four buckets.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Read-only tools
&lt;/h3&gt;

&lt;p&gt;These fetch information but do not change anything.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search the knowledge base;&lt;/li&gt;
&lt;li&gt;read product inventory;&lt;/li&gt;
&lt;li&gt;fetch appointment availability;&lt;/li&gt;
&lt;li&gt;inspect order status;&lt;/li&gt;
&lt;li&gt;retrieve recent invoices;&lt;/li&gt;
&lt;li&gt;check website analytics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are usually safe to run automatically, assuming access control is correct and private data is handled properly. The main risk is information exposure, not operational damage.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Drafting tools
&lt;/h3&gt;

&lt;p&gt;These create something that still needs another step before it affects the outside world.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;draft a customer email;&lt;/li&gt;
&lt;li&gt;create an unpublished CMS post;&lt;/li&gt;
&lt;li&gt;prepare an invoice but do not send it;&lt;/li&gt;
&lt;li&gt;generate a quote;&lt;/li&gt;
&lt;li&gt;fill a CRM note;&lt;/li&gt;
&lt;li&gt;suggest a schedule change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These can often run automatically too, because the output is parked somewhere for review. Drafting is where small businesses get a lot of value quickly. A human still owns the final action, but the blank page disappears.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Reversible write tools
&lt;/h3&gt;

&lt;p&gt;These change state, but the change is low value, easy to undo, or visible only internally.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tag a lead;&lt;/li&gt;
&lt;li&gt;update a task status;&lt;/li&gt;
&lt;li&gt;add an internal note;&lt;/li&gt;
&lt;li&gt;move a ticket between queues;&lt;/li&gt;
&lt;li&gt;create a calendar hold;&lt;/li&gt;
&lt;li&gt;enrich a record with public data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These deserve more thought. Some can be automatic after testing. Others should start with approval until the team sees a few weeks of behaviour. The important part is to know why a tool is allowed to write, what the rollback path is, and who gets notified when it does.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Expensive buttons
&lt;/h3&gt;

&lt;p&gt;These are actions that spend money, make promises, expose content publicly, affect legal or financial records, or annoy customers if wrong.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send an email or SMS to a customer;&lt;/li&gt;
&lt;li&gt;publish a website or social post;&lt;/li&gt;
&lt;li&gt;issue a refund;&lt;/li&gt;
&lt;li&gt;change a live product price;&lt;/li&gt;
&lt;li&gt;delete a customer record;&lt;/li&gt;
&lt;li&gt;approve payroll;&lt;/li&gt;
&lt;li&gt;submit a tax or compliance document;&lt;/li&gt;
&lt;li&gt;place an order with a supplier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the expensive buttons. Put approval gates here first.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP needs business permissions, not just technical auth
&lt;/h2&gt;

&lt;p&gt;MCP authorization is important because MCP servers can expose sensitive resources and operations. The official docs focus on securing access to restricted servers and protected resources. That is necessary, but business safety needs one more layer.&lt;/p&gt;

&lt;p&gt;A valid user token answers: "is this client allowed to access the server?"&lt;/p&gt;

&lt;p&gt;A useful small-business policy also asks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this tool read-only or write-capable?&lt;/li&gt;
&lt;li&gt;Can this action be undone?&lt;/li&gt;
&lt;li&gt;Is there a money limit?&lt;/li&gt;
&lt;li&gt;Is there a customer-visible side effect?&lt;/li&gt;
&lt;li&gt;Does this action require a manager, owner, or domain expert?&lt;/li&gt;
&lt;li&gt;Should the same person who requested the action be allowed to approve it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That policy does not have to be complicated. A simple YAML file or database table is enough for many teams:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;read_order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;risk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read_only&lt;/span&gt;
    &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;never&lt;/span&gt;
  &lt;span class="na"&gt;draft_refund_email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;risk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;draft&lt;/span&gt;
    &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;never&lt;/span&gt;
  &lt;span class="na"&gt;issue_refund&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;risk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;expensive_button&lt;/span&gt;
    &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;required&lt;/span&gt;
    &lt;span class="na"&gt;max_without_owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;
  &lt;span class="na"&gt;publish_wordpress_post&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;risk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public_action&lt;/span&gt;
    &lt;span class="na"&gt;approval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;required&lt;/span&gt;
    &lt;span class="na"&gt;approvers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;marketing&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is not the format. The point is that your agent runtime, MCP gateway, or workflow orchestrator should know the difference between "look this up" and "do this now."&lt;/p&gt;

&lt;h2&gt;
  
  
  What an approval request should include
&lt;/h2&gt;

&lt;p&gt;A bad approval request says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The AI wants to use &lt;code&gt;issue_refund&lt;/code&gt;. Approve?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A good approval request gives the human enough context to make the decision in ten seconds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requested action;&lt;/li&gt;
&lt;li&gt;customer or record affected;&lt;/li&gt;
&lt;li&gt;amount or business impact;&lt;/li&gt;
&lt;li&gt;agent's reason;&lt;/li&gt;
&lt;li&gt;evidence it used;&lt;/li&gt;
&lt;li&gt;exact payload it will send;&lt;/li&gt;
&lt;li&gt;rollback path;&lt;/li&gt;
&lt;li&gt;timeout behaviour.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Refund £18.50 to Order #1842 because the courier marked the item lost and the customer has waited 9 days. Evidence: tracking link, customer message, policy section 4.2. If approved, the refund is sent via Stripe and a confirmation email is drafted. If rejected, the ticket stays open.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is reviewable. The owner can approve, reject, or edit. The agent has still saved the time: it found the order, checked the policy, wrote the rationale, and assembled the payload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with three gates
&lt;/h2&gt;

&lt;p&gt;If you are adding agents to an existing business workflow, do not start with a giant governance programme. Start with three gates.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Public communication gate&lt;/strong&gt; — anything that sends or publishes outside the company.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Money gate&lt;/strong&gt; — refunds, invoices, discounts, purchases, payroll, subscriptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record destruction gate&lt;/strong&gt; — deletes, merges, irreversible CRM/accounting changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything else can be evaluated tool by tool.&lt;/p&gt;

&lt;p&gt;This works especially well with n8n-style workflows. The agent can run the first 80% of the process, then pause at a human-in-the-loop node or approval-enabled tool. The approval can happen in the channel the business already uses. After approval, the workflow resumes and logs the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical architecture
&lt;/h2&gt;

&lt;p&gt;A small-business agent stack does not need to be exotic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP servers expose business tools: CRM, CMS, calendar, accounting, documents, email.&lt;/li&gt;
&lt;li&gt;A gateway or policy layer tags tools by risk and enforces approval rules.&lt;/li&gt;
&lt;li&gt;A workflow engine such as n8n handles routing, waiting, reminders, and notifications.&lt;/li&gt;
&lt;li&gt;The agent prepares the action and evidence.&lt;/li&gt;
&lt;li&gt;A human approves expensive buttons.&lt;/li&gt;
&lt;li&gt;Every decision is logged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can make this more advanced later with dynamic tool routing, observability traces, local models, and audit dashboards. But the core pattern is simple: &lt;strong&gt;agents prepare; humans approve; workflows execute; logs remember.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is good for adoption
&lt;/h2&gt;

&lt;p&gt;Small businesses are not short of AI demos. They are short of trustworthy systems that fit into messy daily operations.&lt;/p&gt;

&lt;p&gt;Approval gates make agents less magical and more usable. They give owners a way to start small without handing over the keys. They also produce training data: every approval, rejection, and edit teaches the team where the agent is reliable and where the policy needs tightening.&lt;/p&gt;

&lt;p&gt;That is how automation becomes operational instead of performative.&lt;/p&gt;

&lt;p&gt;Do not ask, "Can the agent do the whole job?"&lt;/p&gt;

&lt;p&gt;Ask, "Which parts can it do safely, and where should it stop?"&lt;/p&gt;

&lt;p&gt;That question is much easier to answer. It is also the question that turns AI agents from a risky experiment into something a small business can actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;n8n docs: human-in-the-loop tool calls can pause an AI Agent before review-enabled tools and request approval through Slack, Telegram, or n8n Chat.&lt;/li&gt;
&lt;li&gt;MCP docs: authorization protects access to sensitive resources and operations exposed by MCP servers.&lt;/li&gt;
&lt;li&gt;X trend scan, July 2026: current small-business automation discussion is clustering around agents, MCP, workflow automation, and human oversight for high-stakes actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.n8n.io/build/integrate-ai/ai-examples/human-in-the-loop-for-tools" rel="noopener noreferrer"&gt;https://docs.n8n.io/build/integrate-ai/ai-examples/human-in-the-loop-for-tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.n8n.io/advanced-ai/human-in-the-loop-tools/" rel="noopener noreferrer"&gt;https://docs.n8n.io/advanced-ai/human-in-the-loop-tools/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/tutorials/security/authorization" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/docs/tutorials/security/authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/draft/basic/authorization" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/draft/basic/authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/HappyMonkeyAI/status/2073238780086042981" rel="noopener noreferrer"&gt;https://x.com/HappyMonkeyAI/status/2073238780086042981&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/GoodFellasTech/status/2073075934895153194" rel="noopener noreferrer"&gt;https://x.com/GoodFellasTech/status/2073075934895153194&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>mcp</category>
      <category>n8n</category>
    </item>
    <item>
      <title>Your AI agent needs receipts, not vibes: tracing MCP workflows for small businesses</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Sat, 04 Jul 2026 13:32:20 +0000</pubDate>
      <link>https://dev.to/sphillips1337/your-ai-agent-needs-receipts-not-vibes-tracing-mcp-workflows-for-small-businesses-4lf2</link>
      <guid>https://dev.to/sphillips1337/your-ai-agent-needs-receipts-not-vibes-tracing-mcp-workflows-for-small-businesses-4lf2</guid>
      <description>&lt;p&gt;A small-business AI agent is easy to demo and surprisingly hard to trust.&lt;/p&gt;

&lt;p&gt;The demo looks clean: connect the agent to email, invoices, a CRM, maybe a few n8n workflows, then ask it to chase unpaid invoices or triage customer messages. It calls the right tools. It writes a neat summary. Everyone nods.&lt;/p&gt;

&lt;p&gt;Then Monday happens.&lt;/p&gt;

&lt;p&gt;A customer asks why they got the wrong follow-up. The owner wants to know whether the agent actually checked the CRM before it emailed them. The developer opens a log file and finds prompts, HTTP requests, half-useful timestamps, and no story.&lt;/p&gt;

&lt;p&gt;That is the line between an AI automation toy and an AI automation system: can you reconstruct what happened after the agent did something real?&lt;/p&gt;

&lt;p&gt;For HappyMonkey-style small-business automation, this is the next practical problem after “can the agent call tools?” MCP gives agents a standard way to connect to external systems. n8n and similar tools give teams a place to run repeatable processes. OpenTelemetry and simple receipt logs give you the missing paper trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP gives the agent hands
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol is an open standard for connecting AI apps to external systems: local files, databases, tools, search, workflows, prompts. The docs use a USB-C metaphor. Fine. The useful part is the separation.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding every integration into the agent, you expose capabilities through MCP servers. The agent discovers a tool, calls it with structured inputs, and gets structured results back.&lt;/p&gt;

&lt;p&gt;That matters because small-business stacks are messy. Accounting in one system. Leads from a website form. Bookings in a calendar. The owner still forwards important emails by hand. If every integration needs bespoke agent code, the project dies under maintenance.&lt;/p&gt;

&lt;p&gt;MCP makes tool access more regular. It does not magically make the work safe. Once an agent can touch real systems, you need to know what it touched, why, how long it took, what it cost, and what came back.&lt;/p&gt;

&lt;p&gt;Tool access without observability is just a more confident black box.&lt;/p&gt;

&lt;p&gt;One practical pattern is a dynamic MCP gateway rather than a static pile of servers. We use &lt;a href="https://github.com/HappyMonkeyAI/DynamicMCPProxy" rel="noopener noreferrer"&gt;DynamicMCPProxy&lt;/a&gt; for this: the IDE connects to one proxy, sends project/task context, and the proxy lazily activates relevant MCP servers while keeping the active tool count under control. That reduces tool soup. It also creates a control point for receipts: server activation, tool call, latency, and outcome can all pass through one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflows give the agent rails
&lt;/h2&gt;

&lt;p&gt;This is where tools like n8n fit. AI workflow automation differs from classic app-to-app glue: the AI layer can interpret, decide, and generate, while the workflow layer still provides structure.&lt;/p&gt;

&lt;p&gt;That split is useful. Let the agent decide which business action is needed, but put the actual action behind a workflow with retries, validation, credentials, and predictable side effects.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lookup_customer_balance&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;send_payment_reminder_for_invoice&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_follow_up_task&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;summarize_new_leads_from_website&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;draft_wordpress_post_from_source_notes&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each can be an MCP-exposed tool or a workflow behind an MCP server. The agent chooses. The workflow executes.&lt;/p&gt;

&lt;p&gt;After a failure, the question is not “did we use MCP?” It is “what exactly happened?”&lt;/p&gt;

&lt;p&gt;If an invoice reminder went to the wrong person, you need a trace that answers boring questions quickly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which user request started this run?&lt;/li&gt;
&lt;li&gt;Which model answered?&lt;/li&gt;
&lt;li&gt;Which tools did it call?&lt;/li&gt;
&lt;li&gt;What arguments did it pass?&lt;/li&gt;
&lt;li&gt;Which workflow ran?&lt;/li&gt;
&lt;li&gt;Did the workflow retry?&lt;/li&gt;
&lt;li&gt;What did the external API return?&lt;/li&gt;
&lt;li&gt;Did a human approve the final action?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The boring questions are the business-critical ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traces beat giant logs
&lt;/h2&gt;

&lt;p&gt;A normal application log says “this thing happened at this time.” Useful, but agent runs are nested. One request might include planning, retrieval, model calls, tool calls, workflow calls, retries, and a final response.&lt;/p&gt;

&lt;p&gt;A trace gives you the tree.&lt;/p&gt;

&lt;p&gt;OpenTelemetry is already the common language for tracing distributed systems. Its GenAI semantic conventions cover model requests, token usage, and related AI operations. Treat model calls and agent steps as first-class spans rather than random log lines.&lt;/p&gt;

&lt;p&gt;The CNCF has also written about Jaeger evolving for AI-agent traces with OpenTelemetry. Agent observability is being pulled into the same operational world as services, queues, databases, and APIs.&lt;/p&gt;

&lt;p&gt;For small-business automation you probably do not need a huge observability platform on day one. You do need the shape of the data to be right.&lt;/p&gt;

&lt;p&gt;A practical trace might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer_email_triage run
  model.plan
  mcp.tool.search_customer_by_email
  mcp.tool.get_recent_orders
  workflow.n8n.create_support_ticket
  model.draft_reply
  human.approval.requested
  email.send
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each span should carry just enough metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;span name: mcp.tool.get_recent_orders
customer_id: cust_123
workflow_run_id: n8n_456
latency_ms: 820
status: ok
records_returned: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not log private customer content by default. Log IDs, counts, status, latency, cost, tool names, model names, and approval state. Keep sensitive payloads somewhere controlled, if you keep them at all.&lt;/p&gt;

&lt;p&gt;That design choice matters. Teams choose local AI or self-hosted workflows for privacy, cost, or control. Observability should not undo that by spraying customer emails into a third-party logging account.&lt;/p&gt;

&lt;h2&gt;
  
  
  The minimum viable agent receipt
&lt;/h2&gt;

&lt;p&gt;If you are building this for a client, start smaller than you think.&lt;/p&gt;

&lt;p&gt;For every agent run, save a receipt with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trigger&lt;/strong&gt; — user message, cron, webhook, or inbound email
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision&lt;/strong&gt; — short reason the agent chose a tool or workflow
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool calls&lt;/strong&gt; — name, redacted args, status, duration
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow calls&lt;/strong&gt; — workflow ID, run ID, status, retry count
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model usage&lt;/strong&gt; — model name, latency, token count or local runtime estimate
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human gate&lt;/strong&gt; — approved, edited, or blocked
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outcome&lt;/strong&gt; — what changed in the real world
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A JSON file is enough at first. OpenTelemetry spans can come later. Design as if someone will ask “why did the agent do that?” because someone will.&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;"run_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;"run_2026_07_04_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inbound_customer_email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support_triage_agent"&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;"local-llm-via-ollama"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tool_calls"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp.tool.search_customer_by_email"&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;"ok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"duration_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;210&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"redacted_args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"email_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workflow_calls"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n.create_support_ticket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"run_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;"n8n_456"&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;"ok"&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;"human_approval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"required_before_send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outcome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"drafted_reply_and_created_ticket"&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;Not glamorous. It is what keeps the owner from losing confidence the first time a workflow behaves oddly.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete gateway example
&lt;/h2&gt;

&lt;p&gt;In our stack, DynamicMCPProxy started as a way to stop MCP tool soup: one proxy, right servers for the current project, active tool list under a sensible budget.&lt;/p&gt;

&lt;p&gt;The same gateway is a natural place for receipts. Recent versions record JSONL events for handshakes, server activation, lazy materialisation, and child MCP tool calls — &lt;code&gt;run_id&lt;/code&gt;, &lt;code&gt;span_id&lt;/code&gt;, event type, caller identity, status, latency, server name, runtime, argument keys.&lt;/p&gt;

&lt;p&gt;The security detail that matters is what it does &lt;strong&gt;not&lt;/strong&gt; record. HMAC-authenticated sidecar calls log a caller such as &lt;code&gt;service:hmac&lt;/code&gt;, but not the key. Tool arguments are summarised as keys, types, lengths, and hashes rather than raw customer content. Optional OpenTelemetry export can mirror the trace later; local JSONL still works without shipping sensitive payloads to a vendor.&lt;/p&gt;

&lt;p&gt;Pattern for most small-business agents: local receipts first, OpenTelemetry when traffic or risk justifies distributed tracing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would instrument first
&lt;/h2&gt;

&lt;p&gt;Do not start by instrumenting every prompt token. Start where support pain or money lives.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Invoices:&lt;/strong&gt; customer lookup, invoice lookup, payment status, reminder generation, approval, send
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leads:&lt;/strong&gt; source, dedupe, enrichment, CRM write, notification, follow-up task
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WordPress/content:&lt;/strong&gt; source URLs, summarisation, draft creation, image generation, human review, publish state — especially publish state
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local AI / Ollama:&lt;/strong&gt; runtime and fallback. If a local model fails and the system falls back to cloud, that should be visible. A silent model switch puts a hole in the privacy story.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The sales angle is reliability, not magic
&lt;/h2&gt;

&lt;p&gt;A lot of small-business AI pitches still sound like magic: “we will automate your operations with agents.” Owners have heard enough of that.&lt;/p&gt;

&lt;p&gt;A better pitch is concrete:&lt;/p&gt;

&lt;p&gt;“We will automate one repetitive workflow. You will see every tool the agent used, every workflow it triggered, whether a human approved it, and what changed. If something goes wrong, we can replay the receipt.”&lt;/p&gt;

&lt;p&gt;Less flashy. More believable.&lt;/p&gt;

&lt;p&gt;MCP makes integrations less brittle. Workflow tools make actions repeatable. Observability makes the whole thing accountable.&lt;/p&gt;

&lt;p&gt;That combination is what turns a clever prototype into a service you can charge for every month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCP intro: &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/docs/getting-started/intro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenTelemetry GenAI semantic conventions: &lt;a href="https://opentelemetry.io/docs/specs/semconv/gen-ai/" rel="noopener noreferrer"&gt;https://opentelemetry.io/docs/specs/semconv/gen-ai/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CNCF / Jaeger on AI-agent traces: &lt;a href="https://www.cncf.io/blog/2026/05/26/how-jaeger-is-evolving-to-trace-ai-agents-with-opentelemetry/" rel="noopener noreferrer"&gt;https://www.cncf.io/blog/2026/05/26/how-jaeger-is-evolving-to-trace-ai-agents-with-opentelemetry/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;n8n AI workflow automation overview: &lt;a href="https://blog.n8n.io/best-ai-workflow-automation-tools/" rel="noopener noreferrer"&gt;https://blog.n8n.io/best-ai-workflow-automation-tools/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DynamicMCPProxy: &lt;a href="https://github.com/HappyMonkeyAI/DynamicMCPProxy" rel="noopener noreferrer"&gt;https://github.com/HappyMonkeyAI/DynamicMCPProxy&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>observability</category>
      <category>automation</category>
    </item>
    <item>
      <title>Local AI agents for small businesses: where Ollama and MCP actually fit</title>
      <dc:creator>Stephen Phillips</dc:creator>
      <pubDate>Fri, 03 Jul 2026 14:04:58 +0000</pubDate>
      <link>https://dev.to/sphillips1337/local-ai-agents-for-small-businesses-where-ollama-and-mcp-actually-fit-2m69</link>
      <guid>https://dev.to/sphillips1337/local-ai-agents-for-small-businesses-where-ollama-and-mcp-actually-fit-2m69</guid>
      <description>&lt;p&gt;Local AI is having another moment because the use case finally makes sense.&lt;/p&gt;

&lt;p&gt;A small business does not always need the smartest model in the world. It often needs a private assistant that can read the right files, draft the right response and avoid sending customer data to five different cloud services.&lt;/p&gt;

&lt;p&gt;That is where Ollama plus MCP becomes interesting.&lt;/p&gt;

&lt;p&gt;Ollama gives you a local model endpoint. The Ollama API docs show the default local base URL as &lt;code&gt;http://localhost:11434/api&lt;/code&gt;, with endpoints such as &lt;code&gt;/api/generate&lt;/code&gt;. MCP gives the agent a standard way to reach tools, resources and prompts around that model.&lt;/p&gt;

&lt;p&gt;The combination is not magic. It is just a sensible architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic shape
&lt;/h2&gt;

&lt;p&gt;A local-first business agent stack looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ollama runs the model.&lt;/li&gt;
&lt;li&gt;MCP servers expose business tools.&lt;/li&gt;
&lt;li&gt;A thin agent decides what to read or draft.&lt;/li&gt;
&lt;li&gt;Human approval gates anything risky.&lt;/li&gt;
&lt;li&gt;Logs record what happened.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many businesses, that is enough.&lt;/p&gt;

&lt;p&gt;You can run it on a spare machine, a Mac mini, a local server, or a small GPU box. The exact hardware depends on the model size and workload, but the point is control. Your customer emails, internal notes and messy spreadsheets can stay on your network.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should stay local
&lt;/h2&gt;

&lt;p&gt;Not every AI task needs to be local. Some jobs are harmless enough to send to a hosted model. But local is worth considering when the data is sensitive, repetitive or close to day-to-day operations.&lt;/p&gt;

&lt;p&gt;Good local candidates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer support triage.&lt;/li&gt;
&lt;li&gt;Internal knowledge-base search.&lt;/li&gt;
&lt;li&gt;First drafts of replies and proposals.&lt;/li&gt;
&lt;li&gt;Summaries of call transcripts.&lt;/li&gt;
&lt;li&gt;Invoice and receipt categorisation.&lt;/li&gt;
&lt;li&gt;Staff process documentation.&lt;/li&gt;
&lt;li&gt;Website content drafts from approved notes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model does not need to be perfect. It needs to be useful inside a bounded workflow.&lt;/p&gt;

&lt;p&gt;A local model that drafts a reply for review can save time today. A local model that autonomously emails customers needs much more work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP matters here
&lt;/h2&gt;

&lt;p&gt;A local model by itself is just text in, text out.&lt;/p&gt;

&lt;p&gt;MCP changes the shape of the problem. The official MCP tools spec describes tools that a model can discover and invoke, backed by schemas. Those tools can query databases, call APIs or run computations.&lt;/p&gt;

&lt;p&gt;That means your local model can become part of a workflow without every integration becoming custom glue.&lt;/p&gt;

&lt;p&gt;For example, a local support agent could have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A read-only inbox search tool.&lt;/li&gt;
&lt;li&gt;A customer lookup tool.&lt;/li&gt;
&lt;li&gt;A policy document resource.&lt;/li&gt;
&lt;li&gt;A draft reply writer.&lt;/li&gt;
&lt;li&gt;A ticket note updater.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is already useful. The agent reads the customer message, checks the policy, drafts a reply and records a summary. A person still approves the final email.&lt;/p&gt;

&lt;h2&gt;
  
  
  The privacy advantage is real, but not automatic
&lt;/h2&gt;

&lt;p&gt;Running the model locally helps, but it does not make the whole system private by default.&lt;/p&gt;

&lt;p&gt;If your MCP tools call cloud APIs, data still leaves the machine. If your logs capture full customer records and sync to a third-party observability service, data still leaves. If the agent can call a web search tool with private context in the query, data still leaks.&lt;/p&gt;

&lt;p&gt;Local-first architecture needs boring rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate local tools from cloud tools.&lt;/li&gt;
&lt;li&gt;Mark tools as read-only or write-capable.&lt;/li&gt;
&lt;li&gt;Redact sensitive fields in logs.&lt;/li&gt;
&lt;li&gt;Keep customer data out of prompts when it is not needed.&lt;/li&gt;
&lt;li&gt;Use draft actions before send actions.&lt;/li&gt;
&lt;li&gt;Keep approval on anything external-facing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model location is only one part of the privacy story.&lt;/p&gt;

&lt;h2&gt;
  
  
  A first workflow: local proposal assistant
&lt;/h2&gt;

&lt;p&gt;Imagine a small web agency.&lt;/p&gt;

&lt;p&gt;Every new lead asks roughly the same questions: price, timeline, whether WordPress is okay, whether SEO is included, whether the agency can migrate old content.&lt;/p&gt;

&lt;p&gt;A local proposal assistant could:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the contact-form submission.&lt;/li&gt;
&lt;li&gt;Search internal service notes.&lt;/li&gt;
&lt;li&gt;Pull a few approved case-study snippets.&lt;/li&gt;
&lt;li&gt;Draft a reply.&lt;/li&gt;
&lt;li&gt;Draft a proposal outline.&lt;/li&gt;
&lt;li&gt;Save both for review.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent does not need the ability to send the email. It does not need access to payroll. It does not need all files on disk.&lt;/p&gt;

&lt;p&gt;It needs a small set of tools and a clear output.&lt;/p&gt;

&lt;p&gt;That is the part people miss when they get excited about local agents. The win is not "my laptop has a CEO now". The win is that a boring admin task becomes 70 percent done before you touch it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where hosted models still fit
&lt;/h2&gt;

&lt;p&gt;A local setup can also route harder tasks to hosted models.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Use Ollama for triage, classification and drafts with sensitive data.&lt;/li&gt;
&lt;li&gt;Use a hosted model for public research where no private data is included.&lt;/li&gt;
&lt;li&gt;Use a stronger hosted model for final editing after removing customer details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This hybrid approach is often better than ideological purity. Keep sensitive context local. Use stronger cloud models when the input is safe and the quality gain matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MVP stack
&lt;/h2&gt;

&lt;p&gt;For a small business, I would start with this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ollama for a local model endpoint.&lt;/li&gt;
&lt;li&gt;A filesystem or document MCP server limited to one folder.&lt;/li&gt;
&lt;li&gt;An email or CRM MCP server in read-only mode where possible.&lt;/li&gt;
&lt;li&gt;A draft writer tool that saves markdown, not sends messages.&lt;/li&gt;
&lt;li&gt;A simple approval step.&lt;/li&gt;
&lt;li&gt;A log file with tool calls and outcomes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then pick one workflow.&lt;/p&gt;

&lt;p&gt;Do not start by connecting every system. Start with the task the business already hates doing every week.&lt;/p&gt;

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

&lt;p&gt;Local models still make mistakes. They may misunderstand instructions, miss details, or produce confident but wrong drafts. Smaller models can be especially brittle with long context or complex tool use.&lt;/p&gt;

&lt;p&gt;That is why local agents work best when the workflow is narrow and the failure mode is cheap.&lt;/p&gt;

&lt;p&gt;A bad draft is fine. A bad payment action is not.&lt;/p&gt;

&lt;p&gt;Local AI plus MCP is not a replacement for business process design. It is a cheaper, more private way to automate the parts of the process that were already clear.&lt;/p&gt;

&lt;p&gt;That is a good thing. Most businesses do not need science fiction. They need the inbox to be less awful on Monday morning.&lt;/p&gt;




&lt;p&gt;Source notes used while drafting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP tools specification: &lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/server/tools" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2025-06-18/server/tools&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ollama API introduction: &lt;a href="https://docs.ollama.com/api/introduction" rel="noopener noreferrer"&gt;https://docs.ollama.com/api/introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;n8n MCP server docs: &lt;a href="https://docs.n8n.io/connect/connect-to-n8n-mcp-server" rel="noopener noreferrer"&gt;https://docs.n8n.io/connect/connect-to-n8n-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;n8n MCP tools reference: &lt;a href="https://docs.n8n.io/connect/connect-to-n8n-mcp-server/mcp-server-tools-reference" rel="noopener noreferrer"&gt;https://docs.n8n.io/connect/connect-to-n8n-mcp-server/mcp-server-tools-reference&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pydantic Logfire MCP server guide: &lt;a href="https://pydantic.dev/docs/logfire/guides/mcp-server/" rel="noopener noreferrer"&gt;https://pydantic.dev/docs/logfire/guides/mcp-server/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X trend scans run 2026-07-03 for: MCP agents small business automation, local AI agents Ollama MCP, AI agent tool soup MCP workflow automation.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>localai</category>
      <category>mcp</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
