Skip to main content
Glama
QR for Agent

QR for Agent

by benswel

QR for Agent

benswel/qr-for-agent-api MCP server

QR-as-a-Service API built for AI agents. Create, update, and track dynamic QR codes programmatically via REST API or MCP (37 tools).

QR codes point to short URLs (/r/:shortId) that you can retarget at any time — the QR image never changes, but scanning it goes to the new destination. Multi-tenant by design, with full scan analytics.

Live API: api.qrforagent.com  |  Site: qrforagent.com  |  MCP: qr-for-agent

Features

  • Dynamic QR codes — change the destination URL without regenerating the image

  • 11 QR types — URL, vCard, WiFi, Email, SMS, Phone, Event, Text, Location, Social, App Store

  • Custom styling — dot shapes (square, rounded, dots, classy-rounded), corner styles, colors, gradients, logo embedding, frames with CTA text

  • SVG & PNG — vector and bitmap output

  • Enriched analytics — device type, browser, OS, country, city, referrer, scans-by-day

  • Real-time webhooks — HMAC-SHA256 signed payloads with delivery logging

  • UTM tracking — auto-append UTM parameters to redirect URLs

  • GTM support — intermediate page with Google Tag Manager snippets

  • Conditional redirects — route by device, OS, country, language, time range, or A/B split

  • Custom domains — Pro users brand short URLs with their own domain (qr.yourbrand.com/r/abc123)

  • Expiration & scheduling — auto-expire QR codes or schedule URL swaps

  • Conversion tracking — tracking pixel + API for post-scan events (purchases, signups) with ROI analytics

  • Frames & templates — decorative frames around QR codes (banner_top, banner_bottom, rounded) with CTA text

  • Bulk operations — create, update, or delete up to 50 QR codes per request, or up to 500 via CSV upload (Pro)

  • Multi-tenant — each API key sees only its own data

  • MCP server — qr-for-agent with 37 tools for Claude Desktop, Cursor, etc.

  • Plan-based quotas — Free (10 QR, 1K scans/month) and Pro ($19/month, unlimited)

  • Self-service registration — POST /api/register with email, no credit card

  • Stripe integration — checkout, billing portal, webhook-driven plan management

  • OpenAPI docs — Swagger UI at /documentation

  • AI-discoverable — /.well-known/ai-plugin.json and /.well-known/mcp.json

  • Open source — MIT license, self-hostable via Docker

Related MCP server: QR Code Generator MCP

Quick Start

git clone https://github.com/benswel/qr-for-agent-api.git
cd qr-for-agent-api
npm install
npm run dev

On first startup, an API key is auto-generated and printed to the console.

curl -X POST http://localhost:3100/api/qr \
  -H "Content-Type: application/json" \
  -H "X-API-Key: qr_YOUR_KEY_HERE" \
  -d '{"target_url": "https://example.com", "label": "My first QR"}'

API Endpoints

QR Code Management (X-API-Key required)

Method

Path

Description

POST

/api/qr

Create a QR code (11 types, custom styling)

GET

/api/qr

List all QR codes (paginated)

GET

/api/qr/:shortId

Get QR code details

PATCH

/api/qr/:shortId

Update target URL, label, UTM, GTM, redirect rules

DELETE

/api/qr/:shortId

Delete QR code and its analytics

GET

/api/qr/:shortId/image

Download QR image (regenerated with stored style)

POST

/api/qr/bulk

Create up to 50 QR codes (all-or-nothing)

PATCH

/api/qr/bulk

Update up to 50 QR codes (partial success)

DELETE

/api/qr/bulk

Delete up to 50 QR codes (partial success)

POST

/api/qr/bulk/csv

Create up to 500 QR codes from CSV (Pro only)

Analytics (X-API-Key required)

Method

Path

Description

GET

/api/analytics/:shortId

Scan stats with device, browser, OS, country, city breakdowns + conversions

Conversions (X-API-Key required)

Method

Path

Description

POST

/api/conversions

Record a conversion event for a QR code you own

GET

/api/conversions/:shortId

Get conversion stats (totals, by_event, by_day, recent)

Webhooks (X-API-Key required)

Method

Path

Description

POST

/api/webhooks

Register webhook endpoint (returns HMAC secret)

GET

/api/webhooks

List all webhooks

DELETE

/api/webhooks/:id

Delete a webhook

Custom Domain (X-API-Key required, Pro only)

Method

Path

Description

GET

/api/domain

Get current custom domain and DNS status

PUT

/api/domain

Set custom domain

DELETE

/api/domain

Remove custom domain

Account (X-API-Key required)

Method

Path

Description

GET

/api/usage

Current usage and quota

POST

/api/stripe/checkout

Create Stripe Checkout session (upgrade to Pro)

POST

/api/stripe/portal

Open Stripe billing portal

Public (no auth)

Method

Path

Description

POST

/api/register

Self-service API key registration (rate-limited)

GET

/r/:shortId

Redirect to target URL (records scan)

GET

/t/:shortId

Conversion tracking pixel (returns 1×1 GIF)

GET

/i/:shortId

Serve QR image (cacheable)

GET

/health

Health check

GET

/documentation

Swagger UI

GET

/.well-known/ai-plugin.json

AI plugin manifest

GET

/.well-known/mcp.json

MCP discovery manifest

Admin (X-Admin-Secret header required)

Method

Path

Description

GET

/api/admin/keys

List all registered API keys

GET

/api/admin/stats

Dashboard metrics

Authentication

All /api/* endpoints require an X-API-Key header.

  • Format: qr_ + 32-character random string

  • Auto-generated: on first startup if no keys exist

  • Multi-tenant: each key only sees its own QR codes

  • Create a key: npm run key:create "my-label"

  • List keys: npm run key:list

Public endpoints (/r/*, /i/*, /health, /documentation, /.well-known/*) don't require auth.

MCP Server

Published as qr-for-agent on npm. 37 tools for AI agents to manage QR codes natively.

npx qr-for-agent

Claude Desktop / Cursor

Add to your MCP config (claude_desktop_config.json or .cursor/mcp.json):

{
  "mcpServers": {
    "qr-for-agent": {
      "command": "npx",
      "args": ["-y", "qr-for-agent"],
      "env": {
        "API_KEY": "your-api-key",
        "BASE_URL": "https://api.qrforagent.com"
      }
    }
  }
}

Available Tools (37)

Tool

Description

create_qr_code

Create a URL QR code with optional custom styling

get_qr_code

Get QR code details by short ID

update_qr_destination

Change where a QR code redirects

list_qr_codes

List all QR codes with pagination

delete_qr_code

Delete a QR code and its analytics

get_qr_analytics

Get scan stats and breakdowns

bulk_create_qr_codes

Create up to 50 QR codes at once

bulk_update_qr_codes

Update up to 50 QR codes at once

bulk_delete_qr_codes

Delete up to 50 QR codes at once

create_vcard_qr

Create a vCard contact QR code

create_wifi_qr

Create a WiFi credentials QR code

create_email_qr

Create an email (mailto:) QR code

create_sms_qr

Create an SMS QR code

create_phone_qr

Create a phone call QR code

create_event_qr

Create a calendar event QR code

create_text_qr

Create a plain text QR code

create_location_qr

Create a geo-location QR code

create_social_qr

Create a social media links QR code

create_app_store_qr

Create a smart app store redirect QR code

update_vcard_qr

Update a vCard QR code

update_wifi_qr

Update a WiFi QR code

update_social_qr

Update a social media QR code

update_app_store_qr

Update an app store QR code

create_webhook

Register a webhook endpoint

list_webhooks

List all registered webhooks

delete_webhook

Delete a webhook

register

Register for an API key

get_usage

Get current usage and quota

upgrade_to_pro

Create a Stripe Checkout session

manage_billing

Open Stripe billing portal

set_utm_params

Set UTM tracking parameters on a QR code

set_redirect_rules

Set conditional redirect rules on a QR code

set_custom_domain

Set or remove custom domain (Pro)

get_custom_domain

Get current custom domain and DNS status

bulk_create_from_csv

Create up to 500 QR codes from CSV data (Pro)

record_conversion

Record a post-scan conversion event

get_conversions

Get conversion stats for a QR code

Configuration

Copy .env.example to .env and edit:

Variable

Default

Description

PORT

3100

HTTP port

HOST

0.0.0.0

Bind address

BASE_URL

http://localhost:3100

Public URL (used in short URLs)

DATABASE_URL

./data/qr-agent.db

SQLite file path

SHORT_ID_LENGTH

8

Length of generated short IDs

ADMIN_SECRET

(none)

Secret for admin endpoints (X-Admin-Secret header)

STRIPE_SECRET_KEY

(none)

Stripe API secret key

STRIPE_WEBHOOK_SECRET

(none)

Stripe webhook signing secret

STRIPE_PRICE_ID

(none)

Stripe Price ID for Pro plan

Database

SQLite with Drizzle ORM. Six tables:

  • api_keys — key storage with label, email, plan (free/pro), Stripe IDs, custom domain

  • qr_codes — QR metadata, target URLs, type/type_data, style options, UTM, GTM, redirect rules, expiration/scheduling

  • scan_events — scan tracking: timestamp, user-agent, referer, IP, device, browser, OS, country, city

  • webhooks — webhook endpoints per API key, HMAC secret, subscribed events

  • webhook_deliveries — delivery log: status, response code, error messages

  • conversion_events — conversion tracking: event name, value, metadata, referer, IP, timestamp

npm run db:generate   # Generate migration from schema changes
npm run db:migrate    # Apply pending migrations
npm run db:studio     # Open Drizzle Studio (web UI)

Migrations run automatically on server startup.

Deployment

Docker

docker compose up -d

The database is persisted in a Docker volume.

Railway

The project includes railway.toml and a multi-stage Dockerfile. Connect your GitHub repo to Railway — it builds and deploys automatically with health checks on /health.

Tests

195 integration tests covering all endpoints, auth, multi-tenant isolation, QR types, webhooks, bulk operations, custom domains, frames, conversions, CSV upload, and analytics.

npm test           # Run all tests
npm run test:watch # Watch mode

Scripts

Script

Description

npm run dev

Start dev server with auto-reload

npm run build

Compile TypeScript

npm start

Run production server

npm test

Run test suite

npm run test:watch

Tests in watch mode

npm run key:create

Create API key

npm run key:list

List API keys

npm run db:generate

Generate migration

npm run db:migrate

Run migrations

npm run db:studio

Open Drizzle Studio

License

MIT

Available Tools

37 tools
bulk_create_from_csvA

Create up to 500 QR codes from CSV data. Pro plan required. Send the CSV content as a string. Required column: target_url. Optional columns: label, format, type, foreground_color, background_color, dot_style, corner_style, frame_style, frame_text, expires_at. Returns all created QR codes.

Inputs: csv_content (required).

bulk_create_qr_codesA

Create multiple QR codes in a single request (up to 50). Each item supports the same options as create_qr_code. The quota check is all-or-nothing: if the batch would exceed your plan limit, no QR codes are created. Ideal for generating QR codes for product catalogs, event lists, or batch operations.

Inputs: items (required).

bulk_delete_qr_codesA

Delete multiple QR codes and their scan analytics in a single request (up to 50). Items with non-existent short_id are reported as not_found without failing the whole batch.

Inputs: short_ids (required).

bulk_update_qr_codesA

Update multiple QR codes in a single request (up to 50). Change target URLs and/or labels. Items with non-existent short_id are reported as not_found without failing the whole batch.

Inputs: items (required).

create_app_store_qrA

Create a QR code that redirects to the correct app store based on the device. iPhones go to the App Store, Android devices go to Google Play, and other devices go to the fallback URL. Provide at least one store URL.

Inputs: ios_url, android_url, fallback_url, label, +10 more.

create_email_qrB

Create a QR code that opens a pre-filled email when scanned. The recipient, subject, body, CC, and BCC can all be pre-set.

Inputs: to (required), subject, body, cc, +12 more.

create_event_qrB

Create a QR code that adds a calendar event when scanned. Encodes a standard iCalendar VEVENT that calendar apps can import.

Inputs: summary (required), start (required), end (required), location, +12 more.

create_location_qrB

Create a QR code that opens a map location when scanned. Encodes geographic coordinates that map apps can parse.

Inputs: latitude (required), longitude (required), label, qr_label, +10 more.

create_phone_qrB

Create a QR code that initiates a phone call when scanned. The phone number is encoded directly in the QR code.

Inputs: phone_number (required), label, format, foreground_color, +8 more.

create_qr_codeA

Create a new managed QR code with optional custom styling. The QR code points to a short URL that redirects to your target URL. You can change the target URL later without regenerating the QR image. Supports custom colors, dot shapes, corner shapes, and logo embedding.

Inputs: target_url (required), label, format, foreground_color, +18 more.

create_sms_qrB

Create a QR code that opens a pre-filled SMS message when scanned. Set the phone number and optional message text.

Inputs: phone_number (required), message, label, format, +9 more.

create_social_qrA

Create a QR code that links to social media profiles. When scanned via the short URL, returns a JSON object with all platform links. Provide at least one platform link.

Inputs: facebook, instagram, twitter, linkedin, +15 more.

create_text_qrA

Create a QR code that contains plain text. When scanned, the text is displayed directly. Useful for messages, notes, or any freeform content.

Inputs: content (required), label, format, foreground_color, +8 more.

create_vcard_qrA

Create a QR code that encodes a contact card (vCard). When scanned by a phone camera, it prompts the user to save the contact. Supports all standard vCard fields and custom QR styling.

Inputs: first_name (required), last_name (required), organization, title, +16 more.

create_webhookA

Register a webhook endpoint to receive real-time notifications when QR codes are scanned. Returns an HMAC-SHA256 secret for verifying webhook signatures — store it securely, it is only shown once.

Inputs: url (required), events.

create_wifi_qrC

Create a QR code that encodes WiFi credentials. When scanned by a phone camera, it offers to auto-join the WiFi network. No internet connection needed to join — the credentials are encoded directly in the QR image.

Inputs: ssid (required), password, encryption, hidden, +11 more.

delete_qr_codeA

Permanently delete a QR code and all its scan analytics. The short URL will stop working immediately. This cannot be undone.

Inputs: short_id (required).

delete_webhookA

Delete a webhook endpoint and all its delivery logs. The endpoint will stop receiving events immediately.

Inputs: webhook_id (required).

get_conversionsA

Get conversion statistics for a QR code. Returns total conversions, total value, breakdowns by event name, daily trends, and recent events. Use this to measure QR code ROI and understand which codes drive the most value.

Inputs: short_id (required), period, event.

get_custom_domainA

Get your current custom domain configuration and DNS verification status. Returns the domain, whether DNS is active or pending, and setup instructions.

Inputs: no named parameters.

get_qr_analyticsA

Get enriched scan analytics for a QR code. Returns total scans, daily trends, device/browser/country/referer breakdowns with percentages, and recent scan events with parsed user-agent and geo data.

Inputs: short_id (required), period.

get_qr_codeA

Retrieve details of an existing QR code by its short ID. Returns the current target URL, metadata, and timestamps.

Inputs: short_id (required).

get_usageA

Get current usage and quota for your API key.

Inputs: no named parameters.

list_qr_codesA

List all managed QR codes with pagination. Returns short IDs, target URLs, labels, and timestamps. Use this to browse or search for existing QR codes.

Inputs: limit, offset.

list_webhooksA

List all registered webhook endpoints for your API key. The HMAC secret is not included for security.

Inputs: no named parameters.

manage_billingA

Open the Stripe billing portal to manage your subscription, update payment method, or cancel. Returns a portal URL — tell the user to open it in their browser. Only works if you have an active Pro subscription.

Inputs: no named parameters.

record_conversionA

Record a post-scan conversion event (purchase, signup, etc.) for a QR code you own. Use this to track ROI — e.g., when a user scans a QR code and then makes a purchase, record a 'purchase' conversion with the order value. For client-side tracking without code, use the tracking pixel: .

Inputs: short_id (required), event (required), value, metadata.

registerA

Register for an API key. Provide your email to get a key immediately.

Inputs: email (required), label.

set_custom_domainA

Set a custom domain for your QR code short URLs (Pro plan required). When set, all new QR codes will use https://your-domain.com/r/... instead of the default URL. You must configure DNS (CNAME) to point to the QR Agent server. Pass domain=null to remove the custom domain.

Inputs: domain (required).

set_redirect_rulesA

Set conditional redirect rules on a URL QR code. Rules are evaluated top-to-bottom; each rule has an array of conditions (AND logic) — all must match. First matching rule's URL is used. If no rule matches, the default target_url applies. Conditions: 'device' (mobile/tablet/desktop), 'os' (iOS/Android/Windows/macOS/Linux), 'country' (ISO alpha-2 like 'FR'), 'language' (ISO 639-1 like 'fr'), 'time_range' ({start:'09:00',end:'17:00',timezone:'Europe/Paris'}), 'ab_split' ({percentage:50}). Combine conditions in a single rule for AND logic (e.g. mobile + FR). Pass an empty array to remove all rules.

Inputs: short_id (required), rules (required).

set_utm_paramsA

Set UTM tracking parameters on a URL QR code. These parameters are automatically appended to the target URL on every scan redirect. Use this to track QR code scans in Google Analytics or other analytics tools. Set 'clear' to true to remove all UTM parameters.

Inputs: short_id (required), source, medium, campaign, +3 more.

update_app_store_qrA

Update the app store URLs of an App Store QR code. Partial updates merge with existing data.

Inputs: short_id (required), ios_url, android_url, fallback_url, +1 more.

update_qr_destinationA

Change where an existing QR code redirects to. This is the key 'dynamic link' feature: the QR image stays the same, but scanning it will now go to the new URL. Ideal for updating campaigns, fixing broken links, or A/B testing.

Inputs: short_id (required), target_url (required), label, expires_at, +3 more.

update_social_qrB

Update the social media links of a Social QR code. Partial updates merge with existing data.

Inputs: short_id (required), facebook, instagram, twitter, +6 more.

update_vcard_qrA

Update the contact details of a vCard QR code. Only works on QR codes created with type='vcard'. Partial updates merge with existing data. Note: updating vCard data changes the QR image content.

Inputs: short_id (required), first_name, last_name, organization, +7 more.

update_wifi_qrA

Update the WiFi credentials of a WiFi QR code. Only works on QR codes created with type='wifi'. Note: updating WiFi data changes the QR image content.

Inputs: short_id (required), ssid, password, encryption, +2 more.

upgrade_to_proA

Upgrade to the Pro plan ($19/month) for unlimited QR codes, scans, and webhooks. Returns a Stripe Checkout URL — tell the user to open it in their browser to complete payment. The upgrade takes effect automatically after payment.

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 37 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose, from creating specific QR code types (email, event, location, etc.) to bulk operations, analytics, and account management. No two tools appear to do the same thing, and descriptions clearly differentiate them.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern in snake_case (e.g., create_qr_code, get_qr_analytics, update_qr_destination). There are no deviations or mixed conventions, making the set predictable and easy to navigate.

    Tool Count4/5

    With 37 tools, the count is high but justified by the breadth of functionality: multiple QR types (10+), bulk operations, analytics, webhooks, billing, and customization. While slightly bloated, each tool serves a specific need in QR code management.

    Completeness5/5

    The tool surface covers the full lifecycle: create (single, bulk, specialized types), read (list, get details, analytics), update (destination, styling, dynamic rules), delete, plus extras like webhooks, billing, custom domains, and conversion tracking. No obvious gaps for a QR code service.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables generation of QR codes from text or URLs in multiple formats (DataURL, SVG, terminal display) with customizable options like error correction, colors, and size. Supports batch processing of multiple QR codes and integrates seamlessly with MCP-compatible clients.
      4
      4
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Generate styled QR codes, manage dynamic short links with click analytics, and publish micro-landing pages via AI agents.
      19
      63 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      QrVerloz lets AI agents create QR codes instantly — no account needed, active for 90 days, and claimable at any time to make them permanent. Retarget the destination URL whenever you need, without reprinting.
      3
      MIT