Appqr

by harishakumarn

326 downloads
Not rated
GitHub

About

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.

Details

Author
harishakumarn
Downloads
326
Categories
Other, Marketing

- Free, runs locally, no subscription required.
- Device detection using client-side JavaScript, no server needed.
- Supports campaign tracking parameters for iOS and Android.
- MCP server for AI agents to generate smart QR codes natively.
- Generates QR code images and a universal redirect HTML file.
- No campaign data ever sent to AppQR servers.

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Appqr
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Install globally with npm install -g appqr or run without installing via npx appqr setup. Use appqr setup with store URLs and a hosted URL to generate a redirect HTML and initial QR, then run appqr campaign for new campaign QRs. For AI agent integration, add the MCP server to tools like Claude Desktop and Cursor.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

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

McpServers

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

AppQR

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

npm version
npm downloads
license
node
MCP

</div>

---

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

| Tool | Description |
|------|-------------|
| appqr_setup | First time setup — generates redirect.html + qr.png |
| appqr_campaign | New campaign QR — generates qr.png only |
| appqr_validate | Validate store URLs before generating |

---

Campaign parameter formats

Apple App Store

| Param | What it is | Required | Example |
|-------|-----------|----------|---------|
| ct | Campaign token — your label | Recommended | ct=instagram_launch |
| pt | Provider token — your numeric Apple ID | Recommended | pt=12345 |
| mt | Media type — always 8 for apps | Yes | mt=8 |

--ios-params "ct=instagram_launch&pt=12345&mt=8"

Google Play (standard UTM)

| Param | What it is | Required | Example |
|-------|-----------|----------|---------|
| utm_source | Traffic source | Yes | utm_source=instagram |
| utm_medium | Marketing medium | Yes | utm_medium=paid |
| utm_campaign | Campaign name | Yes | utm_campaign=launch |
| utm_content | Specific ad or creative | No | utm_content=banner_v1 |
| utm_term | Keyword for search ads | No | utm_term=todo+app |

--android-params "utm_source=instagram&utm_campaign=launch&utm_medium=paid"

---

Why not just use Bitly / QR Tiger / Branch?

| | Others | AppQR |
|---|---|---|
| Smart iOS/Android redirect | ✓ paid | ✓ free |
| Pricing | $15–40/month | free |
| 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

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.