mcpField
A
Appqr

Appqr

Local
github.com/harishakumarnBusiness & Marketing0Updated 19w ago

About Appqr

Appqr is a CLI and Node.js package for creating QR codes that route iOS and Android users to their respective app stores. Developers can create campaign-specific codes without changing the hosted redirect file; an MCP server also lets compatible agents run setup and campaign tasks.

Key features

  1. 01Device-based App Store and Google Play redirects
  2. 02Generate QR images for campaigns
  3. 03Separate iOS and Android tracking parameters
  4. 04Validate store URLs
  5. 05CLI, Node.js package, and MCP tools

Use cases

  1. 01Create one QR code for an app listed on both stores
  2. 02Produce distinct QR images for marketing campaigns
  3. 03Generate QR files through an MCP-compatible agent

MCP support

Its built-in MCP server exposes setup, campaign QR generation, and store URL validation tools to compatible AI agents.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"appqr": {
"command": "npx",
"args": [
"-y",
"appqr"
]
}
}
}
Run commandnpx -y appqr

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npmappqr

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

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

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.