About esyURL
esyURL is a hosted MCP server for AI agents to create and manage short links and QR codes. It includes editable destinations, visitor routing, and click and scan statistics, with agent self-registration available.
Key features
- 01Create and manage short links
- 02Render styled QR codes
- 03Edit destinations and routing rules
- 04View click and scan statistics
- 05Organise links into groups
- 06Use custom domains
Use cases
- 01Create QR codes for printed materials
- 02Redirect visitors by device or country
- 03Review link and QR scan activity
- 04Group links for shared campaigns
MCP support
Provides a stateless Streamable HTTP MCP server at `https://esyurl.fyi/mcp`. Clients authenticate with a Bearer token, which an agent can obtain by signing itself up.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://esyurl.fyi/mcpclaude mcp add --transport http esyurl https://esyurl.fyi/mcp{"mcpServers":{"esyurl":{"type":"http","url":"https://esyurl.fyi/mcp"}}}Open in Cursor{"servers":{"esyurl":{"type":"http","url":"https://esyurl.fyi/mcp"}}}Open in VS Code{"mcpServers":{"esyurl":{"type":"http","url":"https://esyurl.fyi/mcp"}}}{"mcpServers":{"esyurl":{"serverUrl":"https://esyurl.fyi/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
https://esyurl.fyi/mcpAuth requiredTools
21| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | No | Human label, up to 200 chars |
| page | object | No | A link page (link in bio): instead of redirecting, the short URL shows a page with a title, an optional avatar and bio, a list of buttons and a row of social icons, styled by a theme. Rules still apply first: a matching rule redirects. Shape: {title (≤80), bio? (≤300), avatar? {data: "data:image/png;base64,..."} or {imageId} to keep the current one, items: [{type: "link", label, url} | {type: "link", label, linkId} (another of your links: opens its short URL) | {type: "header", text} | {type: "text", text}], socials?: [{platform, url}], theme?, language?, noindex?, footer?}. Items take id? (stable, clicks are counted by it; generated if omitted, keep it when editing), enabled? (default true), when? (a condition in the redirect-rule grammar: the item shows only to matching visits, e.g. {"field":"os","op":"eq","value":"ios"}), and link items highlight? (accent colour) and thumbnail? (a picture). Up to 50 items and 8 pictures. socials platforms: instagram, tiktok, youtube, x, facebook, linkedin, github, threads, bluesky, mastodon, whatsapp, telegram, spotify, twitch, discord, pinterest, snapchat, substack, email, website (email takes mailto:). theme: {preset? (light|dark|midnight|sunset|forest|pastel|mono, default light), background? {type: "solid", color} | {type: "gradient", from, to, angle?} | {type: "image", image: {data}, dim? 0-0.8}, text? (hex colour), font? (system|rounded|serif|mono|condensed), button? {shape? (square|rounded|pill), fill? (solid|outline|soft|shadow), color?, text?}, avatarShape? (circle|rounded|square), align? (center|left)}. Low-contrast colours come back as `warnings` but are saved. Pages of self-signed-up tenants carry a small "Made with esyURL · Report" footer; footer: false removes it for a one-off x402 payment per page (see payment). |
| slug | string | No | Custom slug, ^[a-zA-Z0-9_-]{3,64}$; random if omitted |
| tags | array | No | Free-form labels, up to 20; filter with list_short_links tag |
| rules | array | No | Redirect rules, evaluated in order on every visit; the first enabled rule whose "when" matches sends the visitor to its targetUrl, otherwise the link's targetUrl is used. A condition is either a test {field, op, value} or a combination {all: [...]}, {any: [...]}, {not: {...}}. Fields and their ops: os (ios|android|windows|macos|linux|chromeos|other), device (mobile|tablet|desktop|bot), browser (safari|chrome|firefox|edge|samsung|opera|in_app|other), source (qr|direct|bot): eq, neq, in, not_in. language (Accept-Language primary tag; "pt" also matches "pt-BR"): eq, neq, in, not_in, exists. country (ISO 3166-1 alpha-2, e.g. "GB", geolocated by the edge on every host): eq, neq, in, not_in. An unknown or absent value fails eq/in and passes neq/not_in. referrer (host, e.g. instagram.com) and query (needs "key", the parameter name): eq, neq, in, not_in, contains, starts_with, ends_with, exists. time (ISO timestamp): before, after. weekday (sun..sat, UTC): eq, neq, in, not_in. hour (0-23 UTC): eq, neq, in, not_in, gte, lte. in/not_in take an array. Text compares case-insensitively. Up to 20 rules, 20 conditions per rule. Example app-store split: [{"name":"iOS","when":{"field":"os","op":"eq","value":"ios"},"targetUrl":"https://apps.apple.com/app/id123"},{"name":"Android","when":{"field":"os","op":"eq","value":"android"},"targetUrl":"https://play.google.com/store/apps/details?id=com.example"}] |
| payment | any | No | Only for footer: false on a page that has not been paid off, by a self-signed-up tenant: the tool first returns an error whose structuredContent is an x402 PaymentRequired; retry with the signed PaymentPayload in _meta["x402/payment"], or, if your client cannot set _meta, here (an object or base64). |
| qrStyle | object | No | Default look of this link's QR image (free): colours, module and corner-marker shapes, and an optional picture. Styled codes need dark on light with at least 3:1 contrast. The whole style is replaced on update. |
| qrStyle.dark | string | No | Hex colour, e.g. #000000 (the # is optional) |
| qrStyle.image | object | No | A picture in the code. mode "logo": in the middle (error correction becomes H; size is its side as a share of the code, 0.1-0.3, default 0.22). mode "halftone": a photo behind the code, drawn as dots over it. data is a data URL (data:image/png;base64,... png, jpeg, webp or gif, up to 2 MB). To keep the current picture while changing other fields, pass its imageId instead of data. |
| qrStyle.image.data | string | No | A new picture, as a data URL |
| qrStyle.image.mode | enum | Yes | logo | halftone |
| qrStyle.image.size | number | No | |
| qrStyle.image.imageId | string | No | Keep the picture the link already has (its qrStyle.image.imageId) |
| qrStyle.light | string | No | Hex colour, e.g. #000000 (the # is optional) |
| qrStyle.margin | integer | No | Quiet zone in modules, 0-16 |
| qrStyle.eyeBall | enum | No | Centre of the corner markerssquare | rounded | circle |
| qrStyle.modules | enum | No | Shape of the data modules (default square)square | rounded | dot | row | column |
| qrStyle.eyeColor | string | No | Colour of the corner markers; defaults to dark |
| qrStyle.eyeFrame | enum | No | Outer ring of the three corner markerssquare | rounded | circle |
| qrStyle.errorCorrectionLevel | enum | No | QR error correction level: L 7%, M 15% (default), Q 25%, H 30%L | M | Q | H |
| groupIds | array | No | Ids of groups (from create_group/list_groups) this link belongs to, up to 20 |
| metadata | object | No | Up to 20 string key/value pairs for your own bookkeeping |
| targetUrl | string | No | Absolute http(s) URL visitors are redirected to (exclusive with page) |
Details
From the project READMEesyURL MCP server
A hosted MCP server that lets AI agents create and manage short links and QR codes with esyURL: shorten URLs, render styled QR codes, change where a printed or shared link points, route visitors by device or country, and read click and scan stats. The agent can sign itself up; no human account is needed.
- Endpoint:
https://esyurl.fyi/mcp(Streamable HTTP, stateless) - Auth:
Authorization: Bearer esy_...
There is nothing to install or run: this repository describes the hosted server. The server itself is not open source.
Get an API key
An agent without a key can create its own account and get one, following esyurl.fyi/auth.md:
BASE=https://esyurl.fyi
REG=$(curl -s $BASE/agent/identity -H 'content-type: application/json' -d '{"type":"anonymous"}')
KEY=$(curl -s $BASE/oauth2/token \
--data-urlencode grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
--data-urlencode assertion=$(echo "$REG" | jq -r .identity_assertion) | jq -r .access_token)
echo $KEY
Self-signed-up accounts get 100 links, 1000 once a human claims the account by email.
Connect
Claude Code:
claude mcp add --transport http esyurl https://esyurl.fyi/mcp \
--header "Authorization: Bearer esy_..."
Cursor, VS Code and other clients (.mcp.json style):
{
"mcpServers": {
"esyurl": {
"type": "http",
"url": "https://esyurl.fyi/mcp",
"headers": { "Authorization": "Bearer esy_..." }
}
}
}
Tools
| Tool | What it does |
|---|---|
create_short_link | Shorten a URL, with an optional custom slug, QR style and redirect rules |
list_short_links | List your links, optionally by tag or group |
get_short_link | One link, with its groups and lifetime visit count |
update_short_link | Change where a link points, its QR style or rules, or pause it; the short URL and printed QR codes keep working |
delete_short_link | Delete a link |
test_redirect_rules | Check which destination a visitor would get (e.g. iPhone to the App Store, Android to Google Play) |
get_short_link_visits | Visits per day, split into QR scans, direct clicks and bots |
render_qr_code | A PNG QR code for a link (scans counted) or any text: module shapes, corner markers, colours, a logo or a photo |
create_group, list_groups, get_group, update_group, delete_group | Organise links into groups |
add_links_to_group, remove_link_from_group | Group membership |
get_group_visits | Combined visits for a group |
get_custom_domain, set_custom_domain, remove_custom_domain | Short links on your own domain |
Pricing
Links, QR codes and stats are free. Self-signed-up accounts pay once per new
custom domain, in USDC with x402; set_custom_domain
returns the payment requirements first.
More
- esyurl.fyi/llms.txt: the API for agents
- esyurl.fyi/openapi.json: REST API
- esyurl/skills: the same, as agent skills
(
npx skills add esyurl/skills)
License
MIT, for the contents of this repository.
Comments
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.