ext-apps/examples/qr-server
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Tobin South c76f827368
fix(example qr server): Embed widget HTML in QR server (#317)
* feat(qr-server): embed widget HTML for self-contained usage

Embed the widget HTML directly in server.py following the same pattern
as the say-server. This allows the QR server to be run without any
local file dependencies using `uv run <url>`.

The get_widget_html() function prefers the built version from dist/
for local development but falls back to the embedded HTML for unbundled
usage.

* refactor(qr-server): remove widget.html and simplify embedded HTML

Address PR review feedback:
- Remove separate widget.html file (no longer needed)
- Remove get_widget_html() function and dist/mcp-app.html reference
- Inline EMBEDDED_WIDGET_HTML directly in widget() resource
- Remove unused Path import

The server is now fully self-contained in a single file.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-21 16:51:23 +00:00
..
.gitignore Add QR code Python MCP server example (#105) 2025-12-09 19:20:08 +01:00
grid-cell.png feat(qr-server): use Python SDK meta parameter for resource CSP metadata (#303) 2026-01-19 19:11:42 +00:00
package.json feat(qr-server): migrate to uv with PEP 723 inline dependencies 2026-01-14 20:27:35 +00:00
README.md style: format JSON in READMEs with prettier 2026-01-16 15:14:48 +00:00
server.py fix(example qr server): Embed widget HTML in QR server (#317) 2026-01-21 16:51:23 +00:00

QR Code MCP Server

A minimal Python MCP server that generates customizable QR codes with an interactive widget UI.

Screenshot

MCP Client Configuration

First, clone the repository:

git clone https://github.com/modelcontextprotocol/ext-apps.git

Then add to your MCP client configuration (stdio transport), replacing the path with your clone location:

{
  "mcpServers": {
    "qr": {
      "command": "uv",
      "args": [
        "run",
        "/path/to/ext-apps/examples/qr-server/server.py",
        "--stdio"
      ]
    }
  }
}

Features

  • Generate QR codes from any text or URL
  • Customizable colors, size, and error correction
  • Interactive widget that displays in MCP-UI enabled clients
  • Supports both HTTP (for web clients) and stdio (for MCP clients)

Prerequisites

This server uses uv for dependency management. Install it first:

curl -LsSf https://astral.sh/uv/install.sh | sh

Quick Start

# Run server (HTTP mode) - uv handles dependencies automatically
uv run server.py
# → QR Code Server listening on http://localhost:3108/mcp

Usage

HTTP Mode (for basic-host / web clients)

uv run server.py

Connect from basic-host:

SERVERS='["http://localhost:3108/mcp"]' bun serve.ts

Stdio Mode (for MCP clients)

uv run server.py --stdio

See MCP Client Configuration above for how to add this server to your MCP client.

Docker (accessing host server from container)

http://host.docker.internal:3108/mcp

Tool: generate_qr

Generate a QR code with optional customization.

Parameters

Parameter Type Default Description
text string (required) The text or URL to encode
box_size int 10 Size of each box in pixels
border int 4 Border size in boxes
error_correction string "M" Error correction level: L/M/Q/H
fill_color string "black" Foreground color (hex or name)
back_color string "white" Background color (hex or name)

Error Correction Levels

Level Recovery Use Case
L 7% Clean environments
M 15% General use (default)
Q 25% Industrial/outdoor
H 30% Adding logos/damage-prone

Example Inputs

Basic:

{ "text": "https://example.com" }

Styled:

{
  "text": "https://claude.ai",
  "fill_color": "#CC785C",
  "back_color": "#FFF8F5",
  "box_size": 12,
  "border": 3
}

Dark Mode:

{
  "text": "Hello World",
  "fill_color": "#E0E0E0",
  "back_color": "#1a1a1a",
  "box_size": 15,
  "border": 2
}

WiFi QR Code:

{
  "text": "WIFI:T:WPA;S:MyNetwork;P:MyPassword;;",
  "error_correction": "H",
  "box_size": 10
}

Architecture

qr-server/
├── server.py      # MCP server (FastMCP + uvicorn, deps inline via PEP 723)
├── widget.html    # Interactive UI widget
└── README.md

Protocol

The widget uses MCP Apps SDK protocol:

  1. Widget sends ui/initialize request
  2. Host responds with capabilities
  3. Widget sends ui/notifications/initialized
  4. Host sends ui/notifications/tool-result with QR image
  5. Widget renders image and sends ui/notifications/size-changed

Dependencies

Dependencies are declared inline in server.py using PEP 723 and managed by uv:

  • mcp - MCP Python SDK with FastMCP
  • qrcode[pil] - QR code generation with Pillow
  • uvicorn - ASGI server
  • starlette - CORS middleware

License

MIT