Sponsored by Deepsite.site

Appqr

Created By
harishakumarn2 days ago
Generate smart QR codes for App Store and Google Play. One QR detects the device and redirects iOS users to the App Store and Android users to Google Play. Free, no subscriptions, no third-party servers in the redirect chain.
Overview

AppQR

One QR code. Detects the device. Sends users to the right store.

npm version npm downloads license node MCP


You made an app. It's on both stores. You need one QR code for your landing page, business card, and press kit. Every other tool charges a monthly subscription for this. AppQR is free, runs on your machine, and works forever.

npx appqr setup \
  --ios "https://apps.apple.com/app/id123456789" \
  --android "https://play.google.com/store/apps/details?id=com.myapp" \
  --url "https://myapp.com/go"
✓ redirect.html  →  ./appqr-output/redirect.html
✓ qr.png         →  ./appqr-output/qr.png

→ Upload redirect.html to your site at: https://myapp.com/go
→ Done! For future campaigns, run: appqr campaign

How it works

Scan QR
Phone opens: myapp.com/go?d=eyJpb3MiOiJodHRw...
redirect.html detects device (client-side JS, no server)
iOS user  → App Store
Android   → Google Play

The QR code encodes both store URLs as base64 in the URL itself. redirect.html is a tiny generic file that decodes and redirects — it contains zero campaign data and never needs to change. Every new campaign just generates a new QR image.

No AppQR servers are ever in the redirect chain. Everything runs on the developer's own website.


Install

npm install -g appqr

Or run without installing:

npx appqr setup ...

Usage

Step 1 — Setup (once per app)

appqr setup \
  --ios "https://apps.apple.com/app/id123456789" \
  --android "https://play.google.com/store/apps/details?id=com.myapp" \
  --url "https://myapp.com/go"

With campaign tracking on your first QR:

appqr setup \
  --ios "https://apps.apple.com/app/id123456789" \
  --android "https://play.google.com/store/apps/details?id=com.myapp" \
  --url "https://myapp.com/go" \
  --ios-params "ct=launch&pt=12345&mt=8" \
  --android-params "utm_source=launch&utm_campaign=v1&utm_medium=organic" \
  --output ./public/go

Upload redirect.html to your site. That's the only file you ever upload. Never touch it again.


Step 2 — New campaign QR (as many times as you want)

appqr campaign \
  --ios "https://apps.apple.com/app/id123456789" \
  --android "https://play.google.com/store/apps/details?id=com.myapp" \
  --url "https://myapp.com/go" \
  --ios-params "ct=instagram_launch&pt=12345&mt=8" \
  --android-params "utm_source=instagram&utm_campaign=launch&utm_medium=paid" \
  --output ./qrs/instagram
✓ qr.png  →  ./qrs/instagram/qr.png

iOS URL:     https://apps.apple.com/app/id123456789?ct=instagram_launch&pt=12345&mt=8
Android URL: https://play.google.com/store/apps/details?id=com.myapp&utm_source=instagram...

No file upload needed — redirect.html already handles this.

No upload. No website change. Just a new QR image for each campaign.


Show campaign param formats

appqr params

Use as a Node.js package

import { setup, campaign } from 'appqr'

// First time setup
const result = await setup({
  ios: 'https://apps.apple.com/app/id123456789',
  android: 'https://play.google.com/store/apps/details?id=com.myapp',
  hostedUrl: 'https://myapp.com/go',
  iosParams: 'ct=launch&pt=12345&mt=8',
  androidParams: 'utm_source=launch&utm_campaign=v1&utm_medium=organic',
  outputPath: './public/go'
})
// → result.redirectPath  upload this once
// → result.qrPath        use this as your QR image

// Campaign QR — no upload needed
const qr = await campaign({
  ios: 'https://apps.apple.com/app/id123456789',
  android: 'https://play.google.com/store/apps/details?id=com.myapp',
  hostedUrl: 'https://myapp.com/go',
  iosParams: 'ct=instagram_launch&pt=12345&mt=8',
  androidParams: 'utm_source=instagram&utm_campaign=launch&utm_medium=paid',
  outputPath: './qrs/instagram'
})
// → qr.qrPath  your campaign QR image

Full TypeScript types included. No @types/appqr needed.


MCP — For AI agents (Claude, Cursor, Copilot)

AppQR ships with a built-in MCP (Model Context Protocol) server. AI agents that support MCP can generate smart QR codes natively — no CLI knowledge, no manual steps.

Add to Claude Desktop

{
  "mcpServers": {
    "appqr": {
      "command": "npx",
      "args": ["appqr", "mcp"]
    }
  }
}

Add to Cursor

{
  "mcpServers": {
    "appqr": {
      "command": "npx",
      "args": ["appqr", "mcp"]
    }
  }
}

After connecting, the agent can:

"Generate a smart QR code for my app. App Store: apps.apple.com/app/id123. Play Store: play.google.com/store/apps/details?id=com.app. Host it at myapp.com/go."

The agent calls appqr_setup or appqr_campaign directly and gets back the file paths.

MCP tools exposed

ToolDescription
appqr_setupFirst time setup — generates redirect.html + qr.png
appqr_campaignNew campaign QR — generates qr.png only
appqr_validateValidate store URLs before generating

Campaign parameter formats

Apple App Store

ParamWhat it isRequiredExample
ctCampaign token — your labelRecommendedct=instagram_launch
ptProvider token — your numeric Apple IDRecommendedpt=12345
mtMedia type — always 8 for appsYesmt=8
--ios-params "ct=instagram_launch&pt=12345&mt=8"

Google Play (standard UTM)

ParamWhat it isRequiredExample
utm_sourceTraffic sourceYesutm_source=instagram
utm_mediumMarketing mediumYesutm_medium=paid
utm_campaignCampaign nameYesutm_campaign=launch
utm_contentSpecific ad or creativeNoutm_content=banner_v1
utm_termKeyword for search adsNoutm_term=todo+app
--android-params "utm_source=instagram&utm_campaign=launch&utm_medium=paid"

Why not just use Bitly / QR Tiger / Branch?

OthersAppQR
Smart iOS/Android redirect✓ paid✓ free
Pricing$15–40/monthfree
Your QR works if they shut down✓ always
Campaign tracking params✓ paid✓ free
Separate Apple & Google params✗ rarely✓ yes
Agent / CLI friendly✓ yes
MCP server✓ yes
Your campaign data on their server✓ always✗ never

Repository structure

appqr/
├── public/
│   ├── index.html        # Landing page
│   └── llms.txt          # AI agent discovery
├── api/
│   └── ping.js           # Telemetry (Vercel serverless)
├── cli/
│   ├── bin/appqr.js      # CLI entry point
│   ├── src/
│   │   ├── core.js       # Core logic
│   │   ├── mcp.mjs       # MCP server
│   │   ├── telemetry.js  # Anonymous counters
│   │   ├── index.js      # npm package exports
│   │   └── index.d.ts    # TypeScript types
│   └── package.json
├── vercel.json
└── README.md             # This file

Deploy the web backend (Vercel + Supabase)

The web backend hosts the landing page and collects anonymous usage telemetry (install count, usage count, agent vs human split — no personal data).

1. Deploy to Vercel

git clone https://github.com/harishakumarn/appqr
cd appqr
vercel deploy

Or connect via the Vercel dashboard — import the repo, one click deploy.

2. Set up Supabase (optional — for telemetry)

Run this SQL in your Supabase project:

create table counters (
  id integer primary key default 1,
  installs bigint default 0,
  setups bigint default 0,
  human_runs bigint default 0,
  agent_runs bigint default 0,
  qrs_generated bigint default 0,
  constraint single_row check (id = 1)
);

insert into counters (id) values (1);

create or replace function increment_counter(col_name text)
returns void as $$
begin
  execute format(
    'update counters set %I = %I + 1 where id = 1',
    col_name, col_name
  );
end;
$$ language plpgsql;

Add to Vercel environment variables:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_KEY=your-service-role-key

3. Update telemetry URL

In cli/src/telemetry.js, replace the TELEMETRY_URL with your Vercel deployment URL.

4. Publish to npm

cd cli
npm publish

Privacy & telemetry

AppQR sends one anonymous ping per run. No URLs, no campaign data, no store links, no personal information, no device identifiers are ever collected.

The only thing tracked is a counter increment for one of: installed, setup, human_run, agent_run, qr_generated

Opt out permanently:

echo 'export APPQR_NO_TELEMETRY=1' >> ~/.zshrc

Or per-run:

APPQR_NO_TELEMETRY=1 appqr setup ...

Contributing

PRs welcome. The codebase is intentionally small — core logic is under 200 lines.

git clone https://github.com/harishakumarn/appqr
cd appqr/cli
npm install
node bin/appqr.js setup --help

License

MIT © AppQR Contributors

Server Config

{
  "mcpServers": {
    "appqr": {
      "command": "npx",
      "args": [
        "appqr",
        "mcp"
      ]
    }
  }
}
Recommend Servers
TraeBuild with Free GPT-4.1 & Claude 3.7. Fully MCP-Ready.
Y GuiA web-based graphical interface for AI chat interactions with support for multiple AI models and MCP (Model Context Protocol) servers.
MCP AdvisorMCP Advisor & Installation - Use the right MCP server for your needs
Baidu Map百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
CursorThe AI Code Editor
Tavily Mcp
Howtocook Mcp基于Anduin2017 / HowToCook (程序员在家做饭指南)的mcp server,帮你推荐菜谱、规划膳食,解决“今天吃什么“的世纪难题; Based on Anduin2017/HowToCook (Programmer's Guide to Cooking at Home), MCP Server helps you recommend recipes, plan meals, and solve the century old problem of "what to eat today"
BlenderBlenderMCP connects Blender to Claude AI through the Model Context Protocol (MCP), allowing Claude to directly interact with and control Blender. This integration enables prompt assisted 3D modeling, scene creation, and manipulation.
AiimagemultistyleA Model Context Protocol (MCP) server for image generation and manipulation using fal.ai's Stable Diffusion model.
Zhipu Web SearchZhipu Web Search MCP Server is a search engine specifically designed for large models. It integrates four search engines, allowing users to flexibly compare and switch between them. Building upon the web crawling and ranking capabilities of traditional search engines, it enhances intent recognition capabilities, returning results more suitable for large model processing (such as webpage titles, URLs, summaries, site names, site icons, etc.). This helps AI applications achieve "dynamic knowledge acquisition" and "precise scenario adaptation" capabilities.
Amap Maps高德地图官方 MCP Server
ChatWiseThe second fastest AI chatbot™
DeepChatYour AI Partner on Desktop
RedisA Model Context Protocol server that provides access to Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.
Visual Studio Code - Open Source ("Code - OSS")Visual Studio Code
Jina AI MCP ToolsA Model Context Protocol (MCP) server that integrates with Jina AI Search Foundation APIs.
WindsurfThe new purpose-built IDE to harness magic
Serper MCP ServerA Serper MCP Server
MiniMax MCPOfficial MiniMax Model Context Protocol (MCP) server that enables interaction with powerful Text to Speech, image generation and video generation APIs.
EdgeOne Pages MCPAn MCP service designed for deploying HTML content to EdgeOne Pages and obtaining an accessible public URL.
Playwright McpPlaywright MCP server