Developers
Give your AI agent QR superpowers: the OpenQR MCP server
9 min read · Updated 26 June 2026
MCP (the Model Context Protocol) is an open standard for letting an AI agent call external tools. Instead of you writing code against the OpenQR REST API, your agent connects to an MCP server, discovers the tools it exposes, and calls them itself when a request needs them. OpenQR runs a hosted MCP server so you do not have to install or self-host anything — you point your client at one URL, paste a key, and the agent can generate and manage QR codes on your behalf.
REST or MCP — same engine
The MCP server is a thin layer over the same API documented in our getting-started and dynamic-codes guides. If you are writing code directly, use the REST endpoints. If you are wiring up an agent, use MCP. They share the account, the keys, the rate limits and the abuse rules.
The endpoint and how auth works
OpenQR exposes a single Streamable HTTP MCP endpoint at https://openqr.uk/mcp, speaking JSON-RPC 2.0 over POST. There is no stdio binary to install and nothing to run locally — it is a hosted server, so any MCP client that supports the HTTP transport can reach it.
Authentication is the same free API key used everywhere else in OpenQR: you send it as Authorization: Bearer oqr_… on the connection. Create one in the dashboard at openqr.uk/api — sign in with a magic link, open API keys, and copy the key (it is shown once and stored only as a SHA-256 hash). Every tool call needs it; an unauthenticated request gets a clear error telling you to add a key rather than silently failing.
The API is key-gated on purpose
The in-browser generator is free and needs no signup. The API and MCP server require a key so OpenQR can keep abuse off the redirect network. Treat the key like a password: it is per-account, scope it to one agent or machine, and rotate it from the dashboard if it leaks.
Connecting from a real client
Most MCP clients — Claude Desktop, Claude Code, Cursor and Cline — take the same shape of config: a server name, the HTTP transport, the URL, and an Authorization header. Add this to the client's MCP settings and restart it:
{
"mcpServers": {
"openqr": {
"type": "http",
"url": "https://openqr.uk/mcp",
"headers": { "Authorization": "Bearer oqr_your_key_here" }
}
}
}- Claude Desktop — add the block to its
mcpServersconfig and restart; the tools appear under the connectors menu. - Claude Code — register the server with
claude mcp addusing the HTTP transport and the same URL and header. - Cursor — add it to your MCP servers settings; the tools become available to the agent in chat.
- Cline — add the same server entry in its MCP configuration.
- OpenClaw — the self-hosted personal AI assistant supports MCP servers too; register
https://openqr.uk/mcpwith the Bearer header via its own MCP config (see its CLI docs for the exact file).
Once connected, the agent calls tools/list automatically and sees everything below. You then just ask for what you want in plain English — the agent picks the tool and fills in the arguments. Prefer code? You can import the full OpenAPI 3.1 spec into the same clients for the REST side.
The ten tools
Anything you can do in the dashboard, an agent can do over MCP. The tools fall into five groups. Argument names below are exact — they are what the server expects.
| Group | Tool | Arguments | What it does |
|---|---|---|---|
| Generate | generate_qr | data (required), format (png|svg), size | Render a static QR image (PNG by default, or SVG markup). |
| Dynamic CRUD | create_dynamic_qr | destination (required), label | Create an editable code; returns its id and oqr.to short link. |
| Dynamic CRUD | update_dynamic_qr | id (required) + any of destination, label, slug, tags, folder_id | Repoint or re-tag a code without reprinting. Send only what changes. |
| Dynamic CRUD | list_dynamic_qr | limit | List your dynamic codes — id, short URL, destination, label, status. |
| Dynamic CRUD | delete_dynamic_qr | id (required) | Permanently delete a code; its short link stops resolving. |
| Analytics | get_scans | id (required) | Scan totals plus top countries, devices and referrers (last 30 days). |
| Bulk | bulk_create_dynamic_qr | codes[] of { destination, label } | Create up to 200 dynamic codes in one call. |
| Folders | list_folders | — | List your folders (id and name). |
| Folders | create_folder | name (required) | Create a folder to organise codes. |
| Folders | delete_folder | id (required) | Delete a folder; its codes are un-filed, not deleted. |
Two things worth knowing
get_scans over MCP always reports a 30-day window (the REST endpoint lets you pass a days range). And update_dynamic_qr is a partial update — to move a code into a folder pass folder_id, to take it out pass folder_id: null.
Example prompts that drive the tools
You never name the tools yourself. You describe the outcome and the agent maps it. A few that work well:
- “Make a QR code for https://openqr.uk and save it as a 1024px PNG.” →
generate_qr - “Create a dynamic code pointing at our spring-sale page, label it Spring Sale.” →
create_dynamic_qr - “That campaign moved — repoint the Spring Sale code to the new URL.” →
update_dynamic_qr - “How many scans has the Spring Sale code had, and where from?” →
get_scans - “Make editable codes for each of these 50 product URLs.” →
bulk_create_dynamic_qr - “Put all the restaurant table codes in a folder called Tables.” →
create_folder+update_dynamic_qr
Worked example 1: a support/marketing agent
A marketing agent is asked to launch a campaign and report back on it later. First it creates the dynamic code — when you ask it to, it issues this tool call (shown here as the raw JSON-RPC a client would send, so you can see exactly what crosses the wire):
curl -X POST https://openqr.uk/mcp \
-H "Authorization: Bearer oqr_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_dynamic_qr",
"arguments": {
"destination": "https://example.com/spring-sale",
"label": "Spring Sale"
}
}
}'The server replies with a text result the agent can read back to you — the new code's id and its oqr.to/<slug> short link. You print the code on the poster. A week later you ask “how is Spring Sale doing?” and the agent calls get_scans with that id:
curl -X POST https://openqr.uk/mcp \
-H "Authorization: Bearer oqr_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_scans",
"arguments": { "id": "the-code-id-from-step-1" }
}
}'Back comes a plain-text summary: total scans, scans in the last 30 days, and the top countries, devices and referrers. Because the destination is dynamic, the same agent can repoint it the moment the sale ends — call update_dynamic_qr with the id and a new destination, and every already-printed code now lands somewhere else. That edit-without-reprint loop is the whole point of dynamic codes over the API.
Worked example 2: bulk-creating from a list
Suppose an agent has a list of product URLs and needs an editable code for each. Rather than calling create_dynamic_qr in a loop, it sends one bulk_create_dynamic_qr call with up to 200 codes. In JavaScript, the same call against the MCP endpoint looks like this:
const products = [
{ destination: "https://shop.example.com/p/1001", label: "Mug" },
{ destination: "https://shop.example.com/p/1002", label: "T-shirt" },
{ destination: "https://shop.example.com/p/1003", label: "Sticker pack" },
];
const res = await fetch("https://openqr.uk/mcp", {
method: "POST",
headers: {
Authorization: "Bearer oqr_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 3,
method: "tools/call",
params: {
name: "bulk_create_dynamic_qr",
arguments: { codes: products },
},
}),
});
const { result } = await res.json();
console.log(result.content[0].text); // ids + oqr.to links for each created codeThe result lists every created code with its id and short link. A natural next step for the agent: create_folder named “Products”, then update_dynamic_qr on each id with that folder_id to file them. For the deeper patterns — chunking large lists, handling rate limits, organising at scale — see bulk generation and folders.
The limits still apply
MCP shares the REST account's rules: dynamic-code creation is rate-limited (20/hour per account), bulk is capped at 200 per call, and destinations must be public http(s) URLs — private hosts and oqr.to self-loops are rejected. If a call fails, the tool returns the error text so the agent can explain it rather than guessing.
Where this fits
MCP is the agent layer. If you are building an LLM feature or automation that needs QR codes as one capability among many, you will want both this and the raw API — start with the API getting-started guide for the fundamentals, then read QR codes in LLM apps and workflows for how to weave generation, dynamic links and analytics into a product. OpenQR is free, open-source and watermark-free; the MCP server, the API and the analytics behind them all come with a free account.
Get your free API keySign in with a magic link, create a key, and connect your agent to https://openqr.uk/mcp.