<?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: Qaiser Mehmood</title>
    <description>The latest articles on DEV Community by Qaiser Mehmood (@qmmughal).</description>
    <link>https://dev.to/qmmughal</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%2F4047580%2F39b0e16e-a935-4149-bb7e-c8e168134692.jpg</url>
      <title>DEV Community: Qaiser Mehmood</title>
      <link>https://dev.to/qmmughal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qmmughal"/>
    <language>en</language>
    <item>
      <title>Building MCP servers for Claude &amp; Cursor? Here's a starting point.</title>
      <dc:creator>Qaiser Mehmood</dc:creator>
      <pubDate>Sun, 26 Jul 2026 06:21:09 +0000</pubDate>
      <link>https://dev.to/qmmughal/building-mcp-servers-for-claude-cursor-heres-a-starting-point-2flm</link>
      <guid>https://dev.to/qmmughal/building-mcp-servers-for-claude-cursor-heres-a-starting-point-2flm</guid>
      <description>&lt;p&gt;Most MCP servers I see in the wild start as a quick script and stay that way — no validation, no structured logging, no tests, and a deploy story that means shipping node_modules around.&lt;/p&gt;

&lt;p&gt;I got tired of rebuilding the same scaffolding every time a client project needed a Model Context Protocol server, so I open-sourced the template I now start every one from: 🚀 mcp-server-template&lt;/p&gt;

&lt;p&gt;It's a production-ready TypeScript/Node.js foundation for building MCP servers that connect AI agents like Claude Desktop and Cursor to your tools, data, and workflows.&lt;/p&gt;

&lt;p&gt;𝗚𝗲𝘁𝘁𝗶𝗻𝗴 𝘀𝘁𝗮𝗿𝘁𝗲𝗱 𝘁𝗮𝗸𝗲𝘀 𝗳𝗼𝘂𝗿 𝗰𝗼𝗺𝗺𝗮𝗻𝗱𝘀:&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/qmmughal/mcp-server-template.git
&lt;span class="nb"&gt;cd &lt;/span&gt;mcp-server-template &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That spins up a working server in watch mode. npm test runs the Vitest suite, npm run build bundles everything into a single dist/index.js with esbuild — no node_modules to deploy.&lt;/p&gt;

&lt;p&gt;𝗪𝗵𝗮𝘁 𝗮 𝘁𝗼𝗼𝗹 𝗮𝗰𝘁𝘂𝗮𝗹𝗹𝘆 𝗹𝗼𝗼𝗸𝘀 𝗹𝗶𝗸𝗲:&lt;/p&gt;

&lt;p&gt;Every tool gets a Zod schema, a definition, and a handler — so a malformed AI payload gets rejected with a clean error instead of crashing your process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The text to process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleExampleTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExampleService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;withErrorHandling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;process_text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;repeat&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;processText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;𝗘𝘅𝘁𝗲𝗻𝗱𝗶𝗻𝗴 𝗶𝘁 𝗳𝗼𝗿 𝘆𝗼𝘂𝗿 𝗼𝘄𝗻 𝘁𝗼𝗼𝗹𝘀:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Drop a new file in src/tools/ following the same schema → definition → handler shape&lt;/li&gt;
&lt;li&gt;Register it in src/tools/index.ts — add your definition to the tools list and a case to the switch statement that routes CallToolRequest to your handler&lt;/li&gt;
&lt;li&gt;Put your real logic in src/services/ so the protocol layer stays thin and your business logic stays unit-testable in isolation&lt;/li&gt;
&lt;li&gt;Resources (data the AI can read) and Prompts (reusable templates) follow the exact same pattern in their own folders — copy the example, rename, adjust the schema&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Structured pino logging routes safely to stderr throughout, so it never corrupts the MCP stdio transport regardless of what you add.&lt;/p&gt;

&lt;p&gt;When you're ready to ship, tag a release and a GitHub Actions workflow publishes to both npm and the MCP Registry automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0.0 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git push origin v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is simple — spend your time on the logic that makes your MCP server useful, not on re-solving logging, validation, and bundling for the fifth time.&lt;/p&gt;

&lt;p&gt;It's MIT licensed and live on GitHub now. If you're building agentic AI integrations, I'd love feedback or a star:&lt;/p&gt;

&lt;p&gt;🔗 github.com/qmmughal/mcp-server-template&lt;/p&gt;

&lt;h1&gt;
  
  
  MCP #ModelContextProtocol #AgenticAI #TypeScript #OpenSource #AIEngineering #ClaudeAI
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
    <item>
      <title>AgentWire: Wireshark for the Agentic Stack</title>
      <dc:creator>Qaiser Mehmood</dc:creator>
      <pubDate>Sun, 26 Jul 2026 06:07:46 +0000</pubDate>
      <link>https://dev.to/qmmughal/agentwire-wireshark-for-the-agentic-stack-2653</link>
      <guid>https://dev.to/qmmughal/agentwire-wireshark-for-the-agentic-stack-2653</guid>
      <description>&lt;p&gt;Every team building with AI agents eventually hits the same wall: the moment a request leaves your application and enters the world of LLMs, tool calls, and MCP servers, it disappears into a black box. You can see the final answer, but not the packet trail that produced it — which model actually answered, how many tokens it burned, how long each hop took, or whether something in that chain quietly leaked a secret or got hijacked by a prompt injection.&lt;/p&gt;

&lt;p&gt;That's the gap &lt;strong&gt;AgentWire&lt;/strong&gt; is built to close.&lt;/p&gt;

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

&lt;p&gt;AgentWire is an open-source observability, security, and cost-analytics layer for AI agents, LLMs, and MCP servers. The project's own tagline sums up the ambition well: &lt;em&gt;OpenTelemetry + Wireshark + Cloudflare for AI agents&lt;/em&gt;. In practice, that means one system doing three jobs that today live in three different toolchains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt; — trace every hop between a user, an agent, an LLM, and any MCP servers it calls, the way OpenTelemetry does for microservices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; — inspect that same traffic for prompt injection, secret leakage, and malicious patterns, the way an edge gateway inspects HTTP traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost intelligence&lt;/strong&gt; — attribute a dollar figure to every packet, broken down by agent, model, and provider, so "why did our OpenAI bill triple" has an actual answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's built on ASP.NET Core, licensed Apache 2.0, and designed from the start as an event-driven system rather than a simple logging wrapper — because agentic traffic doesn't arrive as tidy request/response pairs, it arrives as a high-throughput stream of packets that need to be ingested, enriched, and queried without blocking the agent itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the project stands today
&lt;/h2&gt;

&lt;p&gt;AgentWire is honest about being an active MVP rather than a finished platform, and the README draws a clear line between what's real today and what's on the roadmap:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Available now:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trace ingestion via &lt;code&gt;POST /v1/traces&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Packet inspection via &lt;code&gt;GET /v1/packets&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cost rollups via &lt;code&gt;GET /v1/analytics/costs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;An optional Next.js dashboard scaffold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planned:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A YARP-based gateway with collector microservices&lt;/li&gt;
&lt;li&gt;ClickHouse as the analytical store for packet-scale data&lt;/li&gt;
&lt;li&gt;A prompt injection scanner and a full replay engine&lt;/li&gt;
&lt;li&gt;A multi-tenant, enterprise-ready edition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a deliberately narrow MVP: get a local ingestion API and cost endpoints working on SQLite first, prove the data model, then grow into the full event-driven architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples: getting a trace flowing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone and run the API
&lt;/h3&gt;

&lt;p&gt;With the .NET 10 SDK installed:&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/qmmughal/AgentWire.git
&lt;span class="nb"&gt;cd &lt;/span&gt;AgentWire
dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; src/AgentWire.Presentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API comes up on &lt;code&gt;localhost:5102&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Send a trace
&lt;/h3&gt;

&lt;p&gt;Every time an agent talks to an LLM, you send AgentWire a packet describing that exchange — which agent, which provider and model, the prompt, the response, and the token/latency numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:5102/v1/traces &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "traceId": "demo-001",
    "agentId": "support-bot",
    "modelProvider": "openai",
    "modelName": "gpt-4o-mini",
    "systemPrompt": "You are a helpful assistant.",
    "userPrompt": "Hello",
    "llmResponse": "Hi there!",
    "promptTokens": 12,
    "completionTokens": 8,
    "latencyMs": 220
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ingestion is asynchronous by design, so the call returns immediately with an acknowledgement while the packet is enriched and stored in the background:&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;"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;"accepted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"traceId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"demo-001"&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;h3&gt;
  
  
  3. Inspect the packet
&lt;/h3&gt;

&lt;p&gt;Pull the packet back to see what AgentWire recorded and enriched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5102/v1/packets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"traceId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"demo-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;"packetId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pk_9f2c1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agentId"&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-bot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"modelProvider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"modelName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4o-mini"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"promptTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"completionTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"latencyMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0000042&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&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-26T10:15:03Z"&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;em&gt;(Field names and exact values will track whatever the schema looks like by the time you run it — this is illustrative of the shape, not a frozen contract.)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Roll it up into cost
&lt;/h3&gt;

&lt;p&gt;The same packet feeds the cost-analytics endpoint, so you can see spend sliced by agent, model, or provider instead of digging through a provider dashboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5102/v1/analytics/costs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalCost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0000042&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"byAgent"&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;"support-bot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0000042&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;"byModel"&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;"gpt-4o-mini"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0000042&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;h3&gt;
  
  
  5. Optional — dashboard and local infra
&lt;/h3&gt;

&lt;p&gt;If you'd rather look at a UI than curl JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;src/Client/dashboard
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That opens a Next.js dashboard on &lt;code&gt;localhost:3000&lt;/code&gt; against the API above.&lt;/p&gt;

&lt;p&gt;And if you want to start poking at the pieces the full architecture will eventually run on — Postgres, Redis, RabbitMQ, ClickHouse — they're all wired into a Compose file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; deploy/docker-compose.yml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;App container builds aren't wired up yet, so &lt;code&gt;dotnet run&lt;/code&gt; stays the way to run the API itself for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it's headed architecturally
&lt;/h2&gt;

&lt;p&gt;The target architecture is a proper event-driven pipeline: a YARP-based API gateway takes in traffic from agents, SDKs, and OpenTelemetry exporters; a stateless Traffic Collector validates and pushes packets onto a message broker (RabbitMQ/MassTransit) to absorb spikes; a Traffic Analyzer consumes that queue, enriches the data, and batch-writes into storage; and a parallel Security Scanner and Cost Engine run over the same stream without adding latency to the agent's actual request path.&lt;/p&gt;

&lt;p&gt;Storage is deliberately polyglot — PostgreSQL for relational metadata like organizations, projects, and agents, with row-level security for tenant isolation; ClickHouse for the high-volume, time-series packet data that needs fast aggregation; and Redis for configuration and rate-limit caching. SDKs for .NET, Python, and JavaScript wrap standard OpenTelemetry SDKs, and a plugin system lets providers (OpenAI, Anthropic) and MCP servers plug in their own cost calculations and security rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  The business model, up front
&lt;/h2&gt;

&lt;p&gt;The MVP — ingestion, packets, and cost rollups — stays free and open source; that's a deliberate bet that the same organic trust a project like the maintainer's own &lt;code&gt;ckeditor5-blazor&lt;/code&gt; built up over years is worth more long-term than gating the basics. The parts of the roadmap that are genuinely expensive to run well — the ClickHouse analytics store, the security scanner, multi-tenant SaaS operations — are earmarked for an eventual hosted, managed tier. There's no beta or waitlist yet; that's a future announcement, not a present pitch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Most of the AI observability tooling available today was built for a world where an LLM call was the whole story. Agentic systems break that assumption — a single user request can now fan out into a dozen tool calls, several LLM round-trips, and one or more MCP server hops, each with its own latency, cost, and attack surface. AgentWire is a bet that this traffic deserves the same category of tooling that network engineers have had for decades: something you can point at the wire, watch the packets go by, and trust to tell you the truth about what actually happened.&lt;/p&gt;

&lt;p&gt;It's early — alpha, by the project's own description — but the direction is clear, and the repository is open for anyone who wants to try it, file an issue, or contribute against the sketched-out MVP epics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/qmmughal/AgentWire" rel="noopener noreferrer"&gt;github.com/qmmughal/AgentWire&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; Apache 2.0&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>security</category>
    </item>
    <item>
      <title>SQL RecycleBin: An Undo Button for SQL Server</title>
      <dc:creator>Qaiser Mehmood</dc:creator>
      <pubDate>Sun, 26 Jul 2026 06:06:43 +0000</pubDate>
      <link>https://dev.to/qmmughal/sql-recyclebin-an-undo-button-for-sql-server-1i80</link>
      <guid>https://dev.to/qmmughal/sql-recyclebin-an-undo-button-for-sql-server-1i80</guid>
      <description>&lt;p&gt;Every DBA has lived this moment: someone runs a DELETE without a WHERE clause on a production table, and the room goes quiet.&lt;/p&gt;

&lt;p&gt;Oracle has had an answer for this for years — Flashback Query. SQL Server's answer has basically been: hope your backup chain is intact, or pay for a $2,000 transaction-log forensics tool.&lt;/p&gt;

&lt;p&gt;So I built SQL RecycleBin.&lt;/p&gt;

&lt;p&gt;It's exactly what it sounds like — a recycle bin for SQL Server. Enable it once per table, and every DELETE or UPDATE gets captured automatically. When something goes wrong, you don't restore a backup and lose every transaction since — you just query it back and undo it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core flow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Turn on capture for a table (one-time setup)&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Orders'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- ...someone runs DELETE without a WHERE clause...&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- See exactly what was lost, as real typed columns — not raw log bytes&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deleted&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Orders'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Put it all back. Done.&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UndoLast&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Orders'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No log readers, no downtime, no third-party agent sitting in your pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few examples of it in practice
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Recovering from a bad UPDATE, not just a DELETE:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Customers'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- A migration script accidentally overwrites everyone's email domain&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'unknown@company.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Inspect before/after values for recent updates&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Updated&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Customers'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Revert every captured update since it happened&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UndoLast&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Customers'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rolling back to a specific point in time, across a whole transaction:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Find the transaction ID responsible&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Undo everything from that specific transaction, not just the last one&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UndoTransaction&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;TxId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;48213&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Or roll a table back to how it looked at a timestamp&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Restore&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;Table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dbo.Orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2026-07-25 09:00'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Excluding capture during bulk jobs or ETL, so you're not paying trigger overhead where you don't need it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BypassOn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Nightly bulk load — none of this gets captured&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BypassOff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Keeping the history store lean:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Purge anything older than 14 days (the default retention window)&lt;/span&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cleanup&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;KeepDays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prefer PowerShell over T-SQL?&lt;/strong&gt; The same engine is wrapped as a module on the PowerShell Gallery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Install-Module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SqlRecycleBin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Install-SqlRecycleBin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Database&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyDb"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Enable-SqlRecycleBinCapture&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dbo.Orders"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Restore-SqlRecycleBinLast&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dbo.Orders"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's actually happening under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rb.Enable&lt;/code&gt; generates a lightweight &lt;code&gt;AFTER UPDATE, DELETE&lt;/code&gt; trigger on the table.&lt;/li&gt;
&lt;li&gt;Changed rows are captured as JSON into a compressed internal store (&lt;code&gt;rb.ChangeLog&lt;/code&gt;) — JSON means an &lt;code&gt;ALTER TABLE&lt;/code&gt; on your side never breaks the safety net.&lt;/li&gt;
&lt;li&gt;Retrieval procs (&lt;code&gt;rb.Deleted&lt;/code&gt;, &lt;code&gt;rb.Updated&lt;/code&gt;) project that JSON back into real typed columns via &lt;code&gt;OPENJSON&lt;/code&gt;, using the table's current schema.&lt;/li&gt;
&lt;li&gt;Undo procs handle &lt;code&gt;IDENTITY_INSERT&lt;/code&gt; and skip primary key collisions automatically.&lt;/li&gt;
&lt;li&gt;All of it is persistent on disk — it survives restarts and failovers, unlike an in-memory cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest about its limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TRUNCATE TABLE&lt;/code&gt;, &lt;code&gt;DROP TABLE&lt;/code&gt;, and minimally-logged bulk operations don't fire triggers, so they aren't captured. This is a safety net, not a backup replacement.&lt;/li&gt;
&lt;li&gt;Tables need a primary key.&lt;/li&gt;
&lt;li&gt;Trigger capture adds write overhead — measure it on your workload, and use &lt;code&gt;rb.BypassOn&lt;/code&gt; around heavy bulk jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full details are in the README.&lt;/p&gt;

&lt;h2&gt;
  
  
  Licensing
&lt;/h2&gt;

&lt;p&gt;I'm shipping it as source-available under PolyForm Noncommercial — the complete v1 is free to read, install, and use for personal, educational, and noncommercial work. Commercial use requires a license, and that's what funds the roadmap: a CDC-based capture engine with zero trigger overhead, a Blazor dashboard with a diff viewer and one-click restore, and app-level user identity for who-did-what forensics behind connection pools.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/qmmughal/sql-recyclebin" rel="noopener noreferrer"&gt;https://github.com/qmmughal/sql-recyclebin&lt;/a&gt;&lt;br&gt;
Live demo + docs: &lt;a href="https://sqlrecyclebin.com" rel="noopener noreferrer"&gt;https://sqlrecyclebin.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you manage SQL Server databases — or you've ever been the person who had to explain a bad DELETE to your team — I'd love a star, a try, or just your thoughts on what a real "undo" for SQL Server should look like.&lt;/p&gt;

&lt;h1&gt;
  
  
  SQLServer #DBA #OpenSource #TSQL #DisasterRecovery #DataEngineering
&lt;/h1&gt;

</description>
      <category>backend</category>
      <category>database</category>
      <category>sql</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
