QR Code Studio: open-source QR generation with an API agents can actually use
The real impetus was not a roadmap item. Mark posted on X the night we shipped:
Wife does a lot of flyers for her new job. All the ones she pulled up on the app store were ad-infested slop. I built a super simple QR code generator for her. And because I'm mister overkill, built an API, agents.md file and an SMCP plugin for it, too.
That is the honest origin story. A person making flyers needed a QR code without downloading spyware cosplaying as a utility. Everything else — open source, normalization, branded center logos, Kitchen POS pickup links — grew from "make the simple thing first, then stop lying to yourself about scope."
QR Code Studio lives at qr.decisionsciencecorp.com: browser studio for humans, REST API + PHP/Python SDKs + SMCP plugin + agents.md for everyone who cannot use the App Store version. Code is AGPL-3.0; docs are CC BY-SA 4.0 (COPYING.md). We published the repo in June 2026 because if we built it for family, we might as well ship it for strangers with the same ad-free constraint.
This post covers what we built after the flyer problem, why we open-sourced it, and how to integrate without reading three repos first.
Screenshots below are from the live site at qr.decisionsciencecorp.com — not mockups.
The problem with "just use a free QR site"
The App Store results Mark's wife tried are the consumer face of a deeper issue. Free generators are fine for one-off personal links. They are painful when:
- Typos become permanent. Email domains and TLDs get mangled (
con→com,gnail→gmail) at keyboard speed. Stickers do not have an undo button. - Agents cannot click. Vernal, Broca, and SMCP hosts need normalize → generate as HTTP or CLI — not "open this page in a browser."
- Branding matters. Pickup windows and partner tables want a center logo on the code without breaking scan reliability.
- Licensing is vague. We wanted code we could fork, self-host, and ship in client engagements without a terms-of-service archaeology project.
QR Code Studio is deliberately narrow: URLs, email, phone, plain text — validated, normalized, encoded. Not a marketing suite. Not a URL shortener. A tool that does one job honestly.
Two surfaces: browser studio and REST API
Browser studio (client-side)
The public page is a static studio: paste content, pick Auto/URL/Email/Phone, see a live preview, download PNG or SVG. Encoding runs in the browser via vendored qrcode-generator (MIT) — no round-trip required for casual use.
The studio shares the same normalization rules as the API. app.js and PHP QrNormalize are kept in semantic parity so "it looked fine in the browser" and "the API returned garbage" cannot diverge.
REST API (server-side)
For automation, batch jobs, and agents:
| Endpoint | Role |
|---|---|
GET /api/v1/health.php |
Liveness + capability flags |
POST /api/v1/normalize.php |
Validate, autocorrect, return encoded payload + suggestions |
POST /api/v1/generate.php |
PNG or SVG bytes (base64 in JSON) |
GET /api/v1/openapi.json |
Machine-readable contract |
Quick start:
curl -sS https://qr.decisionsciencecorp.com/api/v1/health.php
curl -sS -X POST https://qr.decisionsciencecorp.com/api/v1/normalize.php \
-H 'Content-Type: application/json' \
-d '{"content":"hello@gnail.com"}'
curl -sS -X POST https://qr.decisionsciencecorp.com/api/v1/generate.php \
-H 'Content-Type: application/json' \
-d '{"content":"https://decisionsciencecorp.com","format":"png","ecl":"M"}'
PNG generation uses phpqrcode (LGPL) via PHP GD. SVG works without GD — useful on stripped-down dev hosts. OpenAPI documents error codes, optional X-API-Key auth, and rate limits (~120 req/min per IP on the public tier).
Normalization is the product
Anyone can draw black squares. The value is catching mistakes before they ship.
QrNormalize implements:
- Scheme hints — bare domains get
https://suggested;mailto:andtel:for email/phone modes. - Email domain typos — Levenshtein-style fixes against a curated domain list (
gmail.com,outlook.com,decisionsciencecorp.com, …). - TLD repairs —
con→com,og→org, and other fat-finger patterns we have seen on real sticker orders. - Structured responses —
encoded,type, optionalsuggestion+suggestion_reasonso UIs and agents can ask "did you mean …?" instead of silently baking in the typo.
The API returns the same shape the browser uses. SDKs wrap it; the SMCP plugin wraps the SDK path. One normalization brain, three entrypoints.
Branded codes: center logo overlay
Commit 40640b0 added optional center logo overlay on generated PNG/SVG. Logos are base64 in the generate request; the renderer bumps error correction to at least Q when a logo is present so real-world scans stay reliable.
That matters for Empanada Empire pickup signage and partner materials — a plain black QR on a white label is fine for dev; affiliates want their mark in the center without hiring a designer for every window.
Agent integration: agents.md and SMCP
We ship agent onboarding the same way we ship human docs:
| Resource | URL |
|---|---|
| DEV hub | qr.decisionsciencecorp.com/dev |
| agents.md | live docs · GitHub |
| SMCP plugin | smcp_plugin/qr_studio/cli.py --describe |
| PHP SDK | sdk/php/QrStudioClient.php |
| Python SDK | sdk/python/qr_studio/ |
Prefer SMCP when your host already runs Sanctum MCP plugins — health, normalize, generate, tool-help with discovery via --describe. Otherwise hit REST directly or import the SDK.
Optional server-side QR_STUDIO_API_KEY enables X-API-Key / Bearer for higher-trust deployments. Public tier is rate-limited per IP; AGPL source is on GitHub if you need a private instance.
Open-source slice (June 13)
The open-source release (e64cdbf) packaged:
- AGPL API + shared PHP includes
- Browser studio assets
- DEV docs browser (markdown → HTML under
/dev/) - SDKs and SMCP plugin in-repo
COPYING.mddual-license clarity (AGPL code, CC BY-SA docs)- Footer links to DEV hub and agent docs (
57f05f6,827b8a3)
Repo: github.com/decisionsciencecorp/qr.decisionsciencecorp.com
We are not pretending this is a venture-scale QR platform. It is production infrastructure we use — and we would rather maintain it in public than re-explain it on every engagement.
How we use it inside DSC
The flyer use case is still the spine — church bulletins, event handouts, wife's job materials. No ads, no upsell modal before download.
From there it spread into work we were already doing:
- Empanada Empire — pickup URLs, partner customer links (
empanadaempire.us/p/<slug>/), window signage. - Agent workflows — SMCP
qr_studio__*tools for "generate a PNG for this URL" without browser automation. - Client deliverables — normalized email QR codes on conference badges, corrected before print.
If you only need one code once for a flyer, the browser studio is enough — that was the whole point of v1. If you need repeatable, testable, agent-callable QR generation, start at agents.md.
Deploy and ops
QR Code Studio runs on our multihost LEMP stack like sibling DSC properties. /root/sites/qr.decisionsciencecorp.com.env wires GitHub → sync.sh → deploy.sh every few minutes — same cron pattern as Tasks and CRM. See docs/DEPLOY.md in the repo for the env template.
PHP GD must be enabled for PNG API output; SVG generation works without it. We keep db/.gitkeep so deploy rsync has a stable tree — the app is file-backed, not a heavy database product.
Health check for monitors:
curl -sS https://qr.decisionsciencecorp.com/api/v1/health.php | jq .
Design and quality bar
The studio uses the same dark DSC chrome as our other properties — compact hero, card-based input/preview grid, Inter typography. Playwright design smoke (tests/design_smoke.py) exercises Auto/URL/Email/Phone cases at mobile and desktop widths against a local php -S server.
API smoke (tests/api_smoke.py) and dev footer checks (dev_smoke.py) keep the OSS docs links from rotting — agents should always find agents.md from the live footer.
What we deliberately did not build
| Out of scope | Why |
|---|---|
| URL shortening / analytics | Different product; use your own redirect layer |
| Dynamic QR redirect swaps | Security and support burden |
| Account billing tiers | Public + optional API key is enough for v1 |
| Exotic payload types (WiFi, vCard) | Maybe later; URL/email/tel cover our lab |
Lessons for teams shipping small OSS utilities
- Ship for one real human first — a flyer deadline beats a architecture diagram every time.
- Normalize before encode — the bug is almost never the QR algorithm; it is the string fed into it.
- Ship
agents.mdbeside README — the overkill phase is optional; the overkill phase is also how Otto stops asking you for PNGs. - SMCP + REST + SDK — same three-layer pattern as Kitchen POS and Tasks; pick your transport.
- Dual license docs — AGPL code with CC BY-SA docs avoids "can we copy the tutorial into the client wiki?" fights.
- OpenAPI on day one — agents and humans both benefit from a single JSON contract.
QR Code Studio is live at qr.decisionsciencecorp.com. Questions, forks, and PRs welcome on GitHub — or contact us if you want help wiring it into a Sanctum agent stack.