<?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: Dan Barr</title>
    <description>The latest articles on DEV Community by Dan Barr (@danbarr).</description>
    <link>https://dev.to/danbarr</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2053808%2Fcb86d326-f1d1-49ec-a784-065db9fa5425.jpeg</url>
      <title>DEV Community: Dan Barr</title>
      <link>https://dev.to/danbarr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danbarr"/>
    <language>en</language>
    <item>
      <title>Introducing Virtual MCP Server: Unified Gateway for Multi-MCP Workflows</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Thu, 11 Dec 2025 15:59:12 +0000</pubDate>
      <link>https://dev.to/stacklok/introducing-virtual-mcp-server-unified-gateway-for-multi-mcp-workflows-17ee</link>
      <guid>https://dev.to/stacklok/introducing-virtual-mcp-server-unified-gateway-for-multi-mcp-workflows-17ee</guid>
      <description>&lt;p&gt;If you're working with AI coding assistants like GitHub Copilot or Claude, you've probably encountered MCP (Model Context Protocol) servers. They're powerful, connecting your AI to GitHub, Jira, Slack, cloud providers, and more. But here's the problem: each connection requires separate configuration, authentication, and maintenance.&lt;/p&gt;

&lt;p&gt;Managing MCP server connections gets messy fast. That’s why we built the &lt;strong&gt;Virtual MCP Server (vMCP)&lt;/strong&gt; in ToolHive to solve this problem by aggregating multiple MCP servers into a single unified endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: connection overload
&lt;/h2&gt;

&lt;p&gt;Picture this: you're an engineer on a platform team. Your AI assistant needs access to GitHub for code, Jira for tickets, Slack for notifications, PagerDuty for incidents, Datadog for metrics, AWS for infrastructure, Confluence for docs, and your internal knowledge base. That's 8 separate MCP server connections, each exposing 10-20+ tools. Now your AI's context window is filling up with 80+ tool descriptions, burning tokens and degrading performance as the LLM struggles to select the right tools from an overwhelming list.&lt;/p&gt;

&lt;p&gt;Each MCP server connection requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Individual configuration in your AI client
&lt;/li&gt;
&lt;li&gt;Separate authentication credentials
&lt;/li&gt;
&lt;li&gt;Manual coordination when tasks span multiple systems
&lt;/li&gt;
&lt;li&gt;Repeated parameter entry (same repo, same channel, same database)
&lt;/li&gt;
&lt;li&gt;Tool filtering to avoid context bloat and wasted tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to investigate a production incident? You're manually running commands across 4 different systems and piecing together the results yourself. Deploying an app? You're orchestrating a sequence of operations: merge PR, wait for CI, get approval, deploy, notify team. It's tedious, error-prone, and not reusable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution: aggregate everything
&lt;/h2&gt;

&lt;p&gt;vMCP transforms those 8 connections into one. You configure a single MCP endpoint that aggregates all your backend servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before vMCP:&lt;/strong&gt;&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;"servers"&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;"github"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"jira"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"slack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"pagerduty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"datadog"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"aws"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"confluence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&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;"docs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With vMCP:&lt;/strong&gt;&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;"servers"&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;"company-tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://vmcp.company.com/mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One connection. One authentication flow. All your tools available.&lt;/p&gt;

&lt;p&gt;And here’s the key: &lt;strong&gt;you can run as many vMCP instances as you need&lt;/strong&gt;. Your frontend team connects to one vMCP with their specific tools. Your platform team connects to another with infrastructure access. Each vMCP aggregates exactly the backends that each team needs, with appropriate security policies and permissions.&lt;/p&gt;

&lt;p&gt;This matters for two reasons: security (no more giving everyone access to everything) and efficiency (fewer tools means smaller context windows, which means lower token costs and better AI performance).&lt;/p&gt;

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

&lt;p&gt;vMCP is part of the ToolHive Kubernetes Operator. It acts as an intelligent aggregation layer that sits between your AI client and your backend MCP servers.&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.amazonaws.com%2Fuploads%2Farticles%2F6k3iv7ipy29yk4cnywjp.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.amazonaws.com%2Fuploads%2Farticles%2F6k3iv7ipy29yk4cnywjp.png" alt="Diagram of the basic vMCP architecture" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Multi-server aggregation with tool filtering
&lt;/h3&gt;

&lt;p&gt;All MCP tools appear through a single endpoint, &lt;strong&gt;but you cherry-pick exactly which tools to expose&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example: An engineer on the ToolHive team gets a single vMCP connection with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub’s &lt;code&gt;search_code&lt;/code&gt; tool (scoped to the &lt;code&gt;stacklok/toolhive&lt;/code&gt; repo only)
&lt;/li&gt;
&lt;li&gt;The ToolHive docs MCP server
&lt;/li&gt;
&lt;li&gt;An internal docs server hooked up to Google Drive and filtered to ToolHive design docs
&lt;/li&gt;
&lt;li&gt;Slack (only the &lt;code&gt;#toolhive-team&lt;/code&gt; channel)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No irrelevant tools cluttering the LLM's context. No wasted tokens on unused tool descriptions. Just the tools needed for their work, making it easier for the AI to select the right tool every time.&lt;/p&gt;

&lt;p&gt;When multiple MCP servers have tools with the same name (both GitHub and Jira have &lt;code&gt;create_issue&lt;/code&gt;), vMCP automatically prefixes them: &lt;code&gt;github_create_issue&lt;/code&gt; and &lt;code&gt;jira_create_issue&lt;/code&gt;. You can customize these names however you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Declarative multi-system workflows
&lt;/h3&gt;

&lt;p&gt;Real tasks often require coordinating across multiple systems. vMCP lets you define deterministic workflows that execute in parallel with conditionals, error handling, and approval gates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Incident investigation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of manually jumping between 4 different systems, copy/pasting data, and aggregating the results, a single “composite tool” could:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ Query logs from logging system
→ Fetch metrics from monitoring platform  
→ Pull traces from tracing service
→ Check infrastructure status from cloud provider
→ Manually combine everything into a report
→ Create Jira ticket with findings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vMCP executes all queries in parallel, automatically aggregates the data, and creates the ticket. Define the workflow once, use it for every incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: App deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A typical deployment workflow handled end-to-end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ Merge pull request in GitHub
→ Wait for CI tests to pass
→ Request human approval (using MCP elicitation)
→ Deploy (only if approved)
→ Notify team in Slack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Pre-configured defaults and guardrails
&lt;/h3&gt;

&lt;p&gt;Stop typing the same parameters repeatedly. Configure defaults once in vMCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Every GitHub query requires specifying &lt;code&gt;repo: stacklok/toolhive&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; The repo is pre-configured. Engineers never specify it, and they can't accidentally query the wrong one.&lt;/p&gt;

&lt;p&gt;This isn’t just convenience, it’s about deterministic behavior and security. By pre-configuring parameters, you ensure tools behave consistently, and users can only access resources you’ve explicitly exposed. No more accidental queries to the wrong repo, Slack channels, databases, cloud regions, or anything else you reference repeatedly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Tool customization and security policies
&lt;/h3&gt;

&lt;p&gt;Third-party MCP servers often expose generic, unrestricted tools. vMCP lets you wrap and restrict them without modifying upstream servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security policy enforcement:&lt;/strong&gt; Restrict a website fetch tool to internal domains only (&lt;code&gt;*.company.com&lt;/code&gt;), validate URLs before calling the backend, and provide clear error messages for violations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simplified interfaces:&lt;/strong&gt; That AWS EC2 tool with 20+ parameters? Create a wrapper that only exposes the 3 parameters your frontend team actually needs, with safe defaults for everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Centralized authentication
&lt;/h3&gt;

&lt;p&gt;vMCP implements a two-boundary authentication model with a complete audit trail. Your AI client authenticates once to vMCP using the OAuth 2.1 methods defined in the official MCP spec. vMCP handles authorization to each backend independently based on its requirements.&lt;/p&gt;

&lt;p&gt;When it’s time to revoke access, disable the user in your identity provider, and all backend access is revoked instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world benefits
&lt;/h2&gt;

&lt;p&gt;Let's look at the incident investigation example with concrete numbers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without vMCP:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 sequential manual commands
&lt;/li&gt;
&lt;li&gt;2-3 minutes per command
&lt;/li&gt;
&lt;li&gt;5-10 minutes aggregating and formatting
&lt;/li&gt;
&lt;li&gt;15-20 minutes total per incident
&lt;/li&gt;
&lt;li&gt;Results vary by engineer
&lt;/li&gt;
&lt;li&gt;Process isn't documented or reusable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With vMCP:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One command triggers the workflow
&lt;/li&gt;
&lt;li&gt;Parallel execution: 30 seconds
&lt;/li&gt;
&lt;li&gt;Automatic aggregation and formatting
&lt;/li&gt;
&lt;li&gt;Consistent results every time
&lt;/li&gt;
&lt;li&gt;Workflow is documented as code
&lt;/li&gt;
&lt;li&gt;Any team member can use it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a team handling 20 incidents per week, that's 5-6 hours saved. More importantly, the response is faster, more consistent, and doesn't require senior engineers to handle routine investigations.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;vMCP runs in Kubernetes alongside your backend MCP servers. You define three types of resources:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCPGroup:&lt;/strong&gt; Organizes backend servers logically (e.g., "platform-tools")&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCPServer:&lt;/strong&gt; Individual backend MCP servers (GitHub, Jira, etc.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VirtualMCPServer:&lt;/strong&gt; The aggregation layer that combines servers from a group&lt;/p&gt;

&lt;p&gt;The ToolHive operator discovers backends, resolves tool name conflicts, applies security policies, and exposes everything through a single endpoint. Your AI client connects to vMCP just like any other MCP server.&lt;/p&gt;

&lt;p&gt;Since each VirtualMCPServer is a separate Kubernetes resource, you can deploy as many as needed. One per team, one per environment, or organized however makes sense for your security model.&lt;/p&gt;

&lt;p&gt;For a working example, check out the &lt;a href="https://docs.stacklok.com/toolhive/tutorials/quickstart-vmcp" rel="noopener noreferrer"&gt;quickstart tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use vMCP
&lt;/h2&gt;

&lt;p&gt;vMCP makes sense when you're managing multiple MCP servers (typically 5+), curating a subset of MCP tools for specific teams and workflows, or need tasks that coordinate across systems. It's especially valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams requiring centralized authentication and authorization
&lt;/li&gt;
&lt;li&gt;Workflows that should be reusable across the entire team
&lt;/li&gt;
&lt;li&gt;Security policies that need centralized enforcement
&lt;/li&gt;
&lt;li&gt;Reducing onboarding complexity for new engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using a single MCP server for simple one-step operations, you probably don't need vMCP. It's built for managing complexity at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;vMCP is available now as part of ToolHive. To try it out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the ToolHive Kubernetes Operator
&lt;/li&gt;
&lt;li&gt;Follow the &lt;a href="https://docs.stacklok.com/toolhive/tutorials/quickstart-vmcp" rel="noopener noreferrer"&gt;vMCP quickstart&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Connect your AI client to the aggregated endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'd love to hear how you're using vMCP. What workflows are you building? Which MCP servers are you aggregating? Join the &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;ToolHive community on Discord&lt;/a&gt; and let us know.&lt;/p&gt;

&lt;p&gt;Looking to leverage vMCP within your enterprise organization? &lt;a href="https://calendly.com/stacklok/30min" rel="noopener noreferrer"&gt;Book a demo with us&lt;/a&gt;.  &lt;/p&gt;




&lt;p&gt;&lt;em&gt;ToolHive is an open-source MCP platform focused on security and enterprise operationalization. Learn more at &lt;a href="https://toolhive.dev" rel="noopener noreferrer"&gt;toolhive.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>toolhive</category>
    </item>
    <item>
      <title>Cut token waste from your AI workflow with the ToolHive MCP Optimizer</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Tue, 28 Oct 2025 17:12:08 +0000</pubDate>
      <link>https://dev.to/stacklok/cut-token-waste-from-your-ai-workflow-with-the-toolhive-mcp-optimizer-3oo6</link>
      <guid>https://dev.to/stacklok/cut-token-waste-from-your-ai-workflow-with-the-toolhive-mcp-optimizer-3oo6</guid>
      <description>&lt;p&gt;If you’ve ever hit a rate limit in your AI assistant or felt the sting of regret after checking your usage bill, you’re not alone. Whether you’re exploring an open source repo or triaging issues for a sprint, running into token walls is disruptive. It breaks your flow and burns your time and money.&lt;/p&gt;

&lt;p&gt;Turns out, there’s a hidden cost in many of today’s AI-enhanced dev workflows: &lt;strong&gt;tool metadata bloat&lt;/strong&gt;. When dozens (or hundreds) of tools get injected into each prompt, it drives up token usage and slows down responses. Input tokens aren’t free, and cluttering the context window with irrelevant content degrades model performance.&lt;/p&gt;

&lt;p&gt;At Stacklok, we’ve been working with the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; and discovered something surprising. A significant chunk of the tokens burned during AI coding sessions doesn’t come from your prompt, or even the code. It comes from tool descriptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Optimizer&lt;/strong&gt;, now available in ToolHive, tackles this problem at the root. It reduces token waste by acting as a smart broker between your AI assistant and MCP servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the waste comes from
&lt;/h2&gt;

&lt;p&gt;Let’s say you’ve installed MCP servers for GitHub, Grafana, and Notion. You ask your assistant:&lt;/p&gt;

&lt;p&gt;“List the 10 most recent issues from my GitHub repo.”&lt;/p&gt;

&lt;p&gt;That simple prompt uses &lt;strong&gt;102,000 tokens&lt;/strong&gt; &lt;em&gt;(total input &amp;amp; output)&lt;/em&gt;, not because the task is complex, but because the model receives metadata for &lt;strong&gt;114 tools&lt;/strong&gt;, most of which have nothing to do with the request.&lt;/p&gt;

&lt;p&gt;Other common prompts create similar waste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;“Summarize my meeting notes from October 19, 2025”&lt;br&gt;
uses &lt;strong&gt;240,600 tokens&lt;/strong&gt;, again with &lt;strong&gt;114 tools&lt;/strong&gt; injected, even though only the Notion server is relevant&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Search dashboards related to RDS”&lt;br&gt;
consumes &lt;strong&gt;93,600 tokens&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In each case, only a small fraction of those tokens are relevant to the task. Even saying “hello” burns more than 46,000 tokens.&lt;/p&gt;

&lt;p&gt;Multiply that across even a few dozen prompts per day, and you’re burning &lt;strong&gt;millions of tokens&lt;/strong&gt; on context the model doesn’t need. That’s not just expensive, it’s disruptive. In rate-limited enterprise environments or time-sensitive projects, this inefficiency slows down responses, breaks flow, and cuts directly into productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing MCP Optimizer: Smarter tool selection for leaner prompts
&lt;/h2&gt;

&lt;p&gt;Instead of flooding the model with all available tools, MCP Optimizer introduces two lightweight primitives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;find_tool&lt;/code&gt;: Searches for the most relevant tools using hybrid semantic + keyword search
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;call_tool&lt;/code&gt;: Routes the selected tool request to the appropriate MCP server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You send a prompt that requires tool assistance (for example, interacting with a GitHub repo)
&lt;/li&gt;
&lt;li&gt;The assistant calls &lt;code&gt;find_tool&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;MCP Optimizer returns the most relevant tools (up to 8 by default, but this is configurable)
&lt;/li&gt;
&lt;li&gt;Only those tools are included in the context
&lt;/li&gt;
&lt;li&gt;The assistant uses &lt;code&gt;call_tool&lt;/code&gt; to execute the task&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The results are dramatic. Using the GitHub, Grafana, and Notion MCP servers from the example above:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prompt&lt;/th&gt;
&lt;th&gt;MCP server used&lt;/th&gt;
&lt;th&gt;Without MCP Optimizer&lt;/th&gt;
&lt;th&gt;With MCP Optimizer&lt;/th&gt;
&lt;th&gt;Token reduction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hello&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Tokens*: 46.8k Tools sent: 114&lt;/td&gt;
&lt;td&gt;Tokens: 11.2k Tools sent: 3&lt;/td&gt;
&lt;td&gt;76%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List the latest 10 issues from the stacklok/toolhive repository.&lt;/td&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;Tokens: 102k Tools sent: 114&lt;/td&gt;
&lt;td&gt;Tokens: 32.4k Tools sent: 11&lt;/td&gt;
&lt;td&gt;68%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Summarize my meeting notes from Oct 19th 2025&lt;/td&gt;
&lt;td&gt;Notion&lt;/td&gt;
&lt;td&gt;Tokens: 240.6k Tools sent: 114&lt;/td&gt;
&lt;td&gt;Tokens: 86.8k Tools sent: 11&lt;/td&gt;
&lt;td&gt;64%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search the dashboards related to "RDS" in my Grafana workspace&lt;/td&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;Tokens: 93.6k Tools sent: 114&lt;/td&gt;
&lt;td&gt;Tokens: 13.7k Tools sent: 11&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;* Total input &amp;amp; output tokens for the request&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By sending only what’s needed, MCP Optimizer reduces total token usage, shortens response times, and prevents the assistant from thrashing through irrelevant tools.&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.amazonaws.com%2Fuploads%2Farticles%2Fy33zspy7ovfkbo418bx9.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.amazonaws.com%2Fuploads%2Farticles%2Fy33zspy7ovfkbo418bx9.png" alt="Bar chart comparing token usage before and after the MCP Optimizer" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No tokens wasted on excessive metadata. No LLMs spiraling as they try to reason through 100+ tools. Just fast, efficient execution.&lt;/p&gt;

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

&lt;p&gt;MCP Optimizer is available today as an experimental feature in the ToolHive desktop app. Here’s how to get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://toolhive.dev/download/" rel="noopener noreferrer"&gt;Download ToolHive&lt;/a&gt; for your platform.
&lt;/li&gt;
&lt;li&gt;Follow the &lt;a href="https://docs.stacklok.com/toolhive/tutorials/quickstart-ui" rel="noopener noreferrer"&gt;Quickstart guide&lt;/a&gt; and &lt;a href="https://docs.stacklok.com/toolhive/guides-mcp" rel="noopener noreferrer"&gt;MCP usage guides&lt;/a&gt; to install a few MCP servers into the &lt;code&gt;default&lt;/code&gt; group (or another group of your choice).
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Settings&lt;/strong&gt; (⚙️) screen, enable &lt;em&gt;MCP Optimizer&lt;/em&gt; under &lt;strong&gt;Experimental Features&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;On the &lt;strong&gt;MCP Servers&lt;/strong&gt; screen, click &lt;strong&gt;MCP Optimizer&lt;/strong&gt;, and enable optimization for the &lt;code&gt;default&lt;/code&gt; group.
&lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;default&lt;/code&gt; group and click &lt;strong&gt;Manage Clients&lt;/strong&gt; to connect your favorite AI client.
&lt;/li&gt;
&lt;li&gt;The optimizer discovers the MCP servers and tools in the default group, and ToolHive automatically connects your clients to the optimizer MCP server.
&lt;/li&gt;
&lt;li&gt;In your AI client, send prompts that require tool usage, like:
“Find a good first issue in the stacklok/toolhive repo to start working on.”&lt;/li&gt;
&lt;/ol&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.amazonaws.com%2Fuploads%2Farticles%2F6kscupkt4mga0zq52kqu.gif" 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.amazonaws.com%2Fuploads%2Farticles%2F6kscupkt4mga0zq52kqu.gif" alt=" " width="1328" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more, see the &lt;a href="https://docs.stacklok.com/toolhive/tutorials/mcp-optimizer" rel="noopener noreferrer"&gt;full tutorial&lt;/a&gt; in the ToolHive documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;We’re building ToolHive and MCP Optimizer in the open, and your feedback helps shape what comes next.&lt;/p&gt;

&lt;p&gt;Explore the project at &lt;a href="https://toolhive.dev" rel="noopener noreferrer"&gt;toolhive.dev&lt;/a&gt; and join our &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;community on Discord&lt;/a&gt; to share your experiences, suggest features, and help make tool-driven AI workflows faster, safer, and more developer-friendly.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>Examining the impact of npm supply chain attacks on MCP</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Thu, 18 Sep 2025 15:03:39 +0000</pubDate>
      <link>https://dev.to/stacklok/examining-the-impact-of-npm-supply-chain-attacks-on-mcp-edo</link>
      <guid>https://dev.to/stacklok/examining-the-impact-of-npm-supply-chain-attacks-on-mcp-edo</guid>
      <description>&lt;p&gt;Last week, a &lt;a href="https://www.aikido.dev/blog/npm-debug-and-chalk-packages-compromised" rel="noopener noreferrer"&gt;significant supply chain attack&lt;/a&gt; hit the JavaScript/TypeScript ecosystem through the npm registry. Multiple widely used packages, collectively downloaded more than 2 billion times per week, were compromised via a single maintainer’s npm account.&lt;/p&gt;

&lt;p&gt;Malicious versions of &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;chalk&lt;/code&gt;, &lt;code&gt;ansi-styles&lt;/code&gt;, and 15 other packages were published. The payload focused on stealing cryptocurrency wallets, but the incident underscored a broader, ongoing risk: the open source supply chain is a high-value target.&lt;/p&gt;

&lt;p&gt;And it didn’t stop there. This week, another campaign dubbed "Shai-Hulud" targeted additional npm packages, this time exfiltrating sensitive data and attempting self-propagation across the ecosystem.&lt;/p&gt;

&lt;p&gt;Plenty has already been written about these attacks. Here, I’ll focus on the impact on the Model Context Protocol (MCP) ecosystem. &lt;strong&gt;A quick scan of npm-based MCP servers showed that a significant percentage were at risk.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why were so many MCP servers exposed?
&lt;/h2&gt;

&lt;p&gt;The compromised packages are foundational in the JavaScript/TypeScript ecosystem. For MCP specifically, they are indirect dependencies of the official MCP TypeScript SDK. Any MCP server built from the SDK was therefore potentially vulnerable.&lt;/p&gt;

&lt;p&gt;Most JS/TS MCP servers are run by clients with &lt;code&gt;npx&lt;/code&gt;, which executes arbitrary commands from npm packages. During execution, all direct and transitive dependencies are pulled down to the local system. Unless wrapped in a Docker container, the server inherits the same access you have to your machine, networks, and data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should MCP users do?
&lt;/h2&gt;

&lt;p&gt;Fortunately, the malicious versions were quickly identified and removed, limiting downstream damage. But assume the worst and take proactive steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check and update the versions of MCP packages you use.
&lt;/li&gt;
&lt;li&gt;Clean your npm/npx cache (&lt;code&gt;npm cache clean --force&lt;/code&gt;) and restart your MCP clients.
&lt;/li&gt;
&lt;li&gt;Pin package versions instead of defaulting to &lt;code&gt;@latest&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Looking forward, apply the same discipline you would for any code you run locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep MCP servers up to date.
&lt;/li&gt;
&lt;li&gt;Prefer servers that are actively maintained.
&lt;/li&gt;
&lt;li&gt;Favor containerized MCP servers to limit their blast radius.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What should MCP server maintainers do?
&lt;/h2&gt;

&lt;p&gt;If you maintain an npm MCP server, rebuild and publish a fresh version, even if you don’t think you were affected. The cost is low, and it eliminates the chance that a malicious dependency slipped in during the attack window.&lt;/p&gt;

&lt;p&gt;Longer term, there are best practices every maintainer should follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audit dependencies regularly with &lt;code&gt;npm audit&lt;/code&gt; or similar tools.
&lt;/li&gt;
&lt;li&gt;Automate updates of direct and indirect dependencies with tools like Dependabot.
&lt;/li&gt;
&lt;li&gt;Pin direct dependency versions.

&lt;ul&gt;
&lt;li&gt;Be cautious: these attackers used patch releases, so even a narrow version range like &lt;code&gt;~1.2.3&lt;/code&gt; would have matched.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Check your lock file into version control so builds are reproducible.
&lt;/li&gt;

&lt;li&gt;Offer containerized builds of your MCP server.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  ToolHive: a secure approach to MCP
&lt;/h2&gt;

&lt;p&gt;At Stacklok, we’re working to secure MCP servers via our open source project, &lt;a href="https://toolhive.dev" rel="noopener noreferrer"&gt;ToolHive&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ve made deliberate choices in the design and development of ToolHive with security in mind. For example, one of our earliest architectural decisions was to &lt;strong&gt;require containerization for MCP servers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We re-package a curated set of MCP servers as container images in the ToolHive registry.  When we learned about this attack, we proactively rebuilt these images as soon as the malicious packages were removed from the npm registry. For third-party images in our registry, we use strict version pinning, ensuring users didn’t pull potentially vulnerable releases during the attack window.&lt;/p&gt;

&lt;p&gt;Containerization brings runtime consistency and portability, but more importantly, it limits exposure: a compromised MCP server is isolated from the rest of your system.&lt;/p&gt;

&lt;p&gt;ToolHive goes further by including network isolation. You can restrict outbound access so MCP servers only connect where they need to. Safe defaults are built into the registry. For example, the GitHub MCP server can be protected with a single &lt;a href="https://docs.stacklok.com/toolhive/guides-cli/network-isolation" rel="noopener noreferrer"&gt;CLI flag&lt;/a&gt; or &lt;a href="https://docs.stacklok.com/toolhive/guides-ui/network-isolation" rel="noopener noreferrer"&gt;UI toggle&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thv run --isolate-network github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fjs86owpyk0a51uoq8fnd.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.amazonaws.com%2Fuploads%2Farticles%2Fjs86owpyk0a51uoq8fnd.png" alt="Network isolation configuration in the ToolHive UI" width="800" height="755"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The npm supply chain attack of September 8, 2025 reached deep into the MCP ecosystem. The actual impact depended on how servers were developed and deployed. Container isolation, and especially when combined with network isolation, proved to be an effective defense.&lt;/p&gt;

&lt;p&gt;This isn’t about a single tool. It’s a reminder that security has to be baked into how we develop and run software. Supply chain attacks will continue to evolve. Our practices must evolve faster.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>npm</category>
      <category>security</category>
      <category>containers</category>
    </item>
    <item>
      <title>How to secure MCP servers with Vault + ToolHive in Kubernetes</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Wed, 17 Sep 2025 18:31:48 +0000</pubDate>
      <link>https://dev.to/stacklok/how-to-secure-mcp-servers-with-vault-toolhive-in-kubernetes-3b0m</link>
      <guid>https://dev.to/stacklok/how-to-secure-mcp-servers-with-vault-toolhive-in-kubernetes-3b0m</guid>
      <description>&lt;p&gt;Running MCP servers in Kubernetes often means dealing with the headache of managing secrets. Hardcoding them? Too risky. Mounting them directly? Too messy.&lt;/p&gt;

&lt;p&gt;That’s where &lt;a href="https://docs.stacklok.com/toolhive/tutorials/vault-integration" rel="noopener noreferrer"&gt;ToolHive’s Vault integration tutorial&lt;/a&gt; comes in. It shows you how to use HashiCorp Vault to provide secure, controlled access to secrets for MCP servers, without exposing more than you should.&lt;/p&gt;

&lt;p&gt;We also put together a short video demo to walk you through it:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/DvlsShJNhpo"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you’re running Kubernetes and want to simplify how your MCP servers access secrets, ToolHive and Vault help you get there faster.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>kubernetes</category>
      <category>security</category>
    </item>
    <item>
      <title>Who are your MCP servers talking to?</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Thu, 26 Jun 2025 15:25:58 +0000</pubDate>
      <link>https://dev.to/stacklok/who-are-your-mcp-servers-talking-to-1m5e</link>
      <guid>https://dev.to/stacklok/who-are-your-mcp-servers-talking-to-1m5e</guid>
      <description>&lt;p&gt;You probably know who you &lt;em&gt;think&lt;/em&gt; they should be talking to, but how do you know for sure? And how do you keep it that way?&lt;/p&gt;

&lt;p&gt;Modern AI workflows rely on agentic systems that leverage Model Context Protocol (MCP) servers. These servers provide rich context to LLMs, enabling smarter, safer, and more customized behavior. But if you’re not controlling their network access, you’re trusting that these tools won’t spill secrets, phone home, or tunnel into places they shouldn’t.&lt;/p&gt;

&lt;p&gt;With the new network isolation features in &lt;a href="https://github.com/stacklok/toolhive" rel="noopener noreferrer"&gt;ToolHive&lt;/a&gt;, you don’t have to trust. You can verify – and enforce.&lt;/p&gt;




&lt;p&gt;Let’s prove the point with a quick test.&lt;/p&gt;

&lt;p&gt;I gave the Fetch MCP server a very strict permission profile: it could only connect to stacklok.com and nothing else. Then I used Copilot to fetch content from both stacklok.com and anthropic.com.&lt;/p&gt;

&lt;p&gt;Here’s what happened:&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.amazonaws.com%2Fuploads%2Farticles%2Fehcyd42973wu272ssn4g.webp" 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.amazonaws.com%2Fuploads%2Farticles%2Fehcyd42973wu272ssn4g.webp" alt="A screenshot of Copilot in VS Code failing to retrieve a website that isn't allowed" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the audit trail from the egress proxy that ToolHive spun up for me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker logs fetch-egress

1750875295.189    449 172.20.0.4 TCP_TUNNEL/200 10451 CONNECT stacklok.com:443 - HIER_DIRECT/5.161.48.178 -
1750875314.012      0 172.20.0.4 TCP_DENIED/403 3786 CONNECT www.anthropic.com:443 - HIER_NONE/- text/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Allowed&lt;/strong&gt;: stacklok.com&lt;/p&gt;

&lt;p&gt;⛔ &lt;strong&gt;Blocked&lt;/strong&gt;: anthropic.com&lt;/p&gt;

&lt;p&gt;That’s real-time enforcement of network policy, with a full audit trail. No special infrastructure required.&lt;/p&gt;

&lt;p&gt;Let’s look at why this matters, and how you can do it yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why network isolation matters
&lt;/h2&gt;

&lt;p&gt;Containerization is a great start for security, but it’s not a silver bullet. A malicious MCP server could still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exfiltrate proprietary data or credentials&lt;/li&gt;
&lt;li&gt;Leak sensitive API access to an unknown endpoint&lt;/li&gt;
&lt;li&gt;Become a pivot point for lateral movement within your network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The attack surface expands when containers are able to download unverified tools, or when a once-trusted MCP gets silently updated with malicious code. These aren’t theoretical risks, they’ve already shown up in detailed &lt;a href="https://www.catonetworks.com/blog/cato-ctrl-exploiting-model-context-protocol-mcp/" rel="noopener noreferrer"&gt;proof of concept research&lt;/a&gt;. Even legitimate MCP servers can be manipulated to devious ends through prompt injection and other techniques, like this &lt;a href="https://invariantlabs.ai/blog/whatsapp-mcp-exploited" rel="noopener noreferrer"&gt;exploitation of the WhatsApp MCP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That’s why ToolHive lets you explicitly define where each MCP can connect, and just as importantly, where it can’t.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to lock it down
&lt;/h2&gt;

&lt;p&gt;ToolHive’s permission profiles let you precisely define network rules for each MCP server. Here’s a quick walkthrough of some common use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: Allow only internal domains
&lt;/h3&gt;

&lt;p&gt;Suppose you want to restrict the Fetch MCP server to only talk to your local system, internal corporate services, and your tenant in Atlassian Cloud:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;fetch-permissions.json&lt;/strong&gt;&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;"network"&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;"outbound"&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;"allow_host"&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="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;".acmecorp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"acmecorp.atlassian.net"&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;"allow_port"&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="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"insecure_allow_all"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the syntax of the &lt;code&gt;.acmecorp.com&lt;/code&gt; entry. The leading &lt;code&gt;.&lt;/code&gt; permits all subdomains below the main domain.&lt;/p&gt;

&lt;p&gt;Then, simply launch the Fetch server with the &lt;code&gt;--isolate-network&lt;/code&gt; flag and your custom permission profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thv run &lt;span class="nt"&gt;--isolate-network&lt;/span&gt; &lt;span class="nt"&gt;--permission-profile&lt;/span&gt; ./fetch-permissions.json fetch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2: Use default registry permissions
&lt;/h3&gt;

&lt;p&gt;Some MCPs ship with default profiles in the built-in ToolHive registry. Want to run the GitHub MCP as-is?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thv run &lt;span class="nt"&gt;--isolate-network&lt;/span&gt; github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can inspect its default permissions first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thv registry info github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Permissions section reveals the default policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Permissions:
  Network:
    Allow Host: .github.com, .githubusercontent.com
    Allow Port: 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 3: Customize for GitHub Enterprise
&lt;/h3&gt;

&lt;p&gt;If you self-host GitHub, tweak the permission profile to replace the &lt;code&gt;allow_host&lt;/code&gt; list with your internal name:&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;"network"&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;"outbound"&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;"allow_host"&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;"github.example.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"allow_port"&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="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"insecure_allow_all"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run with your custom profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thv run &lt;span class="nt"&gt;--isolate-network&lt;/span&gt; &lt;span class="nt"&gt;--permission-profile&lt;/span&gt; ./github-enterprise.json github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 4: Block all network access
&lt;/h3&gt;

&lt;p&gt;Need to sandbox an MCP completely? Use the built-in "none" profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thv run &lt;span class="nt"&gt;--isolate-network&lt;/span&gt; &lt;span class="nt"&gt;--permission-profile&lt;/span&gt; none &amp;lt;MCP_SERVER&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Behind the scenes, ToolHive runs each MCP server inside a locked-down container within that routes egress traffic through a layer 7 HTTP proxy. That proxy enforces the rules you define in your permission profile.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block access entirely&lt;/li&gt;
&lt;li&gt;Allow specific domains, IPs, and ports&lt;/li&gt;
&lt;li&gt;Monitor attempted connections using logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s simple to apply and doesn’t require you to manage iptables, Squid rules, write sidecar policies, or wrangle your own container network routing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pro tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don’t know what to allow?&lt;/strong&gt; Start with &lt;code&gt;--permission-profile none&lt;/code&gt; and check the logs for denied requests.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  docker logs &amp;lt;mcp-name&amp;gt;-egress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Need auditability more than isolation?&lt;/strong&gt; Set &lt;code&gt;"insecure_allow_all": true&lt;/code&gt; in your profile and run with &lt;code&gt;--isolate-network&lt;/code&gt; to log everything without blocking. Currently, the proxy logs are ephemeral inside the egress container, but if you’d like to see a persistence option please let us know via a &lt;a href="https://github.com/stacklok/toolhive/issues/new/choose" rel="noopener noreferrer"&gt;GitHub issue&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Safer defaults, smarter agents
&lt;/h2&gt;

&lt;p&gt;As AI tooling becomes more agentic — running background tasks, accessing services, and making autonomous decisions — you’ll need guardrails that match the autonomy. Network isolation is one of the simplest, most powerful controls you can put in place.&lt;/p&gt;

&lt;p&gt;Ready to take control of your MCP network surface?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 &lt;a href="https://docs.stacklok.com/toolhive/quickstart" rel="noopener noreferrer"&gt;Follow the quickstart guide&lt;/a&gt; to get up and running fast&lt;/li&gt;
&lt;li&gt;📄 Learn more about network isolation in the &lt;a href="https://docs.stacklok.com/toolhive/guides-cli/custom-permissions" rel="noopener noreferrer"&gt;custom permissions guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/stacklok/toolhive" rel="noopener noreferrer"&gt;Check out ToolHive on GitHub&lt;/a&gt; to explore the code and contribute&lt;/li&gt;
&lt;li&gt;💬 &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;Join the Stacklok Discord&lt;/a&gt; to get support, ask questions, or share your feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Build smarter, safer AI workflows, one locked-down container at a time.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Easy and secure MCP servers, now on Windows</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Thu, 05 Jun 2025 15:00:00 +0000</pubDate>
      <link>https://dev.to/stacklok/easy-and-secure-mcp-servers-now-on-windows-56j6</link>
      <guid>https://dev.to/stacklok/easy-and-secure-mcp-servers-now-on-windows-56j6</guid>
      <description>&lt;p&gt;ToolHive v0.0.39 is here, and it comes with a big update for developers: &lt;strong&gt;native Windows support&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Previously, ToolHive worked great on macOS and Linux. But if you develop on Windows, your only option was WSL. That got the job done, but it came with limitations, especially around client auto-configuration. Now with native support, you get the full experience, including seamless integration with VS Code, Cursor, and other supported tools.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/stacklok/toolhive" rel="noopener noreferrer"&gt;ToolHive&lt;/a&gt; makes it easy and secure to run Model Context Protocol (MCP) servers. It wraps any MCP server in a lightweight, locked-down container, taking care of orchestration, security, and client configuration so you can focus on building.&lt;/p&gt;

&lt;p&gt;With ToolHive, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easily discover high-quality MCP servers through the built-in registry
&lt;/li&gt;
&lt;li&gt;Spin up an MCP server with a single &lt;code&gt;thv run&lt;/code&gt; command using Docker or Podman under the hood
&lt;/li&gt;
&lt;li&gt;Securely pass secrets and mount volumes
&lt;/li&gt;
&lt;li&gt;Automatically configure clients like GitHub Copilot in VS Code, Cursor, Cline, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ToolHive isn't just for individual developer workstations, it's also designed with long-term scale and security in mind. Features like Kubernetes integration and support for OAuth-based client auth lay the groundwork for more robust, team-ready deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s new in v0.0.39 and why it matters
&lt;/h2&gt;

&lt;p&gt;With this release, ToolHive offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First-class support for native Windows environments. You now have access to the full ToolHive experience. That includes the automatic configuration of clients, one of the major reasons developers love ToolHive. No more digging through docs or &lt;code&gt;.json&lt;/code&gt; settings to wire things up manually.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Full client auto-discovery and integration&lt;/strong&gt; on Windows for supported tools. Auto-discovery means ToolHive can automatically register new MCP servers with your tools as soon as they start. This was previously only possible on macOS and Linux, but no longer!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This release also underscores a broader commitment: &lt;strong&gt;ToolHive should feel like it belongs on your platform&lt;/strong&gt;, whether you’re using it for a single MCP server or managing a fleet across a team.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to install it
&lt;/h2&gt;

&lt;p&gt;The only prerequisite is to have Docker Desktop or Podman Desktop installed and running on your system. To install the ToolHive CLI, you’ve got three options:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use WinGet
&lt;/h3&gt;

&lt;p&gt;WinGet is built into all current versions of Windows 10 and 11 and is the easiest way to install ToolHive. Just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;winget &lt;span class="nb"&gt;install &lt;/span&gt;stacklok.thv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Download the prebuilt &lt;code&gt;.exe&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Head over to the &lt;a href="https://github.com/stacklok/toolhive/releases" rel="noopener noreferrer"&gt;ToolHive GitHub releases page&lt;/a&gt; and grab the latest Windows binary. Extract the ZIP, move it somewhere in your &lt;code&gt;PATH&lt;/code&gt;, and you’re ready to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Build from source
&lt;/h3&gt;

&lt;p&gt;Have Go 1.24 installed? Then you can build ToolHive yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/stacklok/toolhive.git
&lt;span class="nb"&gt;cd &lt;/span&gt;toolhive

go &lt;span class="nb"&gt;install&lt;/span&gt; .&lt;span class="se"&gt;\c&lt;/span&gt;md&lt;span class="se"&gt;\t&lt;/span&gt;hv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ready to get started?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check out the &lt;a href="https://github.com/stacklok/toolhive" rel="noopener noreferrer"&gt;ToolHive repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join the &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;Stacklok Discord&lt;/a&gt; to ask questions or share feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re always looking to make ToolHive more powerful, more secure, and more developer-friendly. This release is one small step for cross-platform support, one giant leap for better context-aware development. 🚀&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Rewriting an old app with AI: a reality check</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Fri, 28 Mar 2025 17:05:37 +0000</pubDate>
      <link>https://dev.to/stacklok/rewriting-an-old-app-with-ai-a-reality-check-2dma</link>
      <guid>https://dev.to/stacklok/rewriting-an-old-app-with-ai-a-reality-check-2dma</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AI coding tools and the LLMs that drive them can be powerful, but they’re not security-aware by default.&lt;/li&gt;
&lt;li&gt;Outdated packages and insecure practices can creep in. Don’t assume LLMs "just know."&lt;/li&gt;
&lt;li&gt;Clear, specific prompts matter more than you think.&lt;/li&gt;
&lt;li&gt;Don’t skip automated linters, SAST/DAST tools, or dependency checkers. AI doesn’t replace them.&lt;/li&gt;
&lt;li&gt;Code review still matters. A lot.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Throughout my career, I’ve brought a healthy skepticism to the hype that comes with each new wave of technology, and AI code generation is no different. Even now, working at a company building tools to improve security and productivity for AI-assisted developers, I’ve had my doubts. Can LLMs actually produce high-quality, secure code? Can they be trusted with real-world applications, especially for people like me who aren't full-time developers?&lt;/p&gt;

&lt;p&gt;That skepticism shapes how I've approached my exploration of these tools. I’m not just curious about what they can do out of the box, I want to understand how to use them &lt;em&gt;effectively&lt;/em&gt;. Where do AI coding assistants and LLMs genuinely help? Where do they fall short? And how can we guide them to get better results?&lt;/p&gt;

&lt;p&gt;It quickly became clear that AI can help write code but doesn’t take on responsibility for it. That still falls on us, especially when it comes to keeping things secure. LLMs don’t “just get it.” You're still responsible for ensuring the code you deploy is secure, even if an AI writes it. "Vibe coding" with an AI won’t save you when it generates an insecure login page or uses deprecated packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  A real-world experiment
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;For context: I have a computer science degree and spent time as a developer early in my career. I quickly pivoted into infrastructure, where I focused heavily on automation, and now work in technical marketing with a recent focus on AI assisted coding. I’ve kept my foundational understanding of app structure and security risks, but I relied on AI tools here both to teach myself how to work with them and to fill in the gaps in my Python knowledge.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently dusted off a very old PHP-based web app. It’s a small tool for checking in attendees at community meetups, printing name badges, and picking winners for door prizes. Not mission-critical by any means, but I was curious how an LLM like Claude could help modernize it.&lt;/p&gt;

&lt;p&gt;So I used &lt;a href="https://cline.bot/" rel="noopener noreferrer"&gt;Cline&lt;/a&gt; and asked Claude 3.7 Sonnet to rebuild it in Python/Django. A few prompts and iterations later, I had a working app. Victory, right?&lt;/p&gt;

&lt;p&gt;Not quite.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problems
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Old versions&lt;/strong&gt;: Claude defaulted to Django 4, even though Django 5 was released well before its knowledge cutoff. Claude probably made this choice because most public examples during its training were still based on Django 4. LLMs generate code based on what they’ve seen most often, not necessarily what’s most current. I had to explicitly ask for Django 5 before it even considered using it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Outdated dependencies&lt;/strong&gt;: Most of the libraries it picked were outdated (by years in some cases) even within the model’s supposed knowledge window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Password security fail&lt;/strong&gt;: For the admin login, Claude implemented MD5 hashing for password storage. In 2025. Yikes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OWASP Top 10? Nope&lt;/strong&gt;: When I asked it to review its own code against the &lt;a href="https://owasp.org/Top10/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt;, it found glaring issues: insecure cookies, XSS risks, poor session handling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These weren’t edge cases or niche scenarios. They were textbook mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I took away
&lt;/h3&gt;

&lt;p&gt;This experience clarified a few things for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prompt engineering really matters.&lt;/strong&gt; If I had started by specifying what versions to use, which tools to integrate, and what security standards to follow, I would have gotten better results. Instead, I gave a casual, open-ended prompt and got casual, open-ended code in return.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security tooling is essential.&lt;/strong&gt; Arguably even more so with AI-assisted workflows. Using an LLM to generate code doesn't reduce the need for linters, scanners, or security checks; it makes them more critical. Tools like &lt;code&gt;pylint&lt;/code&gt;, &lt;code&gt;bandit&lt;/code&gt;, and &lt;code&gt;trivy&lt;/code&gt; help with dependency and security scanning. Guidance from resources like the OWASP Top 10 rounds out the picture. These aren’t optional, they're lifelines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code review is still critical.&lt;/strong&gt; Just because it compiles and works doesn’t mean it’s good. Experience helps you see what automated tools (including LLMs) don’t.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A checklist for safer AI coding
&lt;/h3&gt;

&lt;p&gt;If you’re using AI to help write or refactor apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Be specific&lt;/strong&gt;: Name your preferred versions, frameworks, and security practices in the prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break it into smaller pieces&lt;/strong&gt;: For migration projects, split the codebase into manageable units (DB, business logic, API, etc.) and prompt the AI layer-by-layer. This reduces context overload and makes review easier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate review&lt;/strong&gt;: Use linters, SAST/DAST tools, and SBOM scanners in your CI/CD pipeline. Don’t ship without them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t skip human review&lt;/strong&gt;: Nothing replaces experienced eyes on code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Final thought
&lt;/h3&gt;

&lt;p&gt;AI-assisted development is powerful, but it’s not magic. It still requires thoughtfulness, review, and good security hygiene. LLMs can save time writing and reviewing code, but that time savings can quickly disappear if you’re cleaning up after a security incident. A little extra effort up front is still the best defense against costly surprises later.&lt;/p&gt;

&lt;p&gt;If you've tried AI coding tools, what surprises or pitfalls have you run into? Let me know in the comments.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
      <category>security</category>
    </item>
    <item>
      <title>Augment Cline and your LLM with up-to-date risk insight using CodeGate</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Thu, 30 Jan 2025 16:25:04 +0000</pubDate>
      <link>https://dev.to/stacklok/give-cline-a-control-boost-with-codegate-1am8</link>
      <guid>https://dev.to/stacklok/give-cline-a-control-boost-with-codegate-1am8</guid>
      <description>&lt;p&gt;The CodeGate team has landed &lt;em&gt;another&lt;/em&gt; integration! 🚀 We're thrilled to announce that CodeGate now supports &lt;a href="https://cline.bot" rel="noopener noreferrer"&gt;Cline&lt;/a&gt;, the popular autonomous coding assistant for VS Code!&lt;/p&gt;

&lt;p&gt;Consider this: what happens when Cline communicates with an LLM that hasn't been updated in months? It might suggest using outdated libraries or ignore potential security threats lurking in new dependencies. And since Cline works with your entire codebase and human error is inevitable, a slip-up could expose sensitive information like API keys and put your projects at risk.&lt;/p&gt;

&lt;p&gt;Enter CodeGate, the perfect complement to Cline's agentic workflow and autonomous coding abilities. By integrating CodeGate with Cline, you're adding an extra layer of protection to your development process. CodeGate keeps your secrets local so that sensitive information like API keys remain secure within your environment. It also examines dependencies for potential risks, using its up-to-date knowledge to warn you about malicious packages or outdated libraries, and guides the LLM to safer alternatives.&lt;/p&gt;

&lt;p&gt;CodeGate is a free and open source gateway, shipped as a single Docker container, that works behind the scenes to analyze every interaction between Cline and your LLM. CodeGate has your back, so you can let Cline manage your coding tasks with confidence.&lt;/p&gt;

&lt;p&gt;Check out the demo to see how it works.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/B3izVWVclIg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Learn more about CodeGate on &lt;a href="https://github.com/stacklok/codegate" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, check out the &lt;a href="https://docs.codegate.ai" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started, and join us on &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cline</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Give aider a privacy and security boost with CodeGate</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Fri, 24 Jan 2025 18:16:21 +0000</pubDate>
      <link>https://dev.to/stacklok/give-aider-a-privacy-and-security-boost-with-codegate-1n2h</link>
      <guid>https://dev.to/stacklok/give-aider-a-privacy-and-security-boost-with-codegate-1n2h</guid>
      <description>&lt;p&gt;We know you love &lt;a href="https://aider.chat" rel="noopener noreferrer"&gt;aider&lt;/a&gt;...how it works right from your terminal, understands your codebase, and its automated Git commits.&lt;/p&gt;

&lt;p&gt;But what happens when aider talks to an LLM that was trained many months ago and doesn't know about the latest risky dependencies and malicious packages? Or when you accidentally let an API key slip into your code and it gets shared with OpenAI?&lt;/p&gt;

&lt;p&gt;Now, you can pair aider with CodeGate to give your favorite AI pair programmer a privacy and security boost! Using CodeGate with aider keeps your secrets local, your dependencies secure, and your projects safe from vulnerabilities.&lt;/p&gt;

&lt;p&gt;Check it out in this demo video:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/VxvEXiwEGnA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Aider + CodeGate: better together!&lt;/p&gt;

&lt;p&gt;Learn more about CodeGate on the &lt;a href="https://codegate.ai" rel="noopener noreferrer"&gt;website&lt;/a&gt;, check out the &lt;a href="https://docs.codegate.ai" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started, and join us on &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aider</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Avoid risky dependencies in AI generated code</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Wed, 22 Jan 2025 22:37:29 +0000</pubDate>
      <link>https://dev.to/stacklok/avoid-risky-dependencies-in-ai-generated-code-1ajk</link>
      <guid>https://dev.to/stacklok/avoid-risky-dependencies-in-ai-generated-code-1ajk</guid>
      <description>&lt;p&gt;The LLMs that power your favorite AI coding assistants like GitHub Copilot or Continue take a lot of time and money to train, so they're not working with up-to-date knowledge. In fact, their knowledge cutoff dates are often 12-18 months in the past.&lt;/p&gt;

&lt;p&gt;That means they don't know anything about the latest threats in the open source package ecosystem, like malicious packages. They also don't know which projects have been deprecated or archived since they were trained.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codegate.ai" rel="noopener noreferrer"&gt;CodeGate&lt;/a&gt; augments your LLM's knowledge with an up-to-date database of risky packages in five popular ecosystems (PyPI, npm, golang.org, crates.io, and Maven), powered by &lt;a href="https://insight.stacklok.com" rel="noopener noreferrer"&gt;Stacklok Insight&lt;/a&gt;. CodeGate is a new open source project from Stacklok that runs locally to protect your privacy and security while you use AI coding tools.&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.amazonaws.com%2Fuploads%2Farticles%2Fvdnvhl44kh79g00ot1dr.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.amazonaws.com%2Fuploads%2Farticles%2Fvdnvhl44kh79g00ot1dr.png" alt="Diagram of CodeGate checking for risky dependencies between an AI assistant and the LLM" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this video, see how CodeGate automatically protects you from malicious or deprecated dependencies without changing how you work with your AI coding assistant.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/WimBevc_Ji0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Learn more about CodeGate on the &lt;a href="https://codegate.ai" rel="noopener noreferrer"&gt;website&lt;/a&gt;, check out the &lt;a href="https://docs.codegate.ai" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started, and join us on &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>supplychain</category>
      <category>security</category>
    </item>
    <item>
      <title>Stop AI coding assistants from leaking your secrets</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Thu, 16 Jan 2025 16:28:57 +0000</pubDate>
      <link>https://dev.to/stacklok/stop-ai-coding-assistants-from-leaking-your-secrets-2mm9</link>
      <guid>https://dev.to/stacklok/stop-ai-coding-assistants-from-leaking-your-secrets-2mm9</guid>
      <description>&lt;p&gt;You're careful not to let your secrets wind up in source code. You use &lt;code&gt;.gitignore&lt;/code&gt; files. You scan for secrets with TruffleHog and turn on GitHub's push protection. But despite all this, chances are your AI coding assistant is sharing your secrets with a large language model (LLM) in the cloud. 😱&lt;/p&gt;

&lt;p&gt;That's where &lt;a href="https://codegate.ai" rel="noopener noreferrer"&gt;CodeGate&lt;/a&gt; comes in. CodeGate is a new open source project from Stacklok that runs locally to protect your privacy and security as you use AI coding tools.&lt;/p&gt;

&lt;p&gt;In this feature spotlight video, I show you how CodeGate encrypts your secrets &lt;em&gt;before&lt;/em&gt; they are sent to an LLM, without changing how you interact with your AI coding assistant.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/lH0o7korRPg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Learn more about CodeGate on the &lt;a href="https://codegate.ai" rel="noopener noreferrer"&gt;website&lt;/a&gt;, check out the &lt;a href="https://docs.codegate.ai" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started, and join us on &lt;a href="https://discord.gg/stacklok" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Your dependencies have dependencies: new features to assess risk</title>
      <dc:creator>Dan Barr</dc:creator>
      <pubDate>Tue, 12 Nov 2024 21:12:50 +0000</pubDate>
      <link>https://dev.to/stacklok/your-dependencies-have-dependencies-new-features-to-assess-risk-3f1b</link>
      <guid>https://dev.to/stacklok/your-dependencies-have-dependencies-new-features-to-assess-risk-3f1b</guid>
      <description>&lt;p&gt;Stacklok has just rolled out some major updates to &lt;a href="https://www.trustypkg.dev" rel="noopener noreferrer"&gt;Trusty&lt;/a&gt;, our free-to-use service that helps developers assess dependency risk in open source packages. These new features are designed to help you make informed decisions about the software dependencies you bring into your projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transitive dependency analysis
&lt;/h2&gt;

&lt;p&gt;The open source ecosystem is a complex web of interdependencies and relationships. When you’re picking the right packages to use in your project, assessing them for risk is a great way to make your project more secure. But the first layer of dependencies only scratches the surface. Your dependencies have dependencies, and so do those, and so on -- it's &lt;del&gt;turtles&lt;/del&gt; dependencies all the way down. Those indirect dependencies further down the tree might bring hidden vulnerabilities or license compliance risks that aren't immediately obvious.&lt;/p&gt;

&lt;p&gt;Trusty now ingests and analyzes transitive dependencies to help you understand the full scope of your dependency tree. For each package version, Trusty crawls the dependency tree to identify the package's direct and indirect dependencies. Along with the list of downstream packages, Trusty surfaces key risk indicators, license information, and activity scores to help you understand the full scope of potential security and health risks lurking deep within your dependency chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refreshed UI and security signals
&lt;/h2&gt;

&lt;p&gt;The Trusty web interface has a fresh new look, highlighting more intuitive security signals and activity scores. Our goal is to make it easier to quickly assess health and security signals and to help you make a decision based on the risk and activity signals that matter most to you.&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.amazonaws.com%2Fuploads%2Farticles%2Fb2ql259417q8j4ism4tc.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.amazonaws.com%2Fuploads%2Farticles%2Fb2ql259417q8j4ism4tc.png" alt="Screenshot of the Trusty package details interface" width="800" height="844"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And for those who prefer to walk on the dark side, Trusty now fully supports dark mode. 😎 &lt;/p&gt;

&lt;p&gt;Check out an overview of the new UI in the docs: &lt;a href="https://docs.stacklok.com/trusty/how-to/package-overview/" rel="noopener noreferrer"&gt;https://docs.stacklok.com/trusty/how-to/package-overview/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New API version
&lt;/h2&gt;

&lt;p&gt;Of course, the best way to use Trusty is to integrate it directly into your development flow. Version 2 of the Trusty API is now available with new and updated endpoints supporting the latest scoring updates and features like transitive dependencies. You can check out the new and improved API docs here: &lt;a href="https://docs.stacklok.com/trusty/ref/api/" rel="noopener noreferrer"&gt;https://docs.stacklok.com/trusty/ref/api/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The quickest way to get started with automating Trusty is the &lt;a href="https://mindersec.github.io/integrations/trusty" rel="noopener noreferrer"&gt;integration with Minder&lt;/a&gt;, the open-source software supply chain automation tool that Stacklok &lt;a href="https://dev.to/stacklok/contributing-minder-to-the-openssf-out-of-a-deep-belief-in-the-power-of-the-open-source-community-1k48"&gt;recently donated to the OpenSSF&lt;/a&gt;. And check out &lt;a href="https://cloud.stacklok.com" rel="noopener noreferrer"&gt;Stacklok Cloud&lt;/a&gt;, our fully managed public SaaS instance of Minder that is free to use with public repositories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let us know what you think
&lt;/h2&gt;

&lt;p&gt;At Stacklok, we’re committed to helping all developers navigate the complex world of open source dependencies and build more secure software. Check out Trusty today at &lt;a href="https://trustypkg.dev" rel="noopener noreferrer"&gt;https://trustypkg.dev&lt;/a&gt; to start understanding your software supply chain risk.&lt;/p&gt;

&lt;p&gt;As always, we're eager to hear your feedback. Leave a comment below, and join us in the &lt;a href="https://discord.com/invite/RkzVuTp3WK" rel="noopener noreferrer"&gt;Stacklok community Discord&lt;/a&gt; to chat about the updates, package scoring, and software supply chain in general!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>security</category>
      <category>supplychain</category>
      <category>news</category>
    </item>
  </channel>
</rss>
