{"slug": "i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-here-s-the-whole", "title": "I built a free QR code API + MCP server on Cloudflare Pages — here's the whole design", "summary": "A developer built FreeQrly, an open-source (MIT) QR code generator running on Cloudflare Pages and D1 that exposes a free static QR API, login-gated dynamic codes, and a Streamable HTTP MCP server at freeqrly.com/mcp. The design routes the web UI, REST API, and MCP tools through one shared auth and quota core, so validation, the 8-code free-tier limit, and ownership checks stay identical across all three surfaces. The project was published to the official MCP Registry as io.github.BryceBin/freeqrly (v1.1.0) and ships llms.txt and a SKILL.md for agent discovery.", "body_md": "Most QR code generators are either ad-covered landing pages or SaaS products with a paywall behind \"dynamic codes\". I wanted the opposite: a generator that's free, private by default, and natively callable by AI agents. So I built [FreeQrly](https://freeqrly.com) — open source ([BryceBin/freeqrly](https://github.com/BryceBin/freeqrly), MIT), running entirely on Cloudflare Pages + D1.\n\nHere's the architecture, including the part I think is most interesting: **one shared auth/quota core serving three surfaces — web UI, REST API, and MCP.**\n\n**1. Static QR API — no key, no signup, CORS wide open**\n\n```\nGET https://freeqrly.com/api/qr?data=https://example.com&size=1024&color=2F4A62&bgcolor=ffffff&margin=4&ecc=M\n```\n\nReturns an SVG. `data` is required (400 with a clear error otherwise), everything else has sane defaults, input is validated (data ≤ 2000 chars, color format checked). Static codes are generated 100% in the browser on the web UI — the API just mirrors that server-side for agents and scripts.\n\n**2. Dynamic codes — login-gated, editable after print**\n\nDynamic codes resolve through short `/q/xxxxxxx` links, so you can change the destination after printing and see scan stats (date / country / device / city breakdowns). Free tier: 8 codes. Login via Google, GitHub, or email+password (Turnstile-protected). The `/q/` hosted pages carry `noindex` + `X-Robots-Tag` so they never end up in search results.\n\n**3. MCP — Streamable HTTP, no auth for static, token for dynamic**\n\n```\nPOST https://freeqrly.com/mcp\n```\n\n`generate_qr` works with zero auth. Send an `Authorization: Bearer <token>` header and five more tools appear in `tools/list`: `dynamic_qr_create`, `dynamic_qr_list`, `dynamic_qr_update`, `dynamic_qr_delete`, `dynamic_qr_stats`.\n\nThe API-token flow reuses the UI's auth and quota logic instead of duplicating it:\n\n`fqly_`, are shown exactly once, and only a SHA-256 hash is stored. Max 20 per account, revocable anytime.`functions/_lib/codes_api.js`) with the UI and the MCP tools — same validation, same 8-code quota, same ownership checks. A token can't create or revoke other tokens (that requires a login session), and deleting your account wipes your tokens.`403 quota_exceeded`; cross-user access returns `403`; revoked/unknown tokens return `401`.\nBecause it's one code path, the three surfaces can't drift apart: what the UI enforces, the API and MCP enforce identically. I verified this end to end with a real test account in a real browser — login, token creation, REST create→list→stats→update→scan-redirect→delete, MCP tool calls, then 401s after revocation — and cleaned up all test data afterward.\n\nI added a `server.json` and published to the official MCP Registry as `io.github.BryceBin/freeqrly` (v1.1.0). Directories like Smithery and PulseMCP sync from the Registry, so one publish covers several. The repo also ships `llms.txt` and a `skills/qr-generator/SKILL.md` so agents can discover the API without reading docs.\n\n`qr_download`, `batch_generate`, `scan_decode`) that I query with plain SQL.\nIf you run an agent that needs QR codes — event badges, WiFi cards, vCards, batch generation (CSV in, ZIP out) — the static API and MCP are free with no signup: `https://freeqrly.com/developers/` has the full reference. Happy to answer questions about the token/quota design in the comments.", "url": "https://wpnews.pro/news/i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-here-s-the-whole", "canonical_source": "https://dev.to/zane_bin_e6f335ca1e4e3960/i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-heres-the-whole-design-93g", "published_at": "2026-10-19 03:14:50+00:00", "updated_at": "2026-10-19 03:19:06.988560+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "developer-tools"], "entities": ["FreeQrly", "Cloudflare Pages", "Cloudflare D1", "BryceBin", "MCP Registry", "Smithery", "PulseMCP", "GitHub"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-here-s-the-whole", "markdown": "https://wpnews.pro/news/i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-here-s-the-whole.md", "text": "https://wpnews.pro/news/i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-here-s-the-whole.txt", "jsonld": "https://wpnews.pro/news/i-built-a-free-qr-code-api-mcp-server-on-cloudflare-pages-here-s-the-whole.jsonld"}}