<?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: Thomas Hansen</title>
    <description>The latest articles on DEV Community by Thomas Hansen (@polterguy).</description>
    <link>https://dev.to/polterguy</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%2F829923%2F04782b3f-244f-42af-a2bb-cd3277828def.png</url>
      <title>DEV Community: Thomas Hansen</title>
      <link>https://dev.to/polterguy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/polterguy"/>
    <language>en</language>
    <item>
      <title>Masturbation Is 100 Times More Dangerous Than AI</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Mon, 14 Sep 2026 13:01:38 +0000</pubDate>
      <link>https://dev.to/polterguy/masturbation-is-100-times-more-dangerous-than-ai-1bjm</link>
      <guid>https://dev.to/polterguy/masturbation-is-100-times-more-dangerous-than-ai-1bjm</guid>
      <description>&lt;p&gt;This headline is intentionally provocative.&lt;/p&gt;

&lt;p&gt;It is also based on a simple comparison between two uncertain figures.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The comparison
&lt;/h2&gt;

&lt;p&gt;An old estimate suggested that between &lt;strong&gt;250 and 1,000 people die each year in the United States from autoerotic asphyxia&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Autoerotic asphyxia means sexual activity involving strangulation or oxygen restriction. It is not ordinary masturbation.&lt;/p&gt;

&lt;p&gt;Separately, a small number of suicides involving ChatGPT, Claude and other conversational AI systems have been publicly reported or alleged through lawsuits, family statements and investigations.&lt;/p&gt;

&lt;p&gt;A reasonable working estimate for these publicly reported AI-associated suicides is approximately &lt;strong&gt;2 to 10 cases&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using midpoint figures:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;500 autoerotic deaths ÷ 5 AI-associated suicides = 100&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Therefore:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Masturbation is approximately 100 times more dangerous than AI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The calculation is not a medical conclusion. It is a statistical punchline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The limitations
&lt;/h2&gt;

&lt;p&gt;The estimate of 250 to 1,000 autoerotic deaths per year is old and uncertain.&lt;/p&gt;

&lt;p&gt;A recent systematic review identified 101 published autoerotic death cases across 44 years. This is not a complete national or global registry. It only counts cases documented in the forensic literature.&lt;/p&gt;

&lt;p&gt;AI-associated deaths have similar classification problems.&lt;/p&gt;

&lt;p&gt;A death may involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A chatbot conversation&lt;/li&gt;
&lt;li&gt;Existing mental illness&lt;/li&gt;
&lt;li&gt;Social isolation&lt;/li&gt;
&lt;li&gt;Family conflict&lt;/li&gt;
&lt;li&gt;Drug use&lt;/li&gt;
&lt;li&gt;Financial or relationship problems&lt;/li&gt;
&lt;li&gt;Other online communities&lt;/li&gt;
&lt;li&gt;Several simultaneous causes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The presence of an AI conversation does not, by itself, establish causation.&lt;/p&gt;

&lt;p&gt;There is currently no standard death-certificate category called “death caused by ChatGPT” or “death caused by Claude.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eric.ed.gov/?id=EJ480743" rel="noopener noreferrer"&gt;Historical autoerotic-death estimate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://link.springer.com/article/10.1007/s00414-024-03367-0" rel="noopener noreferrer"&gt;Recent systematic review of autoerotic deaths&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aimortality.org/" rel="noopener noreferrer"&gt;Database of reported AI-associated fatalities&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Other unusual causes of death
&lt;/h2&gt;

&lt;p&gt;The following figures are mostly from the United States.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Approximate figure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bee, wasp and hornet stings&lt;/td&gt;
&lt;td&gt;72 deaths per year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cattle-related incidents&lt;/td&gt;
&lt;td&gt;Approximately 20–22 deaths per year in older estimates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lightning&lt;/td&gt;
&lt;td&gt;Approximately 20 deaths per year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Furniture and television tip-overs&lt;/td&gt;
&lt;td&gt;217 reported deaths from 2013 to July 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vending machines&lt;/td&gt;
&lt;td&gt;37 reported deaths from 1978 to 1995&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shark attacks&lt;/td&gt;
&lt;td&gt;Usually 5–10 deaths worldwide per year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Falling coconuts&lt;/td&gt;
&lt;td&gt;Unknown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Garden rakes&lt;/td&gt;
&lt;td&gt;Unknown&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Bee, wasp and hornet stings
&lt;/h3&gt;

&lt;p&gt;The CDC recorded 788 deaths from hornet, wasp and bee stings between 2011 and 2021.&lt;/p&gt;

&lt;p&gt;That equals an average of 72 deaths per year.&lt;/p&gt;

&lt;p&gt;The annual figure ranged from 59 to 89. Eighty-four percent of the victims were male.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cdc.gov/mmwr/volumes/72/wr/pdfs/mm7227a6-H.pdf" rel="noopener noreferrer"&gt;CDC data&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cattle
&lt;/h3&gt;

&lt;p&gt;Cattle can kill people by trampling, kicking, crushing or striking them.&lt;/p&gt;

&lt;p&gt;Older CDC agricultural estimates placed cattle-related deaths at approximately 20–22 per year in the United States.&lt;/p&gt;

&lt;p&gt;The victims were mainly agricultural workers handling cattle in pens, chutes and loading areas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stacks.cdc.gov/view/cdc/230082" rel="noopener noreferrer"&gt;CDC agricultural safety material&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lightning
&lt;/h3&gt;

&lt;p&gt;Lightning kills approximately 20 people per year in the United States.&lt;/p&gt;

&lt;p&gt;The rate has declined substantially over the last several decades because of improved warnings, public education, emergency care and changes in outdoor work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stacks.cdc.gov/view/cdc/259425" rel="noopener noreferrer"&gt;CDC-hosted lightning mortality study&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Furniture and televisions
&lt;/h3&gt;

&lt;p&gt;Unsecured furniture, televisions and appliances can tip over onto people.&lt;/p&gt;

&lt;p&gt;The Consumer Product Safety Commission reported 217 fatalities from January 2013 through July 2023. Of those victims, 155 were children.&lt;/p&gt;

&lt;p&gt;The same report estimated approximately 17,800 emergency-department-treated injuries per year from these incidents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cpsc.gov/s3fs-public/2023_Annual_Tip_Over_Report_Posted_2024Feb_FINAL_0.pdf" rel="noopener noreferrer"&gt;CPSC tip-over report&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vending machines
&lt;/h3&gt;

&lt;p&gt;The vending-machine statistic is often exaggerated.&lt;/p&gt;

&lt;p&gt;The CPSC reported at least 37 deaths between 1978 and 1995 after people rocked or tilted vending machines.&lt;/p&gt;

&lt;p&gt;That equals approximately two deaths per year during that period.&lt;/p&gt;

&lt;p&gt;The machines fell onto the victims. They did not kill people by dispensing drinks incorrectly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cpsc.gov/Newsroom/News-Releases/1996/CPSC-Soda-Vending-Machine-Industry-Labeling-Campaign-Warns-Of-Deaths-And-Injuries" rel="noopener noreferrer"&gt;CPSC vending-machine warning&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Falling coconuts
&lt;/h3&gt;

&lt;p&gt;Falling coconuts can cause fatal head injuries.&lt;/p&gt;

&lt;p&gt;However, the popular claim that coconuts kill 150 people per year is unsupported.&lt;/p&gt;

&lt;p&gt;The figure appears to have developed from a medical report about coconut injuries in Papua New Guinea and was later repeated as a global estimate.&lt;/p&gt;

&lt;p&gt;Actual coconut deaths occur, but the annual global number is unknown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pubmed.ncbi.nlm.nih.gov/6502774/" rel="noopener noreferrer"&gt;Original medical paper&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the comparison is useful
&lt;/h2&gt;

&lt;p&gt;The headline does not prove that AI is harmless.&lt;/p&gt;

&lt;p&gt;A handful of reported suicides involving AI systems is still serious, particularly where a system may reinforce delusions, dependency or suicidal thinking.&lt;/p&gt;

&lt;p&gt;The comparison demonstrates something else:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Humans have been dying from bizarre, mundane and poorly tracked activities for a very long time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Masturbation-related deaths have an old and uncertain estimate.&lt;/p&gt;

&lt;p&gt;AI-associated suicides have a new and uncertain estimate.&lt;/p&gt;

&lt;p&gt;The exact ratio cannot be proven.&lt;/p&gt;

&lt;p&gt;But “Masturbation Is 100 Times More Dangerous Than AI” remains a mathematically plausible thing you can quote me on in the public space, and easily be within 2 order of magnitudes correct ...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOW let's talk about AI regulations&lt;/strong&gt; ...&lt;/p&gt;

</description>
      <category>ai</category>
      <category>statistics</category>
      <category>health</category>
      <category>humor</category>
    </item>
    <item>
      <title>Your sitemap is an API — a whole website as one JSON document in 35 lines</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Mon, 14 Sep 2026 07:56:19 +0000</pubDate>
      <link>https://dev.to/polterguy/your-sitemap-is-an-api-a-whole-website-as-one-json-document-in-35-lines-2eai</link>
      <guid>https://dev.to/polterguy/your-sitemap-is-an-api-a-whole-website-as-one-json-document-in-35-lines-2eai</guid>
      <description>&lt;p&gt;Every time I want to give a model a &lt;em&gt;site&lt;/em&gt; rather than a &lt;em&gt;page&lt;/em&gt;, I end up writing the same throwaway script. Fetch the sitemap. Loop the URLs. Pull the title, the H1, the meta description. Strip the HTML down to something readable. Glue it into one file. Delete the script. Write it again three weeks later.&lt;/p&gt;

&lt;p&gt;So I made it a URL instead:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://hyperlambda.dev/website-to-json" rel="noopener noreferrer"&gt;https://hyperlambda.dev/website-to-json&lt;/a&gt;&lt;/strong&gt; — paste a domain, get one JSON document back. Free, no signup, no key.&lt;/p&gt;

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

&lt;p&gt;One array, one object per page:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/pricing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"h1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pricing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pricing | Example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"One flat price, no surprises."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"markdown"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"# Pricing&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;One flat price…"&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;That shape is the whole point. &lt;code&gt;markdown&lt;/code&gt; is the part you feed a model; &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;h1&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; are the parts you filter, dedupe and cite with. A folder of 50 Markdown files makes you rebuild that metadata yourself. One JSON document doesn't.&lt;/p&gt;

&lt;p&gt;Useful immediately for: seeding a RAG index, diffing a site before and after a migration, auditing which pages are missing a meta description, or handing a competitor's docs to a model without writing a crawler.&lt;/p&gt;

&lt;h2&gt;
  
  
  The entire backend
&lt;/h2&gt;

&lt;p&gt;Not a snippet of it. This is the deployed file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.arguments
   url:string

// Throttling to maximum 5 requests per IP per minute!
execution.throttle.create:website-to-json
   limit:int:5
   window:int:60
   per:ip
execution.throttle:website-to-json

strings.concat
   get-value:x:@.arguments/*/url
   .:/sitemap.xml
http.get:x:-
xml2lambda:x:-/*/content
.result
for-each:x:@xml2lambda/*/urlset/*/url/*/loc/*/#text/[0,50]
   http.get:x:@.dp/#
   html2lambda:x:-/*/content
   .h1
   strings.join:x:@html2lambda/*/html/*/body/**/h1/[0,1]/**/#text
      .:" "
   set-value:x:@.h1
      strings.trim:x:@strings.join
   .title
   set-value:x:@.title
      get-value:x:@html2lambda/*/html/*/head/*/title/*/#text
   .description
   set-value:x:@.description
      get-value:x:"@html2lambda/*/html/*/head/*/meta/*/\\@name/=description/./*/\\@content"
   lambda2html:x:@html2lambda/*/html/*/body
   html2markdown:x:@lambda2html
      url:x:@.arguments/*/url
   unwrap:x:+/*/*/*
   add:x:@.result
      .
         .
            url:x:@.dp/#
            h1:x:@.h1
            title:x:@.title
            description:x:@.description
            markdown:x:@html2markdown
return-nodes:x:@.result/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No dependencies, no build step, no project scaffold. That file &lt;em&gt;is&lt;/em&gt; the deployment — saving it publishes the endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts worth stealing
&lt;/h2&gt;

&lt;p&gt;This is Hyperlambda, where code is a tree rather than text, and the interesting bits are the expressions that walk it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The sitemap is parsed, not regexed.&lt;/strong&gt; &lt;code&gt;xml2lambda&lt;/code&gt; turns the XML into nodes, and then the loop selects every URL in one expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for-each:x:@xml2lambda/*/urlset/*/url/*/loc/*/#text/[0,50]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read it right to left: every &lt;code&gt;#text&lt;/code&gt; under every &lt;code&gt;loc&lt;/code&gt; under every &lt;code&gt;url&lt;/code&gt; in the &lt;code&gt;urlset&lt;/code&gt; — then &lt;code&gt;[0,50]&lt;/code&gt; slices the first fifty. The page limit isn't an &lt;code&gt;if&lt;/code&gt; with a counter; it's part of the address of the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attribute matching without a DOM library.&lt;/strong&gt; Pulling &lt;code&gt;&amp;lt;meta name="description" content="…"&amp;gt;&lt;/code&gt; is one expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@html2lambda/*/html/*/head/*/meta/*/\@name/=description/./*/\@content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the &lt;code&gt;@name&lt;/code&gt; attribute whose value equals &lt;code&gt;description&lt;/code&gt;, step back up to its element with &lt;code&gt;.&lt;/code&gt;, then take that element's &lt;code&gt;@content&lt;/code&gt;. Attributes are &lt;code&gt;\@&lt;/code&gt;-prefixed nodes, so they're addressable the same way elements are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H1 text is joined, not assumed.&lt;/strong&gt; An &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; containing a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; and a stray &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; has several text nodes. &lt;code&gt;**/#text&lt;/code&gt; collects all of them under the first H1 and &lt;code&gt;strings.join&lt;/code&gt; puts them back together with a space — so &lt;code&gt;&amp;lt;h1&amp;gt;Build &amp;lt;span&amp;gt;fast&amp;lt;/span&amp;gt;&amp;lt;/h1&amp;gt;&lt;/code&gt; yields &lt;code&gt;Build fast&lt;/code&gt;, not &lt;code&gt;Build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relative links survive.&lt;/strong&gt; The body is serialized back to HTML and converted with the original domain passed in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html2markdown:x:@lambda2html
   url:x:@.arguments/*/url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without that, every &lt;code&gt;/pricing&lt;/code&gt; in the output would be a dead relative link the moment the JSON left the site it came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it will not do
&lt;/h2&gt;

&lt;p&gt;Worth stating plainly, because a crawler that pretends otherwise wastes your afternoon:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It needs a sitemap.&lt;/strong&gt; The URL you pass gets &lt;code&gt;/sitemap.xml&lt;/code&gt; appended, so pass the origin with no trailing slash (&lt;code&gt;https://example.com&lt;/code&gt;). No sitemap, no output. Sites that keep a sitemap index rather than a flat urlset won't enumerate either.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It does not run JavaScript.&lt;/strong&gt; Server-rendered HTML only. A client-rendered app returns its shell, exactly like &lt;code&gt;curl&lt;/code&gt; would.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fifty pages, hard.&lt;/strong&gt; Fine for a docs section or a marketing site; not a crawler for your 40,000-page store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Five requests per minute per IP.&lt;/strong&gt; It's a free shared endpoint doing 50 HTTP fetches per call. Hammer it and you'll just get throttled — the source is above, run your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also costs the target site 50 requests, so point it at your own property or something that welcomes it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I actually find interesting
&lt;/h2&gt;

&lt;p&gt;The file above was written from a plain-English description by a code generator, and every function in it was verified against the functions that actually exist on the server &lt;em&gt;before&lt;/em&gt; it was saved. Not "the model probably got the API right" — checked, then deployed, with no restart.&lt;/p&gt;

&lt;p&gt;That inverts the usual trade-off with generated backend code. The risk isn't that the model writes ugly code, it's that it writes code that references something imaginary and fails at 3am. If the runtime refuses to save anything that invokes a function it doesn't have, the failure happens at generation time instead.&lt;/p&gt;

&lt;p&gt;Same property makes it an agent tool rather than a web page: on this stack every HTTP endpoint is also an MCP tool, role-filtered, so an agent can call &lt;code&gt;website-to-json&lt;/code&gt; and get the same array without a browser in the loop.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;The tool: &lt;strong&gt;&lt;a href="https://hyperlambda.dev/website-to-json" rel="noopener noreferrer"&gt;https://hyperlambda.dev/website-to-json&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;More free ones — page to JSON, dead link checker, link preview checker, llms.txt generator: &lt;strong&gt;&lt;a href="https://hyperlambda.dev/tools" rel="noopener noreferrer"&gt;https://hyperlambda.dev/tools&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Run the whole platform yourself, MIT-licensed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://hyperlambda.dev/docker-compose.yaml | docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; - up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you build something with the output, I'd like to hear what you pointed it at.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built 9 free web tools and printed the entire backend on every page. What should number 10 be?</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Sun, 13 Sep 2026 05:47:20 +0000</pubDate>
      <link>https://dev.to/polterguy/i-built-9-free-web-tools-and-printed-the-entire-backend-on-every-page-what-should-number-10-be-1a8f</link>
      <guid>https://dev.to/polterguy/i-built-9-free-web-tools-and-printed-the-entire-backend-on-every-page-what-should-number-10-be-1a8f</guid>
      <description>&lt;p&gt;Over the last couple of weeks I've built nine small web tools. No signup, no API key, no "start your free trial". You paste a URL, you get a result.&lt;/p&gt;

&lt;p&gt;There's a catch, and it's the interesting part: &lt;strong&gt;every tool prints the complete source code of its own backend, right there on the page.&lt;/strong&gt; Not a snippet. Not pseudocode. The actual file that ran when you clicked the button.&lt;/p&gt;

&lt;p&gt;I did that because I wanted the tools to be an argument, not a brochure. If I claim a backend is small, you shouldn't have to take my word for it.&lt;/p&gt;

&lt;p&gt;Now I've run out of good ideas for number ten, which is why I'm writing this. &lt;strong&gt;Skip to the bottom if you just want to tell me what to build.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The nine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/url-to-markdown" rel="noopener noreferrer"&gt;URL to Markdown&lt;/a&gt;&lt;/strong&gt; — paste a link, get clean Markdown for an LLM prompt, plus the token count before and after so you can see what the HTML was costing you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/page-to-json" rel="noopener noreferrer"&gt;Page to JSON&lt;/a&gt;&lt;/strong&gt; — one page as structured JSON: title, H1, description, text, every link &lt;em&gt;with its anchor text&lt;/em&gt;, every image &lt;em&gt;with its alt&lt;/em&gt;. Missing anchor and alt text get flagged rather than silently returned as empty strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/website-to-json" rel="noopener noreferrer"&gt;Website to JSON&lt;/a&gt;&lt;/strong&gt; — same idea, but walks the sitemap instead of one page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/url-to-yaml" rel="noopener noreferrer"&gt;URL to YAML&lt;/a&gt;&lt;/strong&gt; — a page's metadata as YAML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/llms-txt-generator" rel="noopener noreferrer"&gt;llms.txt generator&lt;/a&gt;&lt;/strong&gt; — builds an &lt;code&gt;llms.txt&lt;/code&gt; from your sitemap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/ai-crawler-check" rel="noopener noreferrer"&gt;AI Crawler Check&lt;/a&gt;&lt;/strong&gt; — which AI crawlers your &lt;code&gt;robots.txt&lt;/code&gt; actually allows or blocks, &lt;strong&gt;citing the exact rule that decided each one&lt;/strong&gt;. Also checks whether your content survives without JavaScript, because most AI crawlers don't render it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/link-preview-checker" rel="noopener noreferrer"&gt;Link Preview Checker&lt;/a&gt;&lt;/strong&gt; — what your Open Graph and Twitter cards really look like to a scraper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/website-image-gallery" rel="noopener noreferrer"&gt;Website Image Gallery&lt;/a&gt;&lt;/strong&gt; — every image across your site with its alt text, so you can find the ones missing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hyperlambda.dev/dead-link-checker" rel="noopener noreferrer"&gt;Dead Link Checker&lt;/a&gt;&lt;/strong&gt; — crawls your sitemap and reports links that don't answer 200.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All nine are here: &lt;strong&gt;&lt;a href="https://hyperlambda.dev/tools" rel="noopener noreferrer"&gt;hyperlambda.dev/tools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What "the whole backend" actually looks like
&lt;/h2&gt;

&lt;p&gt;Here's URL to Markdown, in full. This is not an excerpt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.arguments
   url:string
validators.mandatory:x:@.arguments/*/url
validators.url:x:@.arguments/*/url
http.get:x:@.arguments/*/url
html2markdown:x:-/*/content
   url:x:@.arguments/*/url
openai.tokenize:x:@http.get/*/content
openai.tokenize:x:@html2markdown
yield
   markdown:x:@html2markdown
   html_tokens:x:@openai.tokenize/@openai.tokenize
   markdown_tokens:x:@openai.tokenize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fetch it, convert it, count the tokens twice, return three fields. The language is &lt;a href="https://hyperlambda.dev" rel="noopener noreferrer"&gt;Hyperlambda&lt;/a&gt;, which is my own thing, so take the language advocacy with as much salt as you like — the point I care about is that a working tool can be this small, and that you can check.&lt;/p&gt;

&lt;p&gt;Not all nine are that short. The dead link checker is about seventy lines, because deduplicating links and surviving hosts that refuse connections is genuinely more work. That page says so and prints all seventy.&lt;/p&gt;

&lt;h2&gt;
  
  
  They're also MCP tools
&lt;/h2&gt;

&lt;p&gt;Every HTTP endpoint on this platform is automatically exposed as an &lt;a href="https://hyperlambda.dev/mcp-server" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; tool, filtered by role. So these aren't just web pages — an agent can call the same endpoints directly, and "build a tool" and "build an agent tool" stopped being two separate tasks.&lt;/p&gt;

&lt;p&gt;That turned out to be the thing I use most. Half of these exist because I wanted Claude to be able to read a page properly.&lt;/p&gt;

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

&lt;p&gt;Things I'd rather you hear from me than discover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No JavaScript rendering.&lt;/strong&gt; Everything fetches server-rendered HTML. A client-side-rendered SPA comes back nearly empty — which is also exactly what most AI crawlers see, so arguably that's the useful answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The dead link checker crawls 10 sitemap pages max&lt;/strong&gt;, though it checks every link it finds on them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The image gallery caps out at 50 results.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Some sites return 403/999 to anything that isn't a browser. That's a bot refusal, not a broken link, and the dead link checker separates those into their own bucket instead of calling them dead.&lt;/li&gt;
&lt;li&gt;These are free and shared. Please don't point a load test at them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So — what should number 10 be?
&lt;/h2&gt;

&lt;p&gt;This is the actual reason for the post. I'm better at building these than at thinking of them.&lt;/p&gt;

&lt;p&gt;What I'm after is the thing you currently do by hand, or with a browser extension you don't trust, or by pasting into three different sites in sequence. Ideas I've had and rejected as too boring: another JSON formatter, another minifier, another base64 thing.&lt;/p&gt;

&lt;p&gt;Some prompts, if it helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's the last web-related task where you thought &lt;em&gt;"surely something does this for me"&lt;/em&gt; and nothing did?&lt;/li&gt;
&lt;li&gt;Is there a tool you use that's fine except for one missing feature?&lt;/li&gt;
&lt;li&gt;What would you want an &lt;strong&gt;AI agent&lt;/strong&gt; to be able to do to a web page, that it currently can't?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reply with whatever comes to mind. If I build yours I'll say so in the thread, and it'll be free and no-signup like the rest.&lt;/p&gt;

&lt;p&gt;And if one of the nine is broken or wrong for your site, I'd genuinely rather know — tell me the URL you tried.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Magic vs Directus: An Honest Feature Matrix</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Tue, 01 Sep 2026 06:28:11 +0000</pubDate>
      <link>https://dev.to/polterguy/magic-vs-directus-an-honest-feature-matrix-4onb</link>
      <guid>https://dev.to/polterguy/magic-vs-directus-an-honest-feature-matrix-4onb</guid>
      <description>&lt;p&gt;The &lt;a href="https://hyperlambda.dev/blog/magic-vs-n8n-an-honest-feature-matrix" rel="noopener noreferrer"&gt;n8n matrix&lt;/a&gt; was easy mode. The &lt;a href="https://hyperlambda.dev/blog/magic-vs-pocketbase-an-honest-feature-matrix" rel="noopener noreferrer"&gt;PocketBase one&lt;/a&gt; was hard mode, because PocketBase is Magic's closest architectural sibling.&lt;/p&gt;

&lt;p&gt;This one is different again. Directus is not Magic's closest sibling — it is Magic's closest &lt;em&gt;competitor&lt;/em&gt;. If you are evaluating a platform that wraps a database you already have, in whatever engine it happens to live in, without migrating anything, then Directus and Magic are pitching you the same sentence. It is a genuinely excellent product with a decade of polish on it, and on several rows below it beats Magic outright.&lt;/p&gt;

&lt;p&gt;One sentence of thesis before the table, because every row descends from it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Directus computes your API at runtime. Magic writes it to disk.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Directus introspects your schema, holds permissions as configuration, and resolves each request against both. Nothing is written down — the effective API exists only as the result of that computation. Magic's generator emits actual endpoint files you can open, read, diff, edit and commit. Watch how far that one difference propagates.&lt;/p&gt;

&lt;h2&gt;
  
  
  The matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Directus&lt;/th&gt;
&lt;th&gt;Magic Cloud&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Licence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Monospace Sustainable Core License — source-available, non-compete, with licence-key enforcement you may not circumvent; converts to GPL-3.0 four years after each release&lt;/td&gt;
&lt;td&gt;MIT, all of it, no thresholds and no conversion date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Core: 3 user seats, 25 collections, 5 flows, no SSO&lt;/td&gt;
&lt;td&gt;Self-host everything, uncapped, forever&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Small-company escape hatch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Open Innovation Grant — fully permissive and free under $5M revenue &lt;strong&gt;and&lt;/strong&gt; under 50 employees&lt;/td&gt;
&lt;td&gt;Not needed; MIT has no revenue test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Paid tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Team at $499/mo annual, $599 monthly — 10 SSO seats, 50 collections, 20 flows&lt;/td&gt;
&lt;td&gt;$100/mo per cloudlet, $300 for double the machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Per-user cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$50 per extra seat per month&lt;/td&gt;
&lt;td&gt;None — unlimited users, never counted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Table cap&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A collection maps to a database table: 25 on Core, 50 on Team, $100 per extra 25&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Managed hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$99/mo add-on, on top of the plan&lt;/td&gt;
&lt;td&gt;Included in the cloudlet price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SSO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Team plan and up; unavailable on Core at any price&lt;/td&gt;
&lt;td&gt;Eight OIDC providers built in — Google, Microsoft, GitHub, LinkedIn, Slack, Okta, Auth0, Keycloak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Computed at runtime from schema and config&lt;/td&gt;
&lt;td&gt;Generated Hyperlambda files — real, readable, versionable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schema changes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reflected instantly, nothing to regenerate&lt;/td&gt;
&lt;td&gt;Re-run the generator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Database engines&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, OracleDB, CockroachDB&lt;/td&gt;
&lt;td&gt;SQLite built in, plus MySQL, PostgreSQL and SQL Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Granular: field-level and item-level rules as filter expressions&lt;/td&gt;
&lt;td&gt;Endpoint-level role gating, plus &lt;a href="https://hyperlambda.dev/blog/why-secure-ai-code-execution-requires-runtime-whitelisting-not-prompt-filtering" rel="noopener noreferrer"&gt;runtime slot whitelisting&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extensions in TypeScript, with a build step; Flows with sandboxed JS operations&lt;/td&gt;
&lt;td&gt;Hyperlambda files, hot — no compile, no restart, generated from a prompt if you like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content features&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Revisions, drafts, translations, activity log — a decade of CMS heritage&lt;/td&gt;
&lt;td&gt;None of it; not a CMS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Assets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;File library with on-the-fly image transformation&lt;/td&gt;
&lt;td&gt;File system, upload tickets, image resize and convert&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Realtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebSockets and GraphQL subscriptions&lt;/td&gt;
&lt;td&gt;SignalR — programmable events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not the story&lt;/td&gt;
&lt;td&gt;First-class static and SPA hosting per cloudlet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI and RAG&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI Assistant, AI Translations on higher tiers&lt;/td&gt;
&lt;td&gt;ML types, crawling, vectorisation, deployable chatbots&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent story&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MCP server over the API&lt;/td&gt;
&lt;td&gt;Native MCP with OAuth; agents &lt;a href="https://hyperlambda.dev/blog/the-only-llm-on-earth-that-grows-its-own-tools-securely-on-demand-in-production" rel="noopener noreferrer"&gt;generate new tools for themselves at runtime&lt;/a&gt; inside RBAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Non-developers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Genuinely usable by editors and ops people&lt;/td&gt;
&lt;td&gt;A developer tool, and honest about it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Community&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large, funded, SOC 2, partner programme&lt;/td&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where Directus wins, stated plainly
&lt;/h2&gt;

&lt;p&gt;Per the rules of this series: no rebuttals in this section. They live below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permissions granularity.&lt;/strong&gt; Field-level and item-level rules, expressed as filter conditions, evaluated per request. Magic gates by role at the endpoint. If your requirement is "this role sees every column except salary, and only rows in their own region", Directus expresses that as configuration and Magic expects you to write it. That is the widest genuine capability gap in the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instant schema reflection.&lt;/strong&gt; Add a column, and Directus's API has it. No regeneration step, no stale endpoints, no forgetting to re-run anything. This is the direct upside of the runtime model, and on a schema that changes daily it is a real ergonomic win.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content management.&lt;/strong&gt; Revisions, drafts, translations, an activity log people actually audit. Directus descends from headless CMS and it shows in a hundred small places Magic has never attempted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-developer usability.&lt;/strong&gt; You can hand Directus Studio to a marketing team. You cannot hand Hyper IDE to a marketing team, and I would not suggest trying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database engines.&lt;/strong&gt; Oracle, MariaDB and CockroachDB are supported there and not here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ecosystem and assurance.&lt;/strong&gt; A funded company, a partner programme, SOC 2 Type II, an extension marketplace, a large forum, and people you can hire who already know it. Every one of those is a cost I carry on my side of this table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the bets diverge
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The runtime model versus the generated one.&lt;/strong&gt; Directus's API is a computation; Magic's is a file. That means Directus wins on schema churn and loses on inspection. There is no artefact to review, diff, or hand to a code reviewer — your effective API and permission surface live as rows in a config database, and the only way to know what they do is to ask the running system. Magic's endpoints are text on disk. You can read them, put them under git, and — the part that matters most here — hand them to an AI agent that can read them too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which is why the agent stories are not comparable.&lt;/strong&gt; Both have MCP. But an agent pointed at Directus can call the API; an agent pointed at Magic can read what the API &lt;em&gt;is&lt;/em&gt;, and then write more of it. Magic's generator emits Hyperlambda that executes as an AST where every node must bind to a whitelisted slot, so generated code &lt;a href="https://hyperlambda.dev/blog/why-secure-ai-code-execution-requires-runtime-whitelisting-not-prompt-filtering" rel="noopener noreferrer"&gt;cannot exceed its permissions no matter what the prompt said&lt;/a&gt;. That is the difference between an agent that queries your backend and an agent that builds it. There is &lt;a href="https://hyperlambda.dev/blog/break-my-ai-sandbox-and-make-100-psst-nobodys-done-it-yet" rel="noopener noreferrer"&gt;a standing $100 bounty&lt;/a&gt; on proving that boundary wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The extension model, again.&lt;/strong&gt; This series keeps landing here because it keeps being the fork in the road. Directus extensions are TypeScript with a build step; Flows give you sandboxed JS for the smaller cases. Magic's custom logic is a Hyperlambda file that is live the moment it is saved — no compiler, no restart, no deploy — and can be written from a sentence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing shape, which is a licensing argument wearing a costume.&lt;/strong&gt; Directus meters the two things that grow when your project succeeds: &lt;strong&gt;people&lt;/strong&gt; and &lt;strong&gt;tables&lt;/strong&gt;. Core stops at 3 seats and 25 collections. Team is $499/mo for 10 seats and 50 collections, with extra seats at $50/mo and extra collections at $100 per 25. Managed hosting is another $99. Magic charges per cloudlet — $100 or $300 — and counts neither users nor tables, ever.&lt;/p&gt;

&lt;p&gt;Work an example. A team of six developers wrapping a 70-table legacy database, hosted: on Directus that is Team, plus one 25-collection pack, plus cloud — call it &lt;strong&gt;$698/mo&lt;/strong&gt; before anyone else logs in. On Magic it is &lt;strong&gt;$100&lt;/strong&gt;, and the seventh developer changes nothing.&lt;/p&gt;

&lt;p&gt;Two honest caveats on that comparison, because it flatters me. If you are under $5M revenue &lt;em&gt;and&lt;/em&gt; under 50 employees, the Open Innovation Grant makes Directus free and fully permissive, and this entire paragraph is moot for you — take the grant. And Directus is grandfathering existing customers, so anyone already on an older plan is not living in the table above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The licence, which is the row I would read twice.&lt;/strong&gt; Directus is &lt;em&gt;source-available&lt;/em&gt;, not open source: the Monospace Sustainable Core License forbids Competing Use, forbids circumventing the licence-key functionality, and grants GPL-3.0 only on the fourth anniversary of each release. That is a defensible way to run a company, and I say that without snark — it is a real answer to a real sustainability problem. But it is not the same deal as MIT, and the difference shows up on the day your revenue crosses a threshold, or your lawyer asks what "Competing Use" means for the product you are building on top of it. Magic is MIT with nothing held back, no key, no threshold, no clock.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Choose Directus if:&lt;/strong&gt; non-developers will use the admin UI daily; you need field- and row-level permissions as configuration rather than code; your content needs revisions, drafts or translations; your schema changes constantly; you are on Oracle or CockroachDB; or you qualify for the Open Innovation Grant, in which case a mature, funded, SOC 2 platform costs you nothing and that is very hard to argue with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose Magic if:&lt;/strong&gt; you are above the grant's thresholds and do not want per-seat and per-table metering; you want the API as reviewable source rather than runtime configuration; you need the platform to host the frontend as well as the data; or — the structural one — you expect AI agents to be building the backend rather than querying it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The test that decides it in one question:&lt;/strong&gt; does your backend need to be &lt;em&gt;read&lt;/em&gt; by anything other than the server that runs it? If yes — by a reviewer, by git, by an agent — you want files. If no, a runtime model is less work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fine print
&lt;/h2&gt;

&lt;p&gt;Every number above about Directus was verified on their own pricing and licence pages the day this was published: the MSCL-1.0-GPL terms, the $0 / $499 / custom tiers, the 3-seat and 25-collection Core caps, $50 per extra seat, $100 per 25-collection pack, the $99 cloud add-on, and the under-$5M-and-under-50-employees grant. Pricing pages move. If you are reading this months later, re-verify before quoting me — and I would rather you checked than trusted me.&lt;/p&gt;

&lt;p&gt;The database engine list for Directus is from documentation rather than from my own testing, and Magic's own comparison rows are, obviously, written by the person who wrote Magic. Read the table with that in mind.&lt;/p&gt;

&lt;p&gt;Magic is MIT-licensed and open source — the repository is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;. Testing any of this yourself takes &lt;a href="https://hyperlambda.dev/blog/magic-cloud-digitalocean-one-copy-paste" rel="noopener noreferrer"&gt;one copy-paste on a $6 DigitalOcean droplet&lt;/a&gt;, or &lt;a href="https://hyperlambda.dev/pricing" rel="noopener noreferrer"&gt;a managed cloudlet&lt;/a&gt; if you would rather not.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Is Magic Cloud a Directus alternative?
&lt;/h3&gt;

&lt;p&gt;For the developer case, yes — both wrap an existing database in a secured API without migrating it, both ship an admin UI, both self-host, both offer managed hosting. For the editorial case, no: Directus is a headless CMS with revisions, drafts and translations, and Magic is not trying to be one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Directus open source?
&lt;/h3&gt;

&lt;p&gt;Not in the OSI sense any more. It is source-available under the Monospace Sustainable Core License, which prohibits Competing Use and licence-key circumvention, and converts each release to GPL-3.0 after four years. Magic is MIT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Directus free?
&lt;/h3&gt;

&lt;p&gt;Free at the Core tier within hard caps — 3 seats, 25 collections, 5 flows, no SSO — and genuinely free and fully permissive under the Open Innovation Grant if your organisation is under $5M in revenue and under 50 employees. Above those lines it is $499/mo and up, with per-seat and per-collection metering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which handles a large legacy schema better?
&lt;/h3&gt;

&lt;p&gt;Directus reflects the whole schema instantly with nothing to generate, which is the better ergonomic. But collections are capped by plan, and a 200-table system lands you in Enterprise pricing. Magic makes you run the generator and gives you files afterwards, with no table count anywhere in the pricing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can AI agents use both?
&lt;/h3&gt;

&lt;p&gt;Both expose MCP. The difference is what the agent can do once connected: with Directus it calls your API; with Magic it can read the generated code and write more of it, inside a runtime that constrains what generated code is even able to express.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/magic-vs-pocketbase-an-honest-feature-matrix" rel="noopener noreferrer"&gt;Magic vs PocketBase: An Honest Feature Matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/magic-vs-n8n-an-honest-feature-matrix" rel="noopener noreferrer"&gt;Magic vs n8n: An Honest Feature Matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/magic-cloud-the-self-hosted-supabase-alternative-built-for-ai-agents" rel="noopener noreferrer"&gt;Magic Cloud: The Self-Hosted Supabase Alternative Built for AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/why-secure-ai-code-execution-requires-runtime-whitelisting-not-prompt-filtering" rel="noopener noreferrer"&gt;Why Secure AI Code Execution Requires Runtime Whitelisting, Not Prompt Filtering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>database</category>
      <category>ai</category>
    </item>
    <item>
      <title>From Prompt to MCP Tool in 5 Seconds</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Tue, 18 Aug 2026 10:39:46 +0000</pubDate>
      <link>https://dev.to/polterguy/from-prompt-to-mcp-tool-in-5-seconds-3fad</link>
      <guid>https://dev.to/polterguy/from-prompt-to-mcp-tool-in-5-seconds-3fad</guid>
      <description>&lt;p&gt;Building an MCP tool, as the industry currently understands the job: install an SDK, write a server, hand-author a tool schema, wire the handler, host the process, deploy it, restart it, reconnect the client.&lt;/p&gt;

&lt;p&gt;Here is the same job on &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;Magic&lt;/a&gt;, the MIT-licensed backend platform I work on.&lt;/p&gt;

&lt;p&gt;You write a sentence.&lt;/p&gt;

&lt;p&gt;That is the whole procedure, and this article is about why — because the interesting part is not that it is fast. It is that there is no second step to be fast &lt;em&gt;at&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;I did this on the cloudlet serving my website while writing the article. The generator reports its own execution time, so these numbers are server-measured, not my stopwatch.&lt;/p&gt;

&lt;p&gt;I wanted a tool that did not exist: a daily trend over the anonymous submissions to our carbon calculator — how many people submitted each day, and how heavy their average footprint was.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attempt&lt;/th&gt;
&lt;th&gt;Seconds (measured)&lt;/th&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First generation&lt;/td&gt;
&lt;td&gt;2.88&lt;/td&gt;
&lt;td&gt;Saved, then threw a 500 on invocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regenerated&lt;/td&gt;
&lt;td&gt;1.83&lt;/td&gt;
&lt;td&gt;Live and correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regenerated for a better description&lt;/td&gt;
&lt;td&gt;3.03&lt;/td&gt;
&lt;td&gt;Live, correct, properly documented&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three generations, 7.74 seconds of compute, one live tool. It is public and read-only, so you can call it yourself right now:&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="s2"&gt;"https://hyperlambda.dev/magic/modules/mcp-demo/footprint-trend?days=365"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"day"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2026-08-09"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"submissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"average_total_kg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;16188.0&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="nl"&gt;"day"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2026-08-03"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"submissions"&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="nl"&gt;"average_total_kg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;8772.0&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;I will come back to that failed first attempt, because the honest part of this story is more useful than the fast part.&lt;/p&gt;

&lt;h2&gt;
  
  
  There is no second step
&lt;/h2&gt;

&lt;p&gt;The file the generator saved is this. The comment is abbreviated here; everything else is verbatim.&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="o"&gt;//&lt;/span&gt; &lt;span class="k"&gt;Returns&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;daily&lt;/span&gt; &lt;span class="n"&gt;trend&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;anonymous&lt;/span&gt; &lt;span class="n"&gt;carbon&lt;/span&gt; &lt;span class="n"&gt;footprint&lt;/span&gt; &lt;span class="n"&gt;submissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="n"&gt;per&lt;/span&gt; &lt;span class="k"&gt;day&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;
   &lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;
&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;
   &lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;billionair&lt;/span&gt;
   &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;"select date(created) as day, count(*) as submissions, avg(total_kg) as average_total_kg from footprints where created &amp;gt;= date('now', '-' || @days || ' day') and total_kg &amp;gt; 0 group by day order by day desc"&lt;/span&gt;
      &lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="cm"&gt;/*/days
   return-nodes:x:@data.select/*
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saving that file is the last thing that happens. There is no build, no restart, no registration, no export.&lt;/p&gt;

&lt;p&gt;The reason is that &lt;strong&gt;Magic's MCP server has no tool registry.&lt;/strong&gt; It does not keep a list of tools that somebody has to remember to update. When a client asks what tools exist, the server enumerates the endpoints that exist, right then, and describes them. The catalogue is not a copy of reality that can drift out of date — it is a query against reality.&lt;/p&gt;

&lt;p&gt;Which means a tool cannot be &lt;em&gt;added&lt;/em&gt; to the tool list. It can only be &lt;em&gt;created&lt;/em&gt;, after which the list already contains it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffmyseke02ngvazlii36m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffmyseke02ngvazlii36m.png" alt="A Magic cloudlet connected as an MCP connector, listing the tools it publishes to the agent" width="799" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same is true in the other direction, and this is the part I find quietly elegant: calling a tool runs the endpoint. Not a copy of the endpoint, not a proxy in front of it — the endpoint, through the same invocation path an HTTP request takes, carrying the caller's own identity. So the role check that guards it from a browser is the role check that guards it from an agent, because it is the same check. There was never a second one to keep in sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your prompt is the tool description
&lt;/h2&gt;

&lt;p&gt;Now the mechanic that makes one sentence sufficient.&lt;/p&gt;

&lt;p&gt;A language model deciding whether to call a tool reads two things: the tool's description, and a description of each argument. In every other stack, those are a third artifact — written by hand, next to the code and the schema, and stale within a month.&lt;/p&gt;

&lt;p&gt;Magic publishes an endpoint's file comment as the tool description, and the comment above each argument as &lt;em&gt;that argument's&lt;/em&gt; description. And the generator writes the file comment from your prompt.&lt;/p&gt;

&lt;p&gt;So the sentence you typed is not merely instructions to a code generator that get thrown away afterwards. It survives, in the file, as the documentation your agent reads. Here is what came back out the other end, from this cloudlet's live specification:&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="nl"&gt;"/magic/modules/mcp-demo/footprint-trend"&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;"get"&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;"operationId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"get_mcp-demo_footprint-trend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Returns the daily trend of anonymous carbon footprint submissions, one entry per day, so a caller can see how many people submitted and how heavy their average footprint was [...]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"days"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"schema"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"integer"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I never wrote a schema. I wrote &lt;code&gt;days&lt;/code&gt; in a sentence, said it was an integer, and the type came along for the ride.&lt;/p&gt;

&lt;p&gt;The mapping from Hyperlambda's types to JSON Schema is boring on purpose:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hyperlambda&lt;/th&gt;
&lt;th&gt;JSON Schema&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;short&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;long&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;integer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;decimal&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;number&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;string&lt;/code&gt;, format &lt;code&gt;date-time&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;guid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;string&lt;/code&gt;, format &lt;code&gt;uuid&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;everything else&lt;/td&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  So write the prompt like a docstring
&lt;/h2&gt;

&lt;p&gt;Here is a mistake I made in front of you, and it is the most useful paragraph in this article.&lt;/p&gt;

&lt;p&gt;My second attempt worked perfectly, and its description read:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Use a single SQL statement that does all date arithmetic inside the database itself: group rows by the date part of the 'created' column [...] Do not perform any date arithmetic outside of SQL."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every word of that is true, and every word of it is useless to the model that has to decide whether to call the tool. I had written a work order for a compiler and published it as documentation. An agent reading that learns nothing about &lt;em&gt;when this tool is the right answer&lt;/em&gt; — it learns how I wanted the SQL written.&lt;/p&gt;

&lt;p&gt;So I regenerated a third time, with the same requirements in a different order: what the tool returns first, who would want it, what the argument controls, and the implementation constraint last. That is the 3.03-second run in the table, and it is the version now serving.&lt;/p&gt;

&lt;p&gt;The rule that falls out of this is short. &lt;strong&gt;The prompt becomes the docstring, so write it as one.&lt;/strong&gt; Lead with what the tool does and when to use it. Name every argument and its type. Put implementation notes at the end, where they belong — after the sentence a model actually needs.&lt;/p&gt;

&lt;p&gt;Nobody writes tool definitions on this platform. But somebody still has to write the first sentence well, and that somebody is you.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The first generation was wrong.&lt;/strong&gt; It compiled, it verified, it saved, and it threw a 500 the moment I called it — it had tried to subtract dates in a way the runtime found ambiguous. The verifier proves that every instruction in generated code exists and is real; it does not prove the code does what you meant. That still requires running it, which is why I ran it.&lt;/p&gt;

&lt;p&gt;Note the fix, though: I did not open the file. I changed one clause in the prompt and regenerated, 1.83 seconds. When the build path is that short, it is also the repair path — hand-editing generated code is not the workflow here, and does not need to be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your client may not notice immediately.&lt;/strong&gt; The server's catalogue is current the instant the file lands, but most MCP clients fetch the tool list once, when they connect, and cache it. The tool is live, callable, and in the catalogue — your agent just will not see it until you reconnect the connector. This trips people up regularly, and it is a client behaviour, not a server one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two smaller ones.&lt;/strong&gt; Some clients enforce a 64-character limit on tool names; Magic does not truncate, so a very deeply nested module path could produce a name a strict client dislikes. And the transport is plain request/response JSON — a spec-compliant subset, with no SSE stream and no server-initiated messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  One cloudlet, several servers
&lt;/h2&gt;

&lt;p&gt;A last detail worth knowing. The MCP endpoint takes an optional path, which narrows the catalogue to one module subtree — point a client at &lt;code&gt;?path=/modules/crm/&lt;/code&gt; and it sees the CRM tools and nothing else. The narrowing is confined inside &lt;code&gt;modules/&lt;/code&gt; and normalised at both ends, so &lt;code&gt;/modules/crm&lt;/code&gt; cannot leak into a sibling like &lt;code&gt;/modules/crm-archive&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Combine that with the catalogue being assembled per caller — Magic reads the roles on the authenticated ticket and lists only endpoints that caller may execute — and one backend serves as many different, differently-scoped MCP servers as you have audiences for. I made that argument properly in &lt;a href="https://hyperlambda.dev/blog/convert-your-openapi-specification-to-a-secured-mcp-tool-in-seconds" rel="noopener noreferrer"&gt;the OpenAPI article&lt;/a&gt;, so I will not repeat it here.&lt;/p&gt;

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

&lt;p&gt;One command:&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;-fsSL&lt;/span&gt; https://hyperlambda.dev/docker-compose.yaml | docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; - up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;strong&gt;&lt;code&gt;localhost:5555&lt;/code&gt;&lt;/strong&gt;, point it at &lt;strong&gt;&lt;code&gt;localhost:4444&lt;/code&gt;&lt;/strong&gt;, log in with &lt;code&gt;root&lt;/code&gt; / &lt;code&gt;root&lt;/code&gt;, and describe a tool you wish you had. Then connect an agent and look for it.&lt;/p&gt;

&lt;p&gt;Magic is MIT-licensed and open source. The repository is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, with documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The five seconds in the title is the round number. The measured ones were 2.88, 1.83 and 3.03 — and honestly, the seconds are the least interesting thing about it. What matters is that when they elapsed, there was nothing left to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/convert-your-openapi-specification-to-a-secured-mcp-tool-in-seconds" rel="noopener noreferrer"&gt;Convert your OpenAPI Specification to a Secured MCP Tool in Seconds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/the-only-llm-on-earth-that-grows-its-own-tools-securely-on-demand-in-production" rel="noopener noreferrer"&gt;The Only LLM on Earth That Grows Its Own Tools — Securely, On Demand, In Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/zero-hallucination-code-generation-a-vocabulary-your-ai-cannot-escape" rel="noopener noreferrer"&gt;Zero-Hallucination Code Generation: A Vocabulary Your AI Cannot Escape&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/a-complete-crm-in-one-conversation-60-seconds-of-backend-six-cents-of-tokens" rel="noopener noreferrer"&gt;A Complete CRM in One Conversation: 60 Seconds of Backend, Six Cents of Tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/magic-now-supports-mcp-server-integration-for-ai-agents" rel="noopener noreferrer"&gt;Magic Now Supports MCP Server Integration for AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>opensource</category>
      <category>api</category>
    </item>
    <item>
      <title>From Module to GitHub Repository in One Click</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Sat, 08 Aug 2026 06:06:44 +0000</pubDate>
      <link>https://dev.to/polterguy/from-module-to-github-repository-in-one-click-1bpf</link>
      <guid>https://dev.to/polterguy/from-module-to-github-repository-in-one-click-1bpf</guid>
      <description>&lt;p&gt;Yesterday one of my modules became a GitHub repository. The whole ceremony: hover the folder, click the branch icon, write a commit message, click &lt;em&gt;Publish&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Behind that one click, Magic created a private repository on GitHub, added it as the module's &lt;code&gt;origin&lt;/code&gt; remote, pushed the commit, and configured upstream tracking. Four git operations, zero terminal.&lt;/p&gt;

&lt;p&gt;You know the manual version of this dance. Create the repository in GitHub's UI or with &lt;code&gt;gh repo create&lt;/code&gt;, copy the URL, &lt;code&gt;git remote add origin&lt;/code&gt;, &lt;code&gt;git push -u origin master&lt;/code&gt;, and somewhere in the middle a context switch that costs more than all the commands combined. That dance is now a button — because Hyper IDE has Git built in, and this article is the tour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Git lives
&lt;/h2&gt;

&lt;p&gt;Every top level folder inside &lt;code&gt;/modules/&lt;/code&gt; and &lt;code&gt;/etc/&lt;/code&gt; is treated as a repository root. Hover one in Hyper IDE's file tree, and a branch icon appears among its actions — that is the whole discovery story. One repo per module, deliberately: the module is already the unit of install, the unit of deployment, and the unit of meaning in Magic. Now it is the unit of versioning too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3hmqmvt7shick3gvem6l.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3hmqmvt7shick3gvem6l.jpeg" alt="A module folder's action buttons in Hyper IDE's file tree, with the Git branch icon among them" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The panel
&lt;/h2&gt;

&lt;p&gt;Click the icon and you get the state of that repository: which branch you are on, whether you are ahead of or behind your remote, and every modified and untracked file. Commit everything with a message, push, pull, fetch, switch branches, create new ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2136bl8dyufk096nom4a.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2136bl8dyufk096nom4a.jpeg" alt="Hyper IDE's Git panel showing branch, tracking status, and commit actions for a module" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The detail I care most about is what you &lt;em&gt;cannot&lt;/em&gt; click. Push is greyed out until you actually have commits your remote does not. Clone demands an empty folder, because git demands an empty folder. A freshly initialized repository disables everything that requires a commit to exist. The panel teaches you git's rules by construction, instead of relaying git's error messages after the fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  One token, no keychain
&lt;/h2&gt;

&lt;p&gt;Setup is a single dialog: open &lt;em&gt;Configuration&lt;/em&gt;, click the hamburger menu, choose &lt;em&gt;Git…&lt;/em&gt;, and give it your GitHub username and a fine-grained personal access token with &lt;em&gt;Contents&lt;/em&gt; read and write access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fziis4ux320rjg7d66hem.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fziis4ux320rjg7d66hem.jpeg" alt="The Git settings dialog on the Configuration screen, with GitHub username, token and host" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The architecture behind that dialog matters more than the dialog. Credentials are injected per git invocation, over HTTPS, as a header — &lt;em&gt;nothing&lt;/em&gt; is ever written to the server's global git configuration, no credential helper, no SSH keys sitting on disk. And commits are authored as &lt;em&gt;you&lt;/em&gt;: the author name and email are resolved from the signed-in user's profile, so your history on GitHub shows your name, not some shared server identity. The token authenticates transport; people author commits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one click
&lt;/h2&gt;

&lt;p&gt;Back to the headline. Take any module — say one you have been building all week — and open its Git panel. Not a repository yet? Click &lt;em&gt;Initialize repository&lt;/em&gt;. Write a commit message, click &lt;em&gt;Commit&lt;/em&gt;. Then click &lt;em&gt;Publish to GitHub…&lt;/em&gt;, and give the repository a name — it defaults to the module's folder name, which is almost always the right answer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9chc3l75zew7ducupm3h.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9chc3l75zew7ducupm3h.jpeg" alt="Publishing a module to GitHub from Hyper IDE, prompting for the new repository's name" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That click creates the repository on GitHub — &lt;em&gt;private&lt;/em&gt; by default, flip it to public over there if that is what you want — wires it up as &lt;code&gt;origin&lt;/code&gt;, pushes your commit, and sets upstream tracking. Your module has a home, a history, and a URL.&lt;/p&gt;

&lt;p&gt;Notice, &lt;em&gt;creating&lt;/em&gt; repositories needs one more permission than reading and writing them: the account level repository creation permission on your access token, in addition to &lt;em&gt;Contents&lt;/em&gt;. If your token lacks it, the panel will tell you so in plain text, because errors here are never swallowed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The door swings both ways
&lt;/h2&gt;

&lt;p&gt;Publishing is half the story. The other half: create a new &lt;em&gt;empty&lt;/em&gt; folder inside &lt;code&gt;/modules/&lt;/code&gt;, open its Git panel, and you get the mirror options — initialize, or clone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg01pt1hp2u9w0iv2416k.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg01pt1hp2u9w0iv2416k.jpeg" alt="Hyper IDE's Git panel on a folder that is not yet a repository, offering clone and initialize actions" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;em&gt;Clone into folder&lt;/em&gt;, paste the repository's HTTPS URL, and the module lands on your cloudlet with its entire history attached. It checks out whatever the remote's default branch happens to be called — the panel has no opinions in the main-versus-master wars, and after debugging that assumption out of an earlier iteration, neither do I.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7m9xigrkirysvj7gbsv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7m9xigrkirysvj7gbsv.jpeg" alt="Cloning a GitHub repository into a module folder in Hyper IDE, prompting for the HTTPS URL" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Modules travel now
&lt;/h2&gt;

&lt;p&gt;Here is why this is more than a convenience feature.&lt;/p&gt;

&lt;p&gt;Magic has always let you move modules between cloudlets as zip files — download here, install there. A zip is a snapshot. Git is a &lt;em&gt;history&lt;/em&gt;: branches, rollback, blame, and a remote that two cloudlets can both talk to. Develop a module on your dev cloudlet, publish it, clone it into production, and from then on promotion is a &lt;code&gt;pull&lt;/code&gt;. The zip workflow did not go anywhere — but the module you care about, the one that grows for months, wants version control, and now the platform it lives on speaks it natively.&lt;/p&gt;

&lt;p&gt;And because everything in Magic is reachable by agents, the same is true over MCP — the git workflow tools have been callable by AI agents for a while. What is new is that &lt;em&gt;humans&lt;/em&gt; got the good UI too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fine print
&lt;/h2&gt;

&lt;p&gt;Big claims, precise edges — as always.&lt;/p&gt;

&lt;p&gt;This is not a full git client, and it does not want to be. Commit stages &lt;em&gt;everything&lt;/em&gt; the change list shows — there is no per-file staging in v1. There is no diff viewer and no merge-conflict UI; if a pull lands you in conflict territory, clone the repository locally and resolve it with real tooling, then push. The panel covers the module lifecycle — initialize, commit, branch, publish, clone, pull, push — not interactive rebases.&lt;/p&gt;

&lt;p&gt;One deliberate sharp edge worth knowing: paths must be repository &lt;em&gt;roots&lt;/em&gt;. Git's normal upward discovery is disabled on the server, so a folder that is not itself a repo throws instead of silently operating on some enclosing repository it happened to find above itself. That rule exists because during development, the panel on a repo-less folder cheerfully offered to commit the entire Magic source tree it found two levels up. Loud beats silent, every single time.&lt;/p&gt;

&lt;p&gt;The whole feature was built in a day, driving Claude against the running dashboard — including three separate ambushes by a hardcoded &lt;code&gt;main&lt;/code&gt; branch assumption and the discovery bug above. That story, bug ledger and all, is its own article.&lt;/p&gt;

&lt;h2&gt;
  
  
  The keys
&lt;/h2&gt;

&lt;p&gt;Magic is MIT-licensed and open source — the repository is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, with documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;. If you want a cloudlet of your own to publish modules from, it is &lt;a href="https://hyperlambda.dev/blog/magic-cloud-digitalocean-one-copy-paste" rel="noopener noreferrer"&gt;one copy-paste on a $6 DigitalOcean droplet&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/46000-lines-of-angular-gone-in-a-weekend" rel="noopener noreferrer"&gt;46,000 Lines of Angular, Gone in a Weekend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/vibe-coding-without-a-landlord" rel="noopener noreferrer"&gt;Vibe Coding Without a Landlord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/magic-cloud-digitalocean-one-copy-paste" rel="noopener noreferrer"&gt;Magic Cloud + DigitalOcean: One Copy-Paste&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyperlambda.dev/blog/magic-now-supports-mcp-server-integration-for-ai-agents" rel="noopener noreferrer"&gt;Magic Now Supports MCP Server Integration for AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hyperlambda.dev/blog/from-module-to-github-repository-in-one-click" rel="noopener noreferrer"&gt;hyperlambda.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why Claude Is 10x Cheaper When It Builds on Magic Cloud</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Thu, 06 Aug 2026 07:05:32 +0000</pubDate>
      <link>https://dev.to/polterguy/why-claude-is-10x-cheaper-when-it-builds-on-magic-cloud-4n5</link>
      <guid>https://dev.to/polterguy/why-claude-is-10x-cheaper-when-it-builds-on-magic-cloud-4n5</guid>
      <description>&lt;p&gt;Everyone optimizes the wrong variable.&lt;/p&gt;

&lt;p&gt;Cheaper models.&lt;br&gt;
Shorter prompts.&lt;br&gt;
Compressed context.&lt;/p&gt;

&lt;p&gt;That all helps a little.&lt;/p&gt;

&lt;p&gt;But look at Anthropic's rate card instead, and one asymmetry jumps out: output tokens cost 5x input tokens on every current model. Claude Fable 5 is $10 per million tokens in, and &lt;strong&gt;$50 per million tokens out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Which means the most expensive thing your AI agent does is write code as output.&lt;/p&gt;

&lt;p&gt;Magic is architected so it doesn't.&lt;/p&gt;

&lt;p&gt;And rather than argue this in the abstract, we let Claude build a complete full-stack app on our &lt;a href="https://hyperlambda.dev" rel="noopener noreferrer"&gt;hyperlambda.dev&lt;/a&gt; cloudlet — while measuring everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rate card, straight from Anthropic
&lt;/h2&gt;

&lt;p&gt;These are Anthropic's official API prices, per million tokens, fetched from their pricing documentation on August 6, 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5 / 4.8&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 5 (intro, through Aug 31)&lt;/td&gt;
&lt;td&gt;$2&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 4.6 / Sonnet 5 (from Sep 1)&lt;/td&gt;
&lt;td&gt;$3&lt;/td&gt;
&lt;td&gt;$15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 4.5&lt;/td&gt;
&lt;td&gt;$1&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two things are worth staring at.&lt;/p&gt;

&lt;p&gt;First, the output multiple is universal. Every tier charges 5x more for what the model writes than for what it reads.&lt;/p&gt;

&lt;p&gt;Second, Anthropic's newer tokenizer — used by Claude 4.7 and later — produces roughly 30% more tokens for the same text. Round-tripping source code through a model's context literally got more expensive this year.&lt;/p&gt;

&lt;p&gt;Prompt caching and the Batch API can discount those rates. But a discount on waste is still waste. The interesting question is why the tokens are being spent at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a coding agent's tokens actually go
&lt;/h2&gt;

&lt;p&gt;A conventional coding agent building a backend runs a loop.&lt;/p&gt;

&lt;p&gt;Read files. That is input.&lt;br&gt;
Write code. That is output, at 5x.&lt;br&gt;
Read the error. Input again.&lt;br&gt;
Rewrite. Output again.&lt;br&gt;
Re-read to verify. Input again.&lt;/p&gt;

&lt;p&gt;Every debug iteration compounds, and the compounding happens at the most expensive rate on the card. The model is not reasoning in most of those moments. It is acting as a very costly transport layer for source code.&lt;/p&gt;

&lt;p&gt;I have written before about &lt;a href="https://hyperlambda.dev/blog/how-hyperlambda-can-cut-ai-agent-costs-by-75-to-90-percent" rel="noopener noreferrer"&gt;how Hyperlambda changes these economics&lt;/a&gt; and &lt;a href="https://hyperlambda.dev/blog/how-magic-cuts-backend-build-cost-by-80-percent-in-agentic-workflows" rel="noopener noreferrer"&gt;measured roughly 80 percent savings on a Fable-priced build&lt;/a&gt;. This article is about the mechanism underneath those numbers — and a fresh build with its own receipts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built to prove it
&lt;/h2&gt;

&lt;p&gt;We asked Claude to build &lt;strong&gt;Token Ledger&lt;/strong&gt;: an LLM spend tracker.&lt;/p&gt;

&lt;p&gt;Yes, that is deliberately meta. Claude built a token-cost dashboard while its own token cost was being metered.&lt;/p&gt;

&lt;p&gt;The deliverable: a SQLite database with three linked tables — providers, models, and a usage log — seeded with Anthropic's actual rate card from the table above. Fifteen HTTP endpoints, every one of them role-secured. Two aggregation endpoints feeding charts. And a designed, dark, authenticated dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnjtj6p6gm2rznc8d8hka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnjtj6p6gm2rznc8d8hka.png" alt="Token Ledger dashboard — KPI cards, spend by model, spend by day, recent usage table" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at the dashboard's own numbers for a moment. The second KPI card reads "output share of spend: 37%" — on a realistic mixed workload, over a third of the bill is output tokens. And the spend-by-model chart shows Fable 5 dwarfing everything else, because at $50 per million output tokens, it does.&lt;/p&gt;

&lt;p&gt;The app is arguing the article's thesis from inside the screenshot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The build ledger
&lt;/h2&gt;

&lt;p&gt;Wall-clock time was measured with timestamps, not estimated.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live secured backend — database, schema, seed data, 15 endpoints&lt;/td&gt;
&lt;td&gt;222 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complete working app, including the hand-written frontend&lt;/td&gt;
&lt;td&gt;431 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend lines of code generated&lt;/td&gt;
&lt;td&gt;669&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend lines of code hand-written&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude output tokens spent on backend code&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last row is the entire article.&lt;/p&gt;

&lt;p&gt;The backend was produced by twelve calls to Magic's CRUD generator and three calls to its SQL endpoint generator. Each call is a compact declarative argument — a table name, a column list, a role restriction, an SQL statement. Around a hundred tokens each, roughly 1,500 tokens of arguments in total.&lt;/p&gt;

&lt;p&gt;Not one of the 669 generated lines passed through Claude's output stream at $50 per million tokens. The platform wrote them, server-side, using the same battle-tested generators the Magic dashboard uses.&lt;/p&gt;

&lt;p&gt;Honest scope on the numbers: the 222 seconds include reading the platform's guides and setting up the design tokens. Screenshots and end-to-end verification came after the 431-second mark and included two pauses waiting for human tool approval, so they are excluded from the build figures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffin4gjhfuelei5qhmvxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffin4gjhfuelei5qhmvxy.png" alt="Token Ledger login — role-secured entry to the dashboard" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That login screen is not decoration. Every endpoint behind it is gated by Magic's built-in RBAC — no hand-rolled JWT handling anywhere, because there is no hand-written backend anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five mechanisms
&lt;/h2&gt;

&lt;p&gt;Why does this architecture starve the token meter? Five reasons, each visible in the build above.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Declarative calls replace emitted code
&lt;/h3&gt;

&lt;p&gt;One CRUD-generator call is roughly a hundred output tokens of arguments. It produces a complete endpoint — paging, sorting, filtering, validation, auth — of sixty to a hundred and twenty lines. Streaming the equivalent as source code is thousands of output tokens, usually across multiple attempts. In this build, 1,500 tokens of arguments bought 669 lines of backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Code generation happens server-side
&lt;/h3&gt;

&lt;p&gt;When something bespoke is needed, Magic's Hyperlambda Generator takes a plain-English prompt and writes the file on the server. The code never enters Claude's output stream or its input stream. Claude pays for a sentence, not a source file. And here is the stronger version of that point: this particular build needed &lt;strong&gt;zero&lt;/strong&gt; generator calls. The declarative tools covered the entire backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Code never round-trips through context
&lt;/h3&gt;

&lt;p&gt;Magic's operating rules forbid the agent from reading generated Hyperlambda back. Verification goes through live HTTP invocation and the OpenAPI spec. A conventional coding agent re-reads its files constantly — every read is input tokens, every edit is output tokens. On Magic, that loop is not discouraged. It is structurally impossible.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. No debug spirals
&lt;/h3&gt;

&lt;p&gt;The generators are deterministic. There is no generate, error, paste-the-stacktrace, regenerate cycle — the invisible multiplier on every agent bill. This build's complete bug ledger: one entry, a headless-browser viewport quirk while taking &lt;em&gt;screenshots&lt;/em&gt;. Zero bugs in 669 generated backend lines.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. One-call grounding
&lt;/h3&gt;

&lt;p&gt;At session start, one call returns who the agent is, what backend it is on, and its full operating instructions. One more call returns the exact list of capabilities that exist on the instance. Compare that with an agent grepping directories and reading files to discover what a codebase can do — all of it billed as input, none of it producing anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The accounting: same app, two architectures
&lt;/h2&gt;

&lt;p&gt;Take the same deliverable — the Token Ledger backend, fifteen secured endpoints — and price both paths at Anthropic's current rates.&lt;/p&gt;

&lt;p&gt;The Magic column is this build. The coding-agent column is a calibrated estimate for the same result via a conventional file-editing agent — scaffold, routes, auth, validation, and the customary debug loops — consistent with the roughly 140,000-versus-25,000-token gap &lt;a href="https://hyperlambda.dev/blog/how-magic-cuts-backend-build-cost-by-80-percent-in-agentic-workflows" rel="noopener noreferrer"&gt;measured in the July benchmark&lt;/a&gt;, with the backend-code share broken out.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Claude on Magic (measured shape)&lt;/th&gt;
&lt;th&gt;Claude with generic tooling (estimate)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Output tokens spent on backend code&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;~30,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total output tokens, backend slice&lt;/td&gt;
&lt;td&gt;~2,000&lt;/td&gt;
&lt;td&gt;~35,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total input tokens, backend slice&lt;/td&gt;
&lt;td&gt;~30,000&lt;/td&gt;
&lt;td&gt;~180,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost at Fable 5 ($10 / $50)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≈ $0.40&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≈ $3.55&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost at Opus 5 ($5 / $25)&lt;/td&gt;
&lt;td&gt;≈ $0.20&lt;/td&gt;
&lt;td&gt;≈ $1.78&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost at Sonnet 4.6 ($3 / $15)&lt;/td&gt;
&lt;td&gt;≈ $0.12&lt;/td&gt;
&lt;td&gt;≈ $1.07&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Call it roughly 9x on this app, and the estimate columns are labeled as exactly that — estimates. The ratio is not a constant of nature. It is a consequence of one design decision: source code, the most expensive thing a model can emit, never enters the token stream.&lt;/p&gt;

&lt;p&gt;And notice what happens as the app grows. A CRUD-generator argument is about a hundred tokens whether the table has three columns or thirty. Hand-written code is not. The gap widens with size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where 10x holds — and where it is 5x
&lt;/h2&gt;

&lt;p&gt;Now the honest fine print.&lt;/p&gt;

&lt;p&gt;The July benchmark measured roughly 80 percent — 5x — across a full session, because a real session also contains reasoning, planning, schema decisions, and verification, and those do not compress. The frontend in this build was hand-written by the agent, at normal output rates, and took as long as the entire backend.&lt;/p&gt;

&lt;p&gt;The 10x figure belongs to the code-emission slice of the work: the backend, the endpoints, the auth, the data layer. On backend-heavy agentic workloads that slice dominates, and the blended number climbs toward it. On reasoning-heavy work, expect the 5x, not the 10x.&lt;/p&gt;

&lt;p&gt;Both numbers are worth having. Neither requires exaggeration.&lt;/p&gt;

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

&lt;p&gt;The standard advice for cutting Claude costs is to pick a smaller model, cache your prompts, and batch your jobs. All fine. All discounts on the same architecture.&lt;/p&gt;

&lt;p&gt;Magic changes the architecture. The agent stops being a code emitter paying $50 per million tokens for the privilege, and becomes an operator of a platform that already knows how to build backends — declaratively, server-side, with security enforced by the runtime instead of regenerated per project.&lt;/p&gt;

&lt;p&gt;We measured it: a live, role-secured, fifteen-endpoint backend in 222 seconds, 669 lines generated, zero lines through the token meter.&lt;/p&gt;

&lt;p&gt;Claude is a great engineer. Stop paying it by the line.&lt;/p&gt;

&lt;p&gt;Magic is MIT-licensed and open source — the repository is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, with documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hyperlambda.dev/blog/why-claude-is-10x-cheaper-when-it-builds-on-magic-cloud" rel="noopener noreferrer"&gt;hyperlambda.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>lowcode</category>
      <category>backend</category>
    </item>
    <item>
      <title>Break my AI Sandbox and make $100 - Psst, nobody's done it yet!</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Sat, 01 Aug 2026 10:10:45 +0000</pubDate>
      <link>https://dev.to/polterguy/break-my-ai-sandbox-and-make-100-psst-nobodys-done-it-yet-2b9n</link>
      <guid>https://dev.to/polterguy/break-my-ai-sandbox-and-make-100-psst-nobodys-done-it-yet-2b9n</guid>
      <description>&lt;p&gt;I have a standing offer: find a verified security bug in Magic's backend — the C# code or the Hyperlambda runtime — and I'll pay you $100.&lt;/p&gt;

&lt;p&gt;Nobody has collected.&lt;/p&gt;

&lt;p&gt;$100 is obviously not the point. Companies pay 100 times that for bounties on software with a fraction of the attack surface. The point is that I'm willing to put money on the architecture, publicly, permanently — because the architecture is the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The runtime is the security boundary
&lt;/h2&gt;

&lt;p&gt;Most AI coding tools work like this: the model generates free-form code, and you &lt;em&gt;hope&lt;/em&gt; it generated something safe. The model is the security boundary. Which means every prompt injection, every hallucination, every "ignore previous instructions" is a potential breach.&lt;/p&gt;

&lt;p&gt;Hyperlambda inverts this. The AI generates code, but the &lt;em&gt;runtime&lt;/em&gt; decides what executes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hyperlambda is not free-form code. It's a declarative structure that parses into an AST, and the runtime validates that AST before anything runs.&lt;/li&gt;
&lt;li&gt;Slots are whitelisted. If a slot isn't on the whitelist for the current context, it doesn't execute. Period. The AI can hallucinate whatever it wants — the runtime says no.&lt;/li&gt;
&lt;li&gt;RBAC is enforced at &lt;em&gt;execution time&lt;/em&gt;, not generation time. It doesn't matter what code was generated or by whom. If your JWT doesn't carry the role, the invocation is refused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the AI writes something it shouldn't run, the runtime says no. That single sentence is the difference between a demo and something a regulated company can ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Receipts
&lt;/h2&gt;

&lt;p&gt;I don't expect you to take my word for it. In April I let Claude Code — one of the strongest code-analysis agents available — loose on the entire Magic codebase with explicit instructions to break it.&lt;/p&gt;

&lt;p&gt;It found real issues. All hardening, none sandbox escapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No cap on request body size, allowing a memory-exhaustion DoS. Fixed.&lt;/li&gt;
&lt;li&gt;Missing timeouts that left the server exposed to Slowloris-style slow-drip attacks. Fixed.&lt;/li&gt;
&lt;li&gt;An edge case in path resolution that needed an explicit traversal guard. Fixed.&lt;/li&gt;
&lt;li&gt;A debug statement leaking information to the console. Removed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here's what it &lt;em&gt;couldn't&lt;/em&gt; do, after crawling roughly 9,000 commits accumulated over some 7 years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No SQL injection. Every database access goes through parameterized ADO.NET.&lt;/li&gt;
&lt;li&gt;No password extraction. BCrypt with per-user salts.&lt;/li&gt;
&lt;li&gt;No secrets leakage. AES-GCM for storage.&lt;/li&gt;
&lt;li&gt;No auth bypass. Standard JWT, correctly implemented.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No sandbox escape.&lt;/strong&gt; Every attempt to execute something outside the whitelisted slots was refused by the runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full write-up is here: &lt;a href="https://hyperlambda.dev/blog/claude-code-tried-to-break-magic-cloud-and-mostly-ended-up-confirming-its-security" rel="noopener noreferrer"&gt;Claude Code tried to break Magic Cloud, and mostly ended up confirming its security&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fou4in3lslsgm8p3bhrmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fou4in3lslsgm8p3bhrmi.png" alt="The Hyperlambda playground" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why free-form codegen can't make this offer
&lt;/h2&gt;

&lt;p&gt;Think about what it would take for an AI agent platform built on free-form code generation to make the same offer.&lt;/p&gt;

&lt;p&gt;They'd be paying out daily. When the model is the boundary, one clever prompt is a breach. The industry's answer so far has been layers of prompt-level guardrails — instructions asking the model to please behave. That's not security. That's etiquette.&lt;/p&gt;

&lt;p&gt;When the runtime is the boundary, the model's behavior becomes almost irrelevant to your security posture. The model can be jailbroken, poisoned, or just plain wrong — and the blast radius is a refused invocation and a log entry.&lt;/p&gt;

&lt;p&gt;This is why I can put a standing bounty on it. The security claim isn't "our AI is well-behaved." The claim is "the runtime refuses everything that isn't explicitly allowed." That's a falsifiable, testable claim — so go test it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to collect
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://playground.hyperlambda.dev" rel="noopener noreferrer"&gt;playground.hyperlambda.dev&lt;/a&gt; and hammer it. Or self-host — the whole thing is MIT licensed, so you can read every line of the code you're attacking.&lt;/li&gt;
&lt;li&gt;Find a verified bug in the backend C# or Hyperlambda code. Sandbox escape, RBAC bypass, executing a non-whitelisted slot — anything that breaks the security model.&lt;/li&gt;
&lt;li&gt;Send it to me. I verify it, I fix it, I pay you $100, and I'll publicly credit you for the find.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Prompt-level shenanigans against the AI itself don't count — making a chatbot say something silly is not a runtime breach. The claim under test is the runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you're evaluating AI agent platforms
&lt;/h2&gt;

&lt;p&gt;Ask every vendor you're talking to one question: &lt;em&gt;what happens when the AI generates something it shouldn't?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If the answer involves the words "the model is trained to" or "our system prompt instructs" — you're buying etiquette, not security. If the answer is a deterministic runtime mechanism you can read the source code of, you're buying engineering.&lt;/p&gt;

&lt;p&gt;Magic has been running in production since 2020. It's MIT licensed. The code is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, and the docs are at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Break it and make $100. Psst — nobody's done it yet.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hyperlambda.dev/blog/break-my-ai-sandbox-and-make-100-psst-nobodys-done-it-yet" rel="noopener noreferrer"&gt;hyperlambda.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Turn Your Legacy SQL Server Database into a Modern Full Stack App in Minutes</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Fri, 31 Jul 2026 20:42:35 +0000</pubDate>
      <link>https://dev.to/polterguy/turn-your-legacy-sql-server-database-into-a-modern-full-stack-app-in-minutes-dff</link>
      <guid>https://dev.to/polterguy/turn-your-legacy-sql-server-database-into-a-modern-full-stack-app-in-minutes-dff</guid>
      <description>&lt;p&gt;The app in the screenshots below took 7 minutes to build.&lt;/p&gt;

&lt;p&gt;Not a mockup. A login screen backed by JWT authentication, a client manager reading and writing through a role-secured CRUD API, and an Emails tab that dispatches real messages over SMTP. The backend was produced by wrapping a database in generated CRUD endpoints, plus one English sentence handed to the Hyperlambda Generator for the send-email endpoint.&lt;/p&gt;

&lt;p&gt;I have published the receipts for builds like this before, so this article is not another ledger.&lt;/p&gt;

&lt;p&gt;It is about the part of those 7 minutes that usually gets lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The database was the boring part
&lt;/h2&gt;

&lt;p&gt;Nothing in the build depended on the database being new.&lt;/p&gt;

&lt;p&gt;The CRUD generator does not care where a schema came from. It reads metadata — tables, columns, types, keys — and every Microsoft SQL Server database on earth exposes exactly that. The database in this demo was created seconds before the endpoints were. Yours carries twenty years of history, three generations of developers, and foreign keys that encode how your business actually works.&lt;/p&gt;

&lt;p&gt;Same metadata. Same generator. Same 7 minutes.&lt;/p&gt;

&lt;p&gt;That is the entire point. The demos always run on fresh databases because demos need reproducibility — but the machinery only ever sees the schema, and your ERP on SQL Server has a better schema than any demo. The hard part of a full stack app — modelling the business correctly — is the part you finished years ago.&lt;/p&gt;

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

&lt;p&gt;The front door. JWT authentication against the platform's built-in auth — no auth library, no password hashing code, no session plumbing anywhere in the app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1wtogq0y3nf3edi6zpw7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1wtogq0y3nf3edi6zpw7.webp" alt="The login screen — JWT authentication handled by the platform, zero auth code in the application" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The client manager. Search, add, edit, delete, and per-client notes — every operation travelling through generated CRUD endpoints, each one gated on a role before any logic runs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fues7ht7wxkmuioyg2mae.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fues7ht7wxkmuioyg2mae.webp" alt="The client manager — search, status badges and per-client notes over generated CRUD endpoints" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the one endpoint that is not a table projection: composing an email to a client, dispatched through the platform's SMTP integration. That endpoint was described in a single English sentence and generated in seconds — the application never saw a mail-provider credential, because there is none in the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnhf7119skgmcsch2cvnl.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnhf7119skgmcsch2cvnl.webp" alt="The Emails tab — a generated endpoint looks up the client and dispatches through platform SMTP" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe
&lt;/h2&gt;

&lt;p&gt;Four moves.&lt;/p&gt;

&lt;p&gt;Connect the database. Magic speaks to SQL Server through the standard .NET data provider — it is one more client, nothing installed inside the database, no schema changes.&lt;/p&gt;

&lt;p&gt;Wrap the tables. The CRUD generator reads the schema and emits endpoints — read, create, update, delete, count — with authentication and role-based access control already wired in.&lt;/p&gt;

&lt;p&gt;Describe what CRUD cannot do. "Look up this client's email address and send them a message" is one sentence, and the Hyperlambda Generator turns it into a working, role-gated endpoint.&lt;/p&gt;

&lt;p&gt;Serve the frontend. The same system that serves the API serves static files, so the app's HTML, CSS and JavaScript went live the moment they were written. One host, no CORS, no separate deployment.&lt;/p&gt;

&lt;p&gt;The full walkthrough — scoped database users, read-only starts, connecting an agent over MCP — is its own article: &lt;a href="https://hyperlambda.dev/blog/create-an-ai-agent-from-your-sql-server-or-mysql-database-step-by-step" rel="noopener noreferrer"&gt;Create an AI Agent From Your SQL Server or MySQL Database, Step by Step&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  No agent required
&lt;/h2&gt;

&lt;p&gt;This build ran through an AI agent over MCP, but the CRUD wrap does not need one. The dashboard's Backend Generator does the same thing point-and-click: pick the database, tick the tables, choose which roles may call what, and click Generate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsdhzs9il7h0x3nl9ybua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsdhzs9il7h0x3nl9ybua.png" alt="The Backend Generator — pick a database, tick tables, choose roles, and generate the CRUD API from the dashboard" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same generated endpoints, same enforcement, no conversation required. The agent is a convenience, not a dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  "But my database is legacy"
&lt;/h2&gt;

&lt;p&gt;Legacy means load-bearing, not obsolete — I have made that argument at length in &lt;a href="https://hyperlambda.dev/blog/supabase-for-sql-server-and-mysql-magic-brings-the-supabase-experience-to-legacy-databases-on-premise" rel="noopener noreferrer"&gt;Supabase for SQL Server and MySQL&lt;/a&gt;, so here is the short version.&lt;/p&gt;

&lt;p&gt;You connect through a scoped database user, so the platform can never do more than the credentials the DBA granted. You can start read-only, which turns "what if something writes the wrong thing" into a non-question for day one. And the whole stack runs in two containers you place yourself — same rack, same VLAN, same firewall the auditors already approved. The database does not change, and the data does not leave.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fine print
&lt;/h2&gt;

&lt;p&gt;Seven minutes was measured for this schema, at this size. Your 200-table ERP will take longer — but the added time goes into decisions, not code: which tables deserve exposure, which operations each table gets, which roles may call them. Those are judgment calls a DBA is already equipped to make, and they were never the expensive part.&lt;/p&gt;

&lt;p&gt;The frontend is where human taste still spends its time. Generated backends are uniform; good interfaces are not.&lt;/p&gt;

&lt;p&gt;And writes deserve the same respect they have always deserved. Start read-only, prove the surface, then grant writes table by table. The speed changes nothing about the discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question worth asking
&lt;/h2&gt;

&lt;p&gt;The question is no longer whether your organisation can afford to modernise the systems built on SQL Server. It is whether wrapping one of them in a secured API and a working app is still a project at all — or just an afternoon.&lt;/p&gt;

&lt;p&gt;Magic is MIT-licensed and open source at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, with documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>sqlserver</category>
      <category>dotnet</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>46,000 Lines of Angular, Gone in a Weekend</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Mon, 27 Jul 2026 07:14:31 +0000</pubDate>
      <link>https://dev.to/polterguy/46000-lines-of-angular-gone-in-a-weekend-2nal</link>
      <guid>https://dev.to/polterguy/46000-lines-of-angular-gone-in-a-weekend-2nal</guid>
      <description>&lt;p&gt;I replaced the entire Magic Cloud dashboard this week. Forty-six thousand lines of Angular — HTML, TypeScript and CSS — gone, and in its place a React application of fifteen and a half thousand lines that does more than the thing it replaced.&lt;/p&gt;

&lt;p&gt;Twenty hours of coding. Thirty hours in total, counting my own reviewing, testing and swearing.&lt;/p&gt;

&lt;p&gt;I know exactly what that job costs when you do it by hand, because I have already done it by hand. In 2021 I rewrote this same dashboard the traditional way. A senior developer worked on it for a month and a half. Then I picked it up and worked on it for months more. Call it a three-month job for two experienced developers who knew the domain cold.&lt;/p&gt;

&lt;p&gt;That comparison is the only reason this article is worth writing. Anyone can claim an AI wrote a lot of code quickly. Very few people have the same application, built twice, by the same author, with the same requirements — where the only variable that changed is the tooling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn3l7uxktp24ybspfna8l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn3l7uxktp24ybspfna8l.png" alt="The new Magic Cloud dashboard, showing KPI cards, the MCP agent banner and the Chatbot Wizard" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The ledger
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Then&lt;/th&gt;
&lt;th&gt;Now&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Angular&lt;/td&gt;
&lt;td&gt;React 18 + Vite + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines of code&lt;/td&gt;
&lt;td&gt;~46,000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15,497&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files&lt;/td&gt;
&lt;td&gt;many hundreds&lt;/td&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime dependencies&lt;/td&gt;
&lt;td&gt;the Angular universe&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production build&lt;/td&gt;
&lt;td&gt;tens of MB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;856 KB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build time&lt;/td&gt;
&lt;td&gt;minutes&lt;/td&gt;
&lt;td&gt;~1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to write&lt;/td&gt;
&lt;td&gt;~3 months, two people&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30 hours, one person supervising&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A word on that line-count comparison, because it is the kind of number people rightly poke at. Angular splits a single component across a &lt;code&gt;.ts&lt;/code&gt; file, an &lt;code&gt;.html&lt;/code&gt; template and an &lt;code&gt;.scss&lt;/code&gt; stylesheet. React folds all three into one &lt;code&gt;.tsx&lt;/code&gt;. Counting the old TypeScript against the new TypeScript would flatter me dishonestly, so both sides count everything: markup, logic and styling. Forty-six thousand against fifteen and a half.&lt;/p&gt;

&lt;p&gt;The dependency line matters more than it looks. The whole application runs on React, React-DOM, React Router, CodeMirror, SignalR, &lt;code&gt;marked&lt;/code&gt; and DOMPurify. That is the entire third-party surface. There is no state management library, no component library, no CSS framework, no build plugin zoo. When your dependency list fits in one sentence, upgrades stop being events.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it actually ran
&lt;/h2&gt;

&lt;p&gt;I drove Claude — Fable for the bulk of the work, Opus for the parts that needed more thinking. The model wrote essentially all of the code. My job was to babysit: sanity-check what came back, test it in a browser, catch the things that were confidently wrong, and decide what to build next.&lt;/p&gt;

&lt;p&gt;The loop that made it work was not "describe the feature and hope." It was: screenshot the old Angular screen, build the new one, screenshot the new one, compare them, fix the gap. Verification happened against rendered pages, not against source code. That distinction matters, because a model reading old Angular source will faithfully reproduce old Angular mistakes. A model looking at what the screen actually does will build what the screen actually does.&lt;/p&gt;

&lt;p&gt;Below is what came out of that loop, screen by screen — because the interesting claim is not that thirty hours produced &lt;em&gt;code&lt;/em&gt;, it is that thirty hours produced &lt;em&gt;this much working software&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Login
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc18yybx3aa2lvp0rgfee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc18yybx3aa2lvp0rgfee.png" alt="The Magic login screen with backend selector, magnetic link and Google sign-in" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The dashboard talks to any Magic backend, so the first thing it needs is which one. The backend selector remembers every cloudlet you have ever signed into and keeps a separate JWT for each, so switching between them does not mean signing in again.&lt;/p&gt;

&lt;p&gt;Underneath the password field are two things the Angular version never had. &lt;strong&gt;Magnetic link&lt;/strong&gt; sends a temporary sign-in link to your email — it doubles as passwordless login, and it only appears if the backend actually has SMTP configured, because offering it otherwise is a dead end. &lt;strong&gt;Continue with Google&lt;/strong&gt; signs you in over OIDC against whatever providers the backend has registered. Both were built during this port, not ported into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboard
&lt;/h2&gt;

&lt;p&gt;The landing screen answers "what is this cloudlet, and is anything wrong with it" in one glance: version, endpoint count, users, tasks, log items.&lt;/p&gt;

&lt;p&gt;Two panels below that are new. The first announces that &lt;strong&gt;your cloudlet is an AI agent&lt;/strong&gt; — with the MCP plugin installed, the URL shown there hands any MCP-capable agent your endpoints as callable tools. Claude, or anything else speaking the protocol, can discover and invoke them directly.&lt;/p&gt;

&lt;p&gt;The second is the &lt;strong&gt;Chatbot Wizard&lt;/strong&gt;, which runs the other direction: give it a website, pick a model and a persona, and the backend crawls the site, turns what it finds into training data, and gives you an embeddable chatbot grounded in your own content. The crawl takes minutes and reports progress over a SignalR channel, so the feedback window opens &lt;em&gt;before&lt;/em&gt; the job starts — a socket that connects late misses the first messages. You can close the window; the crawl carries on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hyper IDE
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy4gyvqeifietyxqeejq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy4gyvqeifietyxqeejq9.png" alt="Hyper IDE with a Hyperlambda file open, a dirty tab marker, and the slot autocomplete popup showing" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file manager and code editor for everything on your server, and the component that absorbed the most work.&lt;/p&gt;

&lt;p&gt;The tree browses the whole backend file system. Files open as &lt;strong&gt;tabs&lt;/strong&gt;, several at once, and each tab tracks whether it is dirty — a dot appears on the tab and beside the path in the header the moment you change something, and navigating away asks before discarding it. The editor runs a Hyperlambda mode ported from the old dashboard, so slot invocations are coloured correctly, and &lt;strong&gt;Ctrl+Space completes against the backend's actual vocabulary&lt;/strong&gt; — the list of slots is fetched from the server you are connected to, and cached per backend, because two cloudlets with different plugins know different slots. That is the popup in the screenshot above, listing the &lt;code&gt;log.*&lt;/code&gt; slots this particular cloudlet knows about.&lt;/p&gt;

&lt;p&gt;Executing a file is smarter than it was. If the file is a real HTTP endpoint — it ends in &lt;code&gt;.get.hl&lt;/code&gt;, &lt;code&gt;.post.hl&lt;/code&gt; and friends, and lives under &lt;code&gt;/modules/&lt;/code&gt; or &lt;code&gt;/system/&lt;/code&gt; — the IDE invokes it as an endpoint, with arguments, and shows you the status code and response headers. Only files that are not endpoints get evaluated directly. You can upload and download files, preview HTML, XML, images, JavaScript and CSS straight from &lt;code&gt;/etc/www/&lt;/code&gt;, and press F1 on any selection to ask the AI what it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Playground
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6t19orvr900t3aradjg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6t19orvr900t3aradjg0.png" alt="The Hyperlambda Playground with a data.read example and its result pane" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hyperlambda, executed on your server, without saving anything first. Input on the left, result on the right, F5 to run. It is the scratchpad you reach for when you want to know what a slot actually returns, and it saves snippets when the scratch turns out to be worth keeping.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL Studio
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8edktw394ihvetbktuy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8edktw394ihvetbktuy.png" alt="SQL Studio with a query written against the chinook database" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two tabs over the same three selectors: database type, connection string, database.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;SQL&lt;/strong&gt; tab is a query editor with syntax colouring, Ctrl+Space completion over your real tables and columns, saved snippets, &lt;code&gt;.sql&lt;/code&gt; import, CSV export of results, and a Safe mode toggle that caps what a careless query can do. Selecting part of the text executes only the selection.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Designer&lt;/strong&gt; tab is the one I am quietest about and proudest of. It renders every table in the database as a card — primary keys, column types, nullability, and the foreign keys spelled out underneath — and lets you add tables, add columns and wire up relations without writing DDL. It will also hand you the DDL for a single table or the whole database if you would rather write it yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faxumu6rdhk27fpq2rqvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faxumu6rdhk27fpq2rqvf.png" alt="The SQL Studio Designer tab rendering chinook tables as schema cards with foreign keys" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Databases
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9s05kbp1hmn30e308nes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9s05kbp1hmn30e308nes.png" alt="The Databases screen listing SQLite databases with table counts" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create SQLite databases, back them up, restore them from an uploaded backup, delete the ones you no longer need — and, on the second tab, connect to external MySQL, PostgreSQL and SQL Server instances. Everything else in the dashboard then treats those exactly like a local database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generator
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2w0appui4pdnq6dbm3qf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2w0appui4pdnq6dbm3qf.png" alt="The Generator screen with chinook tables selected and CRUD options" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Point it at a database, tick the tables, and it writes you a complete CRUD backend: POST, GET, PUT and DELETE per table, with paging, sorting, aggregates, distinct and search endpoints if you want them. You choose which roles may call what, whether writes are logged, how long GET responses may be cached, and whether existing files may be overwritten. The second tab wraps a custom SQL statement in an endpoint of its own.&lt;/p&gt;

&lt;p&gt;This is the part that turns a schema into a secured API in seconds, and it is why the backend is rarely where the time goes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Endpoints
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiynm5x308yn6yxywlahh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiynm5x308yn6yxywlahh.png" alt="The Endpoints screen with modules expanded showing HTTP verb badges" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every endpoint on the backend, grouped by module, with its HTTP verb. Open one and you get a form built from its actual arguments — fill them in, invoke it, and see the status code, the response headers and the body rendered according to its content type.&lt;/p&gt;

&lt;p&gt;It handles files in both directions now, which it did not before: endpoints that accept &lt;code&gt;multipart/form-data&lt;/code&gt; get a proper file picker with image thumbnails inline, and endpoints that return files offer them as downloads. Each module will also hand you its OpenAPI specification, which is how you point an external tool — or an agent — at a subset of your API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Users and roles
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1t8ynapnt41vwmcjaext.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1t8ynapnt41vwmcjaext.png" alt="The Users and roles screen listing users with their roles" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Who may reach your backend, and what they may do. Create users, assign roles, change passwords, lock accounts. Roles are the same objects the Generator gates endpoints with and the same ones inside the JWT, so this screen is the authorisation surface for the entire platform in one table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task Manager
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9e9s9d90o5ep4t6idixq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9e9s9d90o5ep4t6idixq.png" alt="The Task Manager listing scheduled Hyperlambda tasks" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hyperlambda that runs on a schedule or on demand — backups, cleanup jobs, crawls, alerts. Tasks can repeat on an interval, fire once at a fixed date, or follow a custom repetition pattern, and you can execute any of them immediately to see what happens. Executing asks first, because a task named &lt;code&gt;delete-old-log-items&lt;/code&gt; means it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Machine Learning
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmoamj1a6gwo0no8fpis.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmoamj1a6gwo0no8fpis.png" alt="The Machine Learning screen listing models with import, vectorise and embed actions" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The largest single screen in the application, at two thousand lines. Models define which LLM answers, at what temperature, with what system message and what threshold. Training data is the content those models answer from — crawled from a site, uploaded as files, or written by hand. Vectorising turns it into embeddings; embedding hands you the snippet that drops the finished chatbot onto a web page. A history tab shows what people actually asked it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugins
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwm5jiqxhfbkmi4pv2cx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwm5jiqxhfbkmi4pv2cx.png" alt="The Plugins screen showing available Bazar modules" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Bazar: MCP, OAuth, OpenAI, Ollama, HuggingFace, Shopify, HubSpot, NetSuite, scraping, charts, and a couple of dozen more. One click installs a module into your cloudlet, endpoints and all. You can also install your own from a ZIP file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Profile
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F33razafuptqnwwr9eomz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F33razafuptqnwwr9eomz.png" alt="The Profile screen with details, password change and access token generation" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your name, your email, your password — and &lt;strong&gt;access tokens&lt;/strong&gt;, which is the part that matters operationally. Generate a long-lived JWT for a service account, a CI pipeline or an integration, scoped to the roles you pick and expiring on a date you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Log
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feq9bs6yumty8jrqli6ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feq9bs6yumty8jrqli6ik.png" alt="The Log screen listing backend log entries by type and time" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What your backend has been doing, newest first, filterable, with severity on every row. It is where you go when something did not work, and the generated CRUD endpoints write to it automatically when you ask them to log writes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What got better, not just moved
&lt;/h2&gt;

&lt;p&gt;If this had been a straight translation I would not have bothered writing about it. The features that did not exist in the Angular version, all built inside those same thirty hours:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OIDC login&lt;/strong&gt; — sign in with Google or any registered provider&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File upload and download through the Endpoints screen&lt;/strong&gt;, with inline image previews&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dirty-file tracking&lt;/strong&gt; across Hyper IDE, SQL Studio and the Playground&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple files open at once&lt;/strong&gt;, as tabs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-backend support&lt;/strong&gt; with a separate JWT per cloudlet and shareable &lt;code&gt;?backend=&lt;/code&gt; links&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Magnetic-link login&lt;/strong&gt; for passwordless sign-in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The MCP agent banner&lt;/strong&gt; and the &lt;strong&gt;Chatbot Wizard&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Previewing&lt;/strong&gt; HTML, XML, images, JavaScript and CSS from &lt;code&gt;/etc/www/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An AI support agent on F1&lt;/strong&gt;, answering from the Hyperlambda and Magic documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bug ledger
&lt;/h2&gt;

&lt;p&gt;Two rules make this kind of build survivable: the model writes, and a human reviews everything before it lands. Here is what the review caught.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React's StrictMode caused three separate bugs.&lt;/strong&gt; It deliberately runs effects twice in development, which broke an image preview (the object URL was revoked before the image loaded), killed a SignalR connection (started and stopped in the same tick), and made two stacked dialogs land on the same z-index. All three were the same root cause wearing different hats, and all three were found by looking at the screen, not the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The model invented a slot that does not exist.&lt;/strong&gt; It used &lt;code&gt;date.add&lt;/code&gt; for date arithmetic. There is no such slot. The fix was &lt;code&gt;math.add&lt;/code&gt; with a &lt;code&gt;time&lt;/code&gt; node — the pattern already used elsewhere in the codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It invented a role, too.&lt;/strong&gt; It gated the dashboard on an &lt;code&gt;admin&lt;/code&gt; role. The backend has 159 endpoints and every one of them checks &lt;code&gt;root&lt;/code&gt;. Caught during review, renamed everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A mail endpoint was built with the wrong node shape&lt;/strong&gt;, which produced a runtime error rather than an email. &lt;strong&gt;A magnetic link took three attempts&lt;/strong&gt; to redirect correctly, because the token was being stripped from the URL before a second render could read it. &lt;strong&gt;An expired token walked straight into the dashboard&lt;/strong&gt;, because expiry was being checked without asking the server whether the token was still valid.&lt;/p&gt;

&lt;p&gt;And two mistakes the model made about its own work, which I include because they are the most instructive of the lot. It told me one screen had no confirmation dialog before running a destructive task — it had searched the code in a way that could not have found the guard, which was sitting six lines above what it read. And it told me a screenshot I had pushed did not exist, when the file was recoverable the whole time. Both were confidently wrong, and both were wrong in the same direction: &lt;em&gt;reporting an absence after looking in the wrong place.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nothing on this list shipped. But the list is the honest cost of the method, and anyone telling you their AI build had no such list is not counting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this actually demonstrates
&lt;/h2&gt;

&lt;p&gt;It would be easy to read this as "AI writes code fast." That is not the finding, and it is not what changed.&lt;/p&gt;

&lt;p&gt;The expensive part of the 2021 rewrite was never typing. It was reading the old implementation to work out what a screen did in the edge cases, holding forty-odd screens' worth of behaviour in your head, and checking parity one control at a time. That is the part that compressed. The model does not get bored on screen thirty-one, and it does not skip the tedious parts of the Machine Learning page because the Dashboard was more fun.&lt;/p&gt;

&lt;p&gt;What did not change is who is responsible. I reviewed everything. I found the invented slot, the invented role, and the token that should not have been trusted. The ratio moved; the accountability did not. Thirty hours with a competent reviewer is not the same thing as thirty hours unattended, and I would not claim otherwise.&lt;/p&gt;

&lt;p&gt;Three months to thirty hours, on the same application, by the same person. That is the number I would want to see from someone else before I believed any of this, so it is the number I am publishing.&lt;/p&gt;

&lt;p&gt;Magic is MIT-licensed and open source — the repository is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, with documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>react</category>
      <category>angular</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Everything Supabase Does Not Have, in One Video: An AI Agent Builds a Role-Secured CRM</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Fri, 24 Jul 2026 13:05:35 +0000</pubDate>
      <link>https://dev.to/polterguy/everything-supabase-does-not-have-in-one-video-an-ai-agent-builds-a-role-secured-crm-1oen</link>
      <guid>https://dev.to/polterguy/everything-supabase-does-not-have-in-one-video-an-ai-agent-builds-a-role-secured-crm-1oen</guid>
      <description>&lt;p&gt;Supabase is a good product. I have written about it &lt;a href="https://hyperlambda.dev/blog/magic-cloud-the-self-hosted-supabase-alternative-built-for-ai-agents" rel="noopener noreferrer"&gt;approvingly&lt;/a&gt;, I have shown how to &lt;a href="https://hyperlambda.dev/blog/how-to-run-ai-agents-on-your-existing-supabase-database-without-migrating-anything" rel="noopener noreferrer"&gt;run AI agents on top of an existing Supabase database&lt;/a&gt;, and none of that changes today.&lt;/p&gt;

&lt;p&gt;But there is a list of things Supabase does not have. Not "does worse" — does not have. And instead of writing that list as a feature matrix, I recorded a video where every item on it gets used, in one conversation, by an AI agent building a complete CRM from a single prompt.&lt;/p&gt;

&lt;p&gt;The prompt was one paragraph: create an app named crm6 — a database with three tables, a CRUD web API, the ability to send emails to contacts, and a modern frontend, with the whole API restricted to users in the "guest" role. The agent — Claude, connected over Magic's MCP server — did the rest. This article walks through what it built, and points out, at each step, the capability it leaned on that Supabase does not ship.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;An SQLite database with three tables — contacts, deals, and activities — with foreign keys, defaults, and seed data.&lt;/li&gt;
&lt;li&gt;Sixteen HTTP endpoints: full GET/POST/PUT/DELETE plus record counts for every table, and a send-email endpoint — every one of them restricted to the "guest" role.&lt;/li&gt;
&lt;li&gt;Email dispatch that looks up a contact by id and sends through the platform's SMTP integration.&lt;/li&gt;
&lt;li&gt;A designed frontend — JWT login against Magic's built-in auth, a KPI dashboard with a pipeline chart, searchable contacts with an email composer, a drag-and-drop deals kanban, and an activities list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2x6fklqwsuoyunyyplfm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2x6fklqwsuoyunyyplfm.jpg" alt="The crm6 dashboard — KPI cards, pipeline by stage, upcoming activities" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Total hand-written backend code: zero lines. The CRUD layer was produced by the crudifier — twelve declarative calls, 722 lines of generated Hyperlambda, each call returning in well under a second. The send-email endpoint was generated from a plain-English prompt in 7.6 measured seconds. The only thing authored line by line was the frontend, and the agent wrote that too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch the build
&lt;/h2&gt;

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

&lt;p&gt;Now the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. A backend that generates itself
&lt;/h2&gt;

&lt;p&gt;Supabase gives you PostgREST: a generic REST reflection of your schema. That is genuinely useful, and it is also where it ends. The moment you need an endpoint that is not a table projection — "look up this contact's email address and send them a message, and throw if the contact does not exist" — you are writing an edge function by hand, in TypeScript, with your own error handling, and deploying it yourself.&lt;/p&gt;

&lt;p&gt;On Magic the agent described that endpoint in one English sentence, and the Hyperlambda Generator produced it, saved it, and put it on the wire — role-gated like everything else — in 7.6 seconds. The backend is not a reflection of the schema. It is generated, customizable code, produced from intent.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Access control the agent cannot code its way out of
&lt;/h2&gt;

&lt;p&gt;This is the structural one, and the reason the video is possible at all.&lt;/p&gt;

&lt;p&gt;Supabase's security model is row-level security: SQL policies you write per table, per app. When an AI agent generates your application code, every generated query and every generated function has to correctly respect those policies — and the service-role key that bypasses them is sitting right there in the environment. The security boundary lives inside generated code, which means every generation is a fresh chance to get it wrong.&lt;/p&gt;

&lt;p&gt;Magic enforces access at execution time, in the runtime. Every endpoint in this build declares that it requires the "guest" role, and the check runs before any endpoint logic — the agent's generated code never gets the option of forgetting it. After the build, anonymous requests against the CRUD layer and the email endpoint were fired as verification: 401, access denied, every time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwugjbbep5xnmjepmcgny.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwugjbbep5xnmjepmcgny.jpg" alt="Magic-auth login — the JWT ticket comes from the platform, not from hand-rolled auth code" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is why you can hand an agent production credentials on this platform and watch it work. The platform, not the prompt, decides what those credentials can do. Supabase has nothing equivalent — not because their engineers are not capable, but because their architecture places authorization inside the application, and the application is now written by a probabilistic author.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A native MCP server
&lt;/h2&gt;

&lt;p&gt;Everything in the video happens over one MCP connection. Creating the database, generating endpoints, uploading files, verifying the result — the agent operates the platform through the same tool surface you are using when you talk to your own Magic cloudlet from Claude.&lt;/p&gt;

&lt;p&gt;Supabase has MCP as an add-on for development workflows. Magic's MCP server is the platform: every capability, scoped to the authenticated user's roles, with the agent able to generate new tools for itself when the existing ones do not fit. There is no "integration" step in the video because there is nothing to integrate.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Email as a platform primitive
&lt;/h2&gt;

&lt;p&gt;The CRM sends email to contacts. On Supabase that feature means an edge function, a third-party mail API, an API key to manage, and retry logic you own forever. On Magic, SMTP is configured once at platform level, and the generated endpoint simply sends — the agent never saw a mail-provider credential, because there is none in the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F61njx0ohe9mhgkmgvdlj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F61njx0ohe9mhgkmgvdlj.jpg" alt="Composing an email to a contact — one guest-gated endpoint, zero mail-provider plumbing" width="798" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. A web server
&lt;/h2&gt;

&lt;p&gt;The frontend in the video is served by the same system that serves the API. The agent wrote three files — HTML, CSS, JavaScript — into the platform's file system, and they were live at their URL the moment they were written. No Vercel, no Netlify, no storage-bucket-pretending-to-be-a-website, no CORS configuration between your frontend host and your backend host, because there is only one host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2rr0zqx9c51an8nc70u9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2rr0zqx9c51an8nc70u9.jpg" alt="The deals kanban — drag a card between stages and the deal updates through the guest-gated API" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Supabase Storage holds files. It is not a web root, and Supabase does not want to be your web server. Magic is one deployable unit that is your database, your API, your auth, your mail, and your frontend host — which is precisely what lets one agent in one conversation ship the whole thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The boring ones that add up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JWT auth with ticket rotation built in&lt;/strong&gt; — the frontend logs in against the platform's auth endpoint and refreshes its ticket on a ten-minute window. No auth library was installed anywhere in this build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task scheduling, logging, and a server-side file system&lt;/strong&gt; — not used heavily in the video, but they are the reason the agent never had to leave the platform for anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT license, one container, nothing gated&lt;/strong&gt; — the entire stack in the video is the open-source product. There is no hosted-only feature making the demo prettier than your deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp8054vzxpibzy5mrtxn9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp8054vzxpibzy5mrtxn9.jpg" alt="Contacts with search, status badges, and per-row actions — generated CRUD underneath" width="799" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Supabase has that Magic does not
&lt;/h2&gt;

&lt;p&gt;Fairness cuts both ways, and this list is real: realtime subscriptions over Postgres replication, the depth of the Postgres extension ecosystem, client SDKs for every framework under the sun, and a community large enough that every question you will ever have is already answered somewhere. If your product is built around live-updating Postgres data and your team's velocity comes from that ecosystem, Supabase remains the right call — I said so in &lt;a href="https://hyperlambda.dev/blog/magic-cloud-the-self-hosted-supabase-alternative-built-for-ai-agents" rel="noopener noreferrer"&gt;the comparison article&lt;/a&gt;, and it still holds.&lt;/p&gt;

&lt;p&gt;But none of those close the gap the video demonstrates. They make Supabase a better database platform. They do not make it a system an AI agent can safely operate end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;The interesting question in 2026 is no longer "which backend has the better dashboard." It is: when the next developer on your team is an agent with a prompt, what can it actually do — and what stops it from doing what it should not?&lt;/p&gt;

&lt;p&gt;In this build the answer was: everything, and the runtime. A database, sixteen role-secured endpoints, email dispatch, and a designed, working frontend, from one paragraph of intent — with every operation bounded by execution-time RBAC the agent could not generate its way around. That combination — generation, enforcement, MCP, mail, and hosting in one self-hosted, MIT-licensed unit — is the system that has everything Supabase does not.&lt;/p&gt;

&lt;p&gt;Magic is open source at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;, and hosted cloudlets at &lt;a href="https://ainiro.io" rel="noopener noreferrer"&gt;ainiro.io&lt;/a&gt; if you would rather not run it yourself.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://hyperlambda.dev/blog/everything-supabase-does-not-have-in-one-video-an-ai-agent-builds-a-role-secured-crm" rel="noopener noreferrer"&gt;hyperlambda.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>supabase</category>
      <category>ai</category>
      <category>backend</category>
      <category>opensource</category>
    </item>
    <item>
      <title>78% of Enterprise AI Teams Now Run MCP Agents in Production — Here's Why Most of Them Are Doing It Wrong</title>
      <dc:creator>Thomas Hansen</dc:creator>
      <pubDate>Thu, 23 Jul 2026 10:27:11 +0000</pubDate>
      <link>https://dev.to/polterguy/78-of-enterprise-ai-teams-now-run-mcp-agents-in-production-heres-why-most-of-them-are-doing-it-109g</link>
      <guid>https://dev.to/polterguy/78-of-enterprise-ai-teams-now-run-mcp-agents-in-production-heres-why-most-of-them-are-doing-it-109g</guid>
      <description>&lt;p&gt;Seventy-eight percent of enterprise AI teams now run MCP-backed agents in production, and &lt;a href="https://andrew.ooo/answers/mcp-model-context-protocol-enterprise-adoption-july-2026/" rel="noopener noreferrer"&gt;28% of the Fortune 500 operate their own MCP servers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The ecosystem has passed &lt;a href="https://tech-insider.org/ie/model-context-protocol-mcp-update-2026/" rel="noopener noreferrer"&gt;10,000 servers, with SDK downloads running at roughly 97 million per month&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Less than two years after &lt;a href="https://www.anthropic.com/news/model-context-protocol" rel="noopener noreferrer"&gt;Anthropic open-sourced the protocol&lt;/a&gt;, MCP is no longer the interesting experiment. It is the default way AI agents reach company data.&lt;/p&gt;

&lt;p&gt;That is the good news.&lt;/p&gt;

&lt;p&gt;The bad news is that adoption happened faster than security maturity. Most of those production deployments were stood up in the demo era — a shared API key in a config file, every tool exposed to every caller — and never hardened afterwards.&lt;/p&gt;

&lt;p&gt;They work. They also hand an autonomous agent the keys to company data with less access control than you would accept for a summer intern.&lt;/p&gt;

&lt;h2&gt;
  
  
  From experiment to infrastructure
&lt;/h2&gt;

&lt;p&gt;The timeline is worth appreciating, because it explains the problem.&lt;/p&gt;

&lt;p&gt;MCP went from novelty to infrastructure in record time. Every major vendor now ships servers — &lt;a href="https://www.microsoft.com/en-us/power-platform/blog/2026/07/06/dataverse-july2026/" rel="noopener noreferrer"&gt;Microsoft alone offers a catalog of 60+ MCP servers across Copilot, Copilot Studio, and Azure AI Foundry&lt;/a&gt;. And in five days, on July 28th, &lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/" rel="noopener noreferrer"&gt;the largest specification revision since MCP launched becomes the official spec, starting a 12-month deprecation clock for older protocol versions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A protocol with a formal deprecation policy is not an experiment anymore. It is plumbing.&lt;/p&gt;

&lt;p&gt;And here is the thing about plumbing: experiments don't get attacked. Infrastructure does.&lt;/p&gt;

&lt;p&gt;When 28% of the Fortune 500 runs something, that something becomes a target. The security posture that was fine for a weekend demo — because nothing valuable was behind it — is now sitting in front of CRMs, ERPs, financial data, and customer records.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three ways teams are doing it wrong
&lt;/h2&gt;

&lt;p&gt;I have looked at a lot of MCP deployments over the last year, and the failures cluster into three patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Over-broad tool exposure
&lt;/h3&gt;

&lt;p&gt;The most common mistake is the simplest one: the server hands every connected agent every tool it has.&lt;/p&gt;

&lt;p&gt;Read the database? Sure. Drop the database? Also sure. Same catalog, same caller, no distinction.&lt;/p&gt;

&lt;p&gt;This violates the oldest rule in security — least privilege — and it does so at the worst possible layer, because the caller is a language model. &lt;a href="https://securityboulevard.com/2026/07/securing-model-context-protocol-the-future-proof-blueprint-for-2026/" rel="noopener noreferrer"&gt;Every serious treatment of MCP security published this year&lt;/a&gt; lands on the same conclusion: the tool catalog an agent sees must be scoped to what that agent's &lt;em&gt;user&lt;/em&gt; is allowed to do, not to what the server is capable of.&lt;/p&gt;

&lt;p&gt;If the agent can enumerate a destructive tool, some prompt, someday, will convince it to call that tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Bolted-on or absent authentication
&lt;/h3&gt;

&lt;p&gt;The second failure is authentication that isn't really authentication.&lt;/p&gt;

&lt;p&gt;A long-lived API key pasted into a JSON config is not identity. It is a password that never rotates, shared by everyone who copies the config, tied to no user, and invisible to your identity provider.&lt;/p&gt;

&lt;p&gt;The protocol itself has moved past this. The MCP team just promoted its &lt;a href="https://www.infoq.com/news/2026/07/mcp-ema-enterprise-auth/" rel="noopener noreferrer"&gt;Enterprise-Managed Authorization extension to stable status&lt;/a&gt;, which routes MCP server access through the organization's identity provider — with support already shipped by Anthropic across Claude, Claude Code, and Cowork, by Visual Studio Code, and server-side by Asana, Atlassian, Canva, Figma, Linear, and Supabase.&lt;/p&gt;

&lt;p&gt;When the protocol's own answer to "who is calling?" is &lt;em&gt;your IdP&lt;/em&gt;, a shared bearer secret in a dotfile is no longer a pragmatic shortcut. It is technical debt with a blast radius.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Trusting the conversation
&lt;/h3&gt;

&lt;p&gt;The third failure is the subtle one, and it is the one that makes MCP security genuinely different from API security.&lt;/p&gt;

&lt;p&gt;An agent is a confused deputy by construction. It reads tool results, web pages, emails, documents — and every one of those inputs is a potential instruction channel. Prompt injection through tool output is not a theoretical attack; it is the standard attack.&lt;/p&gt;

&lt;p&gt;Which means one thing, architecturally: &lt;strong&gt;you cannot firewall a conversation.&lt;/strong&gt; No system prompt, no guardrail phrasing, no "please only use tools responsibly" preamble will hold. If the security check lives in the prompt, the security check is a suggestion.&lt;/p&gt;

&lt;p&gt;The permission decision has to live on the server, at the endpoint, enforced on every call regardless of what the model believes it is doing. I have written before that &lt;a href="https://hyperlambda.dev/blog/agentic-ai-without-permission-boundaries-is-just-malware-with-ux" rel="noopener noreferrer"&gt;agentic AI without permission boundaries is just malware with UX&lt;/a&gt; — MCP at enterprise scale is exactly where that stops being a slogan and starts being an incident report.&lt;/p&gt;

&lt;h2&gt;
  
  
  What doing it right looks like
&lt;/h2&gt;

&lt;p&gt;The fix is not exotic. It is three principles, each one mapping to a failure above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity, not shared secrets.&lt;/strong&gt; Every MCP session belongs to a real user, authenticated against real identity infrastructure, with a token that expires. Per-user, revocable, auditable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Role-gated tool catalogs.&lt;/strong&gt; The &lt;code&gt;tools/list&lt;/code&gt; an agent receives is filtered by the caller's roles before the agent ever sees it. The agent cannot be talked into calling a tool it cannot enumerate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server-side enforcement as the last line.&lt;/strong&gt; Even if the catalog leaks, even if the model hallucinates a tool name, the endpoint itself checks authorization on every invocation. The prompt proposes; the server disposes.&lt;/p&gt;

&lt;p&gt;This is how &lt;a href="https://hyperlambda.dev/blog/magic-now-supports-mcp-server-integration-for-ai-agents" rel="noopener noreferrer"&gt;Magic Cloud's MCP server&lt;/a&gt; is built, and it is worth describing not as a product pitch but as a worked example of the pattern — because Magic did not add security &lt;em&gt;to&lt;/em&gt; MCP. The MCP layer inherits it.&lt;/p&gt;

&lt;p&gt;Every MCP tool in Magic is an HTTP endpoint with its own authorization requirement. The access token is a real JWT tied to a real Magic user with real roles — the same auth system that protects the API protects the MCP surface, because they are the same surface. When an agent connects, the tool list it receives is the list of endpoints its user's roles permit, nothing more. And when it invokes a tool, the role check runs server-side, before any endpoint logic, on every single call.&lt;/p&gt;

&lt;p&gt;There is no separate "MCP security model" to configure, drift, or forget. If a user cannot call an endpoint over HTTP, their agent cannot call it over MCP. One contract, enforced once, in one place.&lt;/p&gt;

&lt;p&gt;That is what &lt;a href="https://hyperlambda.dev/blog/claude-code-tried-to-break-magic-cloud-and-mostly-ended-up-confirming-its-security" rel="noopener noreferrer"&gt;held up when a frontier coding agent spent a session actively trying to break it&lt;/a&gt; — and it is the same boundary that makes it safe to let &lt;a href="https://hyperlambda.dev/blog/a-complete-crm-in-one-conversation-60-seconds-of-backend-six-cents-of-tokens" rel="noopener noreferrer"&gt;an agent build an entire role-secured CRM in one conversation&lt;/a&gt;: the platform, not the prompt, decides what the agent can touch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The window is closing
&lt;/h2&gt;

&lt;p&gt;Here is why this matters &lt;em&gt;now&lt;/em&gt; rather than eventually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/" rel="noopener noreferrer"&gt;The July 28th spec release starts a 12-month deprecation clock&lt;/a&gt;. Every team running MCP in production will touch their stack in the next year whether they want to or not — to move off deprecated protocol versions if nothing else.&lt;/p&gt;

&lt;p&gt;That migration is the natural moment to fix what the demo era left behind. Swap the shared key for identity-backed tokens. Scope the tool catalog by role. Push the permission check down to the server where it belongs. Doing it as part of a migration you already have to do is cheap. Doing it after an agent with a wide-open catalog gets injected by a poisoned tool result is not.&lt;/p&gt;

&lt;p&gt;Being in the 78% is no longer the differentiator. Everyone is in the 78%.&lt;/p&gt;

&lt;p&gt;The differentiator is being in the minority that can answer, precisely and per-user, the only question that matters once agents are in production:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What exactly can this agent do, and who said so?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Magic is MIT-licensed and open source — the repository is at &lt;a href="https://github.com/polterguy/magic" rel="noopener noreferrer"&gt;github.com/polterguy/magic&lt;/a&gt;, with documentation at &lt;a href="https://docs.ainiro.io" rel="noopener noreferrer"&gt;docs.ainiro.io&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hyperlambda.dev/blog/78-percent-of-enterprise-ai-teams-now-run-mcp-agents-in-production-heres-why-most-of-them-are-doing-it-wrong" rel="noopener noreferrer"&gt;hyperlambda.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
