QR Codes in Your Document, Fast and Painless!

My fiancé’s neighbor has a dog that won’t stop barking. So I wrote a little letter suggesting they invest in some Amazon products that might help with that. 

At a technical level, I wanted to add QR codes to a letter without having to go to a website, generate each one, save each one, and drag each one to my doc— I needed to slide a letter under my neighbor's door with QR codes for specific product links, and I wanted a quicker way – ideally, to have the QR codes appear directly in the final printable output without all the manual steps. My goal was to spend maybe 10-20 minutes total.

Here's how I used my Cursor/FastMCP setup with Claude to do it:

1. The Custom Tool:

Using Cursor, I opened my FastMCP project. Already set up. I modified the place I keep Python tool's (server.py) to use the qrcode library. Cursor generated this code. This tool (create_qr_code) takes a web link and returns the QR code image encoded as a base64 string. (See code screenshot). This meant Claude now had a built-in way to generate the QR codes when I provided links.


import asyncio
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
import qrcode
import base64
from io import BytesIO

# Initialize FastMCP server
mcp = FastMCP("wait")
@mcp.tool()
async def create_qr_code(link: str) -> str:
"""Generate a QR code for a given link and return it as a base64-encoded PNG image string.


Args:
link: The URL to encode in the QR code.
Returns:
A base64-encoded PNG image of the QR code.
"""
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(link)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
buffered = BytesIO()
img.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
return img_str

if __name__ == "__main__":
# Initialize and run the server
mcp.run(transport='stdio')

2. Asking Claude for the Letter and Codes:

I wrote a prompt asking Claude to draft the letter and specifically requested it to "Create QR codes for each of these links," mentioning I planned to print it. (See prompt screenshot).



3. The Initial Result (and the fix):

Claude gave me the letter text, which was great. However, for the QR codes, it returned the raw base64 strings, not the visible images. (See response showing base64 strings). This wasn't quite what I needed for printing!




I simply told Claude I needed a printable version. This time, it generated the output as an HTML file, explaining that this format would correctly display the QR codes from the base64 strings. (See response explaining HTML).




4. Printing the Final Document:

I saved the HTML file, opened it in my web browser, and there it was! The letter with the QR codes clearly visible and formatted. I just hit print,

The Takeaway:

Instead of generating QR codes one by one on an external site, saving images, and manually embedding them, I used my AI assistant (Claude) powered by a custom tool to handle the generation and embedding within the final document structure (HTML). This bypassed multiple steps and got me a ready-to-print letter with functional QR codes quickly and efficiently, staying well within my time limit.


"A Name, an Address, a Route" Haiku — Found in RFC 791: DARPA’s 1981 Internet Protocol

A name indicates what we seek.   An address indicates where it is.   A route indicates how to get there.   The internet protocol deals prima...