QR for Agent

Dynamic QR code MCP server for AI agents — create, update, track QR codes

QR Agent Core

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.qragentcore.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 serverqr-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 registrationPOST /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

Quick Start

git clone https://github.com/benswel/qr-agent-core.git
cd qr-agent-core
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)

MethodPathDescription
POST/api/qrCreate a QR code (11 types, custom styling)
GET/api/qrList all QR codes (paginated)
GET/api/qr/:shortIdGet QR code details
PATCH/api/qr/:shortIdUpdate target URL, label, UTM, GTM, redirect rules
DELETE/api/qr/:shortIdDelete QR code and its analytics
GET/api/qr/:shortId/imageDownload QR image (regenerated with stored style)
POST/api/qr/bulkCreate up to 50 QR codes (all-or-nothing)
PATCH/api/qr/bulkUpdate up to 50 QR codes (partial success)
DELETE/api/qr/bulkDelete up to 50 QR codes (partial success)
POST/api/qr/bulk/csvCreate up to 500 QR codes from CSV (Pro only)

Analytics (X-API-Key required)

MethodPathDescription
GET/api/analytics/:shortIdScan stats with device, browser, OS, country, city breakdowns + conversions

Conversions (X-API-Key required)

MethodPathDescription
POST/api/conversionsRecord a conversion event for a QR code you own
GET/api/conversions/:shortIdGet conversion stats (totals, by_event, by_day, recent)

Webhooks (X-API-Key required)

MethodPathDescription
POST/api/webhooksRegister webhook endpoint (returns HMAC secret)
GET/api/webhooksList all webhooks
DELETE/api/webhooks/:idDelete a webhook

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

MethodPathDescription
GET/api/domainGet current custom domain and DNS status
PUT/api/domainSet custom domain
DELETE/api/domainRemove custom domain

Account (X-API-Key required)

MethodPathDescription
GET/api/usageCurrent usage and quota
POST/api/stripe/checkoutCreate Stripe Checkout session (upgrade to Pro)
POST/api/stripe/portalOpen Stripe billing portal

Public (no auth)

MethodPathDescription
POST/api/registerSelf-service API key registration (rate-limited)
GET/r/:shortIdRedirect to target URL (records scan)
GET/t/:shortIdConversion tracking pixel (returns 1×1 GIF)
GET/i/:shortIdServe QR image (cacheable)
GET/healthHealth check
GET/documentationSwagger UI
GET/.well-known/ai-plugin.jsonAI plugin manifest
GET/.well-known/mcp.jsonMCP discovery manifest

Admin (X-Admin-Secret header required)

MethodPathDescription
GET/api/admin/keysList all registered API keys
GET/api/admin/statsDashboard 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.qragentcore.com"
      }
    }
  }
}

Available Tools (37)

ToolDescription
create_qr_codeCreate a URL QR code with optional custom styling
get_qr_codeGet QR code details by short ID
update_qr_destinationChange where a QR code redirects
list_qr_codesList all QR codes with pagination
delete_qr_codeDelete a QR code and its analytics
get_qr_analyticsGet scan stats and breakdowns
bulk_create_qr_codesCreate up to 50 QR codes at once
bulk_update_qr_codesUpdate up to 50 QR codes at once
bulk_delete_qr_codesDelete up to 50 QR codes at once
create_vcard_qrCreate a vCard contact QR code
create_wifi_qrCreate a WiFi credentials QR code
create_email_qrCreate an email (mailto:) QR code
create_sms_qrCreate an SMS QR code
create_phone_qrCreate a phone call QR code
create_event_qrCreate a calendar event QR code
create_text_qrCreate a plain text QR code
create_location_qrCreate a geo-location QR code
create_social_qrCreate a social media links QR code
create_app_store_qrCreate a smart app store redirect QR code
update_vcard_qrUpdate a vCard QR code
update_wifi_qrUpdate a WiFi QR code
update_social_qrUpdate a social media QR code
update_app_store_qrUpdate an app store QR code
create_webhookRegister a webhook endpoint
list_webhooksList all registered webhooks
delete_webhookDelete a webhook
registerRegister for an API key
get_usageGet current usage and quota
upgrade_to_proCreate a Stripe Checkout session
manage_billingOpen Stripe billing portal
set_utm_paramsSet UTM tracking parameters on a QR code
set_redirect_rulesSet conditional redirect rules on a QR code
set_custom_domainSet or remove custom domain (Pro)
get_custom_domainGet current custom domain and DNS status
bulk_create_from_csvCreate up to 500 QR codes from CSV data (Pro)
record_conversionRecord a post-scan conversion event
get_conversionsGet conversion stats for a QR code

Configuration

Copy .env.example to .env and edit:

VariableDefaultDescription
PORT3100HTTP port
HOST0.0.0.0Bind address
BASE_URLhttp://localhost:3100Public URL (used in short URLs)
DATABASE_URL./data/qr-agent.dbSQLite file path
SHORT_ID_LENGTH8Length 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

ScriptDescription
npm run devStart dev server with auto-reload
npm run buildCompile TypeScript
npm startRun production server
npm testRun test suite
npm run test:watchTests in watch mode
npm run key:createCreate API key
npm run key:listList API keys
npm run db:generateGenerate migration
npm run db:migrateRun migrations
npm run db:studioOpen Drizzle Studio

License

MIT

Related Servers