DEV Community

Thomas Hansen
Thomas Hansen

Posted on

Creating Full Stack Apps with Mythos and Magic

I wanted to see how far an AI agent could get building a real, deployed full-stack app against Magic Cloud using nothing but MCP tool calls — no hand-written code. Here's what came out of one session.

The Stack

  • Backend: Hyperlambda, generated entirely via the generate-hyperlambda MCP tool (never hand-written — the platform enforces this)
  • Database: SQLite, crm database, single contacts table
  • Frontend: Vanilla HTML/CSS/JS SPA served from /etc/www/
  • Auth: Magic Auth (built-in RBAC/JWT)
  • Orchestrator: Claude, via the Magic MCP connector (~105 tools across 14 namespaces)

What Got Built

  1. Schema: a contacts table (name, email, phone, company, notes) via execute-sql
  2. CRUD API: four separate Hyperlambda endpoints — create, read (paged/sorted/filtered), update, delete — each generated as its own generate-hyperlambda call and auto-exposed as an MCP tool the moment it's saved
  3. Frontend: login-gated SPA, JWT stored in localStorage, auto-refreshing the ticket every 10 minutes, classic/corporate visual theme
  4. Seed data: 10 example contacts inserted directly via SQL

Total build time: minutes, not hours.

Two Bugs Worth Knowing About

1. GET/DELETE requests can't carry a Content-Type header.

Hyperlambda's HTTP layer throws if you decorate a GET or DELETE request with a content-type header. You cannot decorate an HTTP GET or DELETE request with content type of headers.

This bit both the MCP invoke-http tool (which defaults to application/json unless you override with an empty headers object) and would have bitten the frontend if I hadn't special-cased it — app.js only attaches Content-Type on POST/PUT.

2. Relative asset paths break without a trailing slash.

/etc/www/crm-contacts/index.html serves at /crm-contacts/. But if a user hits /crm-contacts (no trailing slash), the browser resolves <link href="style.css"> against domain root, not the folder — instant 404. Fix: use absolute paths (/crm-contacts/style.css) in every asset reference. Easy to miss, annoying to debug from a screenshot of a 404.

The Interesting Part

The Hyperlambda generator refuses to be hand-debugged — the platform's own tooling actively pushes you toward invoke-http and the OpenAPI spec instead of trying to read/patch the generated .hl files directly. That constraint, combined with checking log_entries in the magic SQLite database for the actual exception text, was faster for root-causing both bugs above than staring at HTTP status codes would have been.

Takeaway

Framework-enforced constraints (no hand-written Hyperlambda, RBAC at execution time, generator-only codegen) slow down the "just let me fix this one line" instinct — but they're also what made a zero-manual-code CRM buildable in a single sitting without the usual pile of copy-pasted, unreviewed AI-generated backend code.

You can watch me going through the whole process below ...

Top comments (0)