I built a QR code generator that works two ways: as a web app with 10 custom styles, and as an MCP server that lets Claude and Cursor generate QR codes directly in conversations.
What I built
Web app: QR generator with 10 style presets, logo uploads, mobile design, and SVG/PNG export
MCP server: Connects to Claude Desktop and Cursor so you can generate QR codes by just asking
Two connection modes: HTTP endpoint (works instantly) and stdio transport (run locally)
Batch tool: Generate dozens of styled QR codes at once for docs or marketing assets
My role and stack
Role: Designed and built everything; product, visuals, architecture, code, and docs
Stack:
Next.js 15 + React 19: Web framework
TypeScript + Zod: Type safety and validation
@modelcontextprotocol/sdk: MCP server
qr-code-styling + jsdom: Server-side QR generation
Tailwind CSS + Radix UI: Styling and components
Vercel: Hosting for both web and MCP
Biome: Linting and formatting
Motion: Animations
The problem
Making QR codes usually means opening a separate tool, downloading generic-looking codes, and manually matching your brand colors. Developers write custom scripts. Designers use Figma plugins. Everyone wastes time.
How I built it
Design
I made 10 color presets: Slate Ember, Night Sky, Graphite Gold, and others. Each one balances contrast for reliable scanning with colors that look good in modern interfaces. Added logo positioning (center or bottom-right), dark/light/system themes, and sound effects you can toggle off.
The styles work identically in the web app and MCP server; same code, same output.
MCP integration
The MCP server exposes three tools:
generate_qr_code- Creates a QR code with style, format, size, and logo optionsget_available_styles- Lists all 10 presetspreview_qr_url- Returns a web link to customize further
You can batch-process URLs and get svg download links back.
Setup takes one line in your Claude or Cursor config. The HTTP version needs no installation. The stdio version runs locally.
Both apps share the same QR generation code. I built separate TypeScript configs; one for Next.js, one for Node. The MCP server uses jsdom to generate codes without a browser. Style resolution happens server-side so colors stay consistent.
Vercel hosts both the web app and the MCP HTTP endpoint from one codebase. You can also install it as an npm package for local stdio mode.
Results
Launched early: One of the first MCP tools that generates visual assets (most tools fetch data or run commands)
Easy setup: Add one line to your config file. No API keys, no installs
Scanability tested: All 10 styles scan reliably on phones, tablets, and printed materials
Community interest: Got featured in MCP showcases and adopted by developers for automated doc generation
New workflows: People started doing things like "scan my README and generate QR codes for every link" or "make QR codes for all product URLs in this spreadsheet"
What I learned
Building for a protocol is different than building for users. The MCP version needed clear parameter names and good error messages because users don't see a UI—they just type requests to an AI.
AI should handle visual tasks too. Most AI tools focus on text and code. But plenty of work involves design assets. Making those accessible through conversation saves time.
Presets beat parameters for style. I could have exposed RGB values and corner radius as parameters. Instead, I made named presets. Much easier to ask for "night-sky style" than to specify hex codes.
Docs are the interface for developer tools. The setup guides with example prompts mattered as much as the code. If people can't configure it in 30 seconds, they won't try.
Dual deployment makes sense. HTTP mode gets you started instantly. Stdio mode lets you fork and modify. Both work from one codebase.
The point
I wanted to make QR codes without leaving my editor. Built a tool that does that, and it turns out other people wanted it too. The web version works if you prefer clicking buttons. The MCP version works if you prefer typing to Claude.
MCP is new. So most tools are still being figured out. This one shows you can use it for design assets, not just data. That feels like it opens up some interesting possibilities.
