esyURL
REMOTE · ESYURL.FYI
Short links and trackable QR codes: editable after printing, device routing, scan stats.
Available components
Last scanned (7 hours ago)
Scores higher than 89% of remote servers
Reachable. Last reached 5 Nov 2026.
Category Marketing and SEO
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security83
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token. View diagnostics → Pass
- HTTPS enforcement could not be verified: the plaintext port answered with HTTP 401, which proves neither a plaintext path nor enforcement. View diagnostics → Unverified
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
- The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents. View diagnostics → Partial
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability63
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 5321 tokens (~241/item across 22 items; 22 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management90
- Stability check failed: schema churn in the 28 days we've observed: 0 tool removals, 1 breaking changes, 0 auth/transport breaks, 3 additions. See how to fix → Fail
Tool Coverage96
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 89% of tool parameters carry a description.Partial
Tool Safety94
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 3 of 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "remove_link_from_group" implies "remove" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Partial
- An AI judge read all 23 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 4 Nov 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87.
- 3 Nov 26 −1
- First check of Authorization: partial security
- Tool “render_qr_code” rewrote its description, which is the text the model reads security
- New tool “get_account” functional
- 1 Nov 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 73 to 77.
- 30 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 67 to 70.
- 28 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 60 to 63.
- 26 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 53 to 57.
- 23 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 43 to 47.
- 21 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 37 to 40.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Probed https://esyurl.fyi/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=esyurl.fyi | CN=YE2,O=Let's Encrypt,C=US | 30 Sept 2026 | 29 Dec 2026 | ECDSA 256 | ECDSA-SHA384 | 669760c782db84d547665720f2cec11bc12 |
| SANs: *.esyurl.fyi, esyurl.fyi | ||||||
| CN=YE2,O=Let's Encrypt,C=US (CA) | CN=Root YE,O=ISRG,C=US | 3 Sept 2025 | 2 Sept 2028 | ECDSA 384 | ECDSA-SHA384 | 4df3b15dd6c0784c507cd37b58e6f115 |
| CN=Root YE,O=ISRG,C=US (CA) | CN=ISRG Root X2,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | ECDSA-SHA384 | 872165fc34b6e5fba8add5b3705fb53a |
| CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) | CN=ISRG Root X1,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | SHA256-RSA | 6c8f1dc727c7117f7baf853ac980f9cd |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of esyurl.fyi. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| fyi. | present | 6839, 24340 | 8, 8 | Verified |
| esyurl.fyi. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication Enforced and verified
The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.
| Result | Enforced and verified |
|---|---|
| Enforced | On tool calls |
| HTTP status | 200 |
WWW-Authenticate challenge Bearer resource_metadata="https://esyurl.fyi/.well-known/oauth-protected-resource"
Bearer resource_metadata="https://esyurl.fyi/.well-known/oauth-protected-resource" | Header | Value |
|---|---|
| strict-transport-security | max-age=31536000; includeSubDomains |
Protected resource metadata
| Document | https://esyurl.fyi/.well-known/oauth-protected-resource |
|---|---|
| Retrieved | Yes |
| Resource | https://esyurl.fyi/ |
| Authorisation server | https://esyurl.fyi |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://esyurl.fyi/mcp | Verified | 200 | |
| http (plaintext) | http://esyurl.fyi/mcp | Inconclusive | 401 |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
add_links_to_group Add links to group ~94
Add up to 25 links to a group in one call. Idempotent: links already in the group are reported in alreadyMembers rather than failing. Fails with not_found if any linkId is unknown (nothing is added).
| Name | Type | Req | Description |
|---|---|---|---|
| groupId | string | yes | The group id (groupId), as returned by create_group or list_groups |
| linkIds | array | yes | 1-25 linkIds |
No output schema declared.
No examples provided.
create_group Create group ~108
Create a group to organise short links (e.g. a campaign or a venue). Groups are many-to-many: a link can be in up to 20 groups. Add links with add_links_to_group, or pass groupIds when creating/updating a link.
| Name | Type | Req | Description |
|---|---|---|---|
| color | string | – | Hex colour for UIs, e.g. #3366ff |
| description | string | – | Up to 500 chars |
| name | string | yes | Group name, up to 100 chars |
No output schema declared.
No examples provided.
create_short_link Create short link ~1,285
Create a short link that redirects to targetUrl, or shows a link page (pass page instead of targetUrl). Returns the link, including linkId (use it with the other tools) and shortUrl (share this). Give a slug for a memorable URL, otherwise a random 8-character one is generated. Slugs are unique across all tenants and cannot be changed later (409 if taken; route names like "api", "admin", "health" are reserved).
| Name | Type | Req | Description |
|---|---|---|---|
| groupIds | array | – | Ids of groups (from create_group/list_groups) this link belongs to, up to 20 |
| metadata | object | – | Up to 20 string key/value pairs for your own bookkeeping |
| name | string | – | Human label, up to 200 chars |
| page | object | – | 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 app… |
| payment | – | – | 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 Paym… |
| qrStyle | object | – | 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… |
| rules | array | – | 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… |
| slug | string | – | Custom slug, ^[a-zA-Z0-9_-]{3,64}$; random if omitted |
| tags | array | – | Free-form labels, up to 20; filter with list_short_links tag |
| targetUrl | string | – | Absolute http(s) URL visitors are redirected to (exclusive with page) |
No output schema declared.
No examples provided.
delete_group Delete group ~47
Delete a group. Its links are NOT deleted; they just stop being members.
| Name | Type | Req | Description |
|---|---|---|---|
| groupId | string | yes | The group id (groupId), as returned by create_group or list_groups |
No output schema declared.
No examples provided.
delete_short_link Delete short link ~83
Permanently delete a short link and remove it from its groups. Its short URL and any printed QR codes stop working (404) and the slug becomes free for anyone. Prefer update_short_link status "paused" if the link may come back.
| Name | Type | Req | Description |
|---|---|---|---|
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
No output schema declared.
No examples provided.
get_account Get account ~43
Your account: tenant (linkLimit and linkCount for sign-up accounts; ownerEmail and claimedAt once a human has claimed it) and the calling credential with its scopes.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_custom_domain Get custom domain ~138
Get this tenant's custom (alias) domain and advance its setup as far as DNS allows. Use it to check progress after creating a DNS record. Lifecycle: pending_validation (create the certificate_validation record, and the optional ownership_verification TXT if listed) → provisioning (automatic, seconds) → pending_dns (create the routing CNAME from the domain to `target`) → active. Nothing advances on its own: call get_custom_domain after each DNS change to move it along. The response always carries `dnsRecords` (exact name/type/value to create, with `done` once seen) and `instructions` saying what to do next.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_group Get group ~49
Fetch one group. To see its links use list_short_links with group = groupId.
| Name | Type | Req | Description |
|---|---|---|---|
| groupId | string | yes | The group id (groupId), as returned by create_group or list_groups |
No output schema declared.
No examples provided.
get_group_visits Get group visits ~97
Combined visit analytics for a group's current member links: totals {visits, qr, direct, bot} and a zero-filled per-day breakdown (UTC). Links removed from the group no longer count.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | How many UTC days back, including today: 1-365, default 30 |
| groupId | string | yes | The group id (groupId), as returned by create_group or list_groups |
No output schema declared.
No examples provided.
get_short_link Get short link ~51
Fetch one short link by linkId, including its groupIds and lifetime visitCount.
| Name | Type | Req | Description |
|---|---|---|---|
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
No output schema declared.
No examples provided.
get_short_link_visits Get short link visits ~227
Visit analytics for one link: totals over the window ({visits, qr, direct, bot}; visits = qr + direct, bots such as link-preview crawlers are counted separately and excluded from visits), a zero-filled per-day breakdown (UTC, oldest first), and the most recent individual visits (newest first, with source, referrerHost, userAgent, country when known, and ruleId when a redirect rule decided it; kept 90 days). byRule splits the window's visits by rule (fallback = went to the link's targetUrl); daily entries carry byRule on days a rule matched. For link pages, byItem counts button clicks per item (daily entries carry clicks by item id).
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | How many UTC days back, including today: 1-365, default 30 |
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
| recent | integer | – | How many recent visit events to include, 0-200, default 50 |
No output schema declared.
No examples provided.
list_groups List groups ~64
List your groups (with linkCount), ordered by groupId. Page with cursor = nextCursor.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | nextCursor from the previous page; omit for the first page |
| limit | integer | – | Page size 1-100, default 20 |
No output schema declared.
No examples provided.
list_short_links List short links ~114
List your short links, newest first. Filter by tag and/or groupId. A page can hold fewer than limit items even when more exist: keep calling with cursor = nextCursor until nextCursor is absent.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | nextCursor from the previous page; omit for the first page |
| group | string | – | Only links in this group (groupId) |
| limit | integer | – | Page size 1-100, default 20 |
| tag | string | – | Only links carrying this tag |
No output schema declared.
No examples provided.
preview_link_page Preview link page ~189
Render a link's page as HTML for a simulated visit, without recording anything: the saved page, or a draft (page) to try before saving (pictures given as data URLs are drawn inline; nothing is stored or charged). Returns the visible item ids (items with "when" conditions depend on the visit) and the HTML.
| Name | Type | Req | Description |
|---|---|---|---|
| acceptLanguage | string | – | – |
| at | string | – | ISO timestamp; default now |
| country | string | – | ISO 3166-1 alpha-2, e.g. "GB" |
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
| page | object | – | A draft to render instead of the saved page |
| query | object | – | – |
| referrer | string | – | – |
| source | string | – | – |
| userAgent | string | – | – |
No output schema declared.
No examples provided.
remove_custom_domain Remove custom domain ~48
Remove this tenant's custom domain. Short links immediately stop resolving on it (QR codes printed with it break) and new short URLs use the platform domain. The DNS records can be deleted afterwards.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
remove_link_from_group Remove link from group ~72
Take one link out of a group. The link itself is untouched.
| Name | Type | Req | Description |
|---|---|---|---|
| groupId | string | yes | The group id (groupId), as returned by create_group or list_groups |
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
No output schema declared.
No examples provided.
render_qr_code Render QR code ~492
Render a QR code as a PNG image. Pass linkId to render a short link: the image encodes {shortUrl}?s=qr so scans are counted as qr visits, and the link's qrStyle is the default look. Or pass data to render any text (URL, Wi-Fi config, vCard...) as a static QR code that is not tracked. Returns the image plus a text line naming exactly what was encoded. Styles are free: module shapes, corner markers, a logo or a halftone photo. Also returns PNG and SVG download URLs that work without a key for an hour (add ?size= for the PNG width): fetch one to save the file, e.g. curl -o qr.svg <url>. A static code with an image has no download URL.
| Name | Type | Req | Description |
|---|---|---|---|
| dark | string | – | Hex colour, e.g. #000000 (the # is optional) |
| data | string | – | Arbitrary text to encode, up to 2048 chars (exclusive with linkId) |
| ecl | string | – | QR error correction level: L 7%, M 15% (default), Q 25%, H 30% |
| eyeBall | string | – | Centre of the corner markers |
| eyeColor | string | – | Colour of the corner markers; defaults to dark |
| eyeFrame | string | – | Outer ring of the three corner markers |
| image | object | – | For data only (a link uses its saved qrStyle). 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 "ha… |
| light | string | – | Hex colour, e.g. #000000 (the # is optional) |
| linkId | string | – | Render this short link (exclusive with data) |
| margin | integer | – | Quiet zone in modules, 0-16, default 4 |
| modules | string | – | Shape of the data modules (default square) |
| size | integer | – | Width in pixels, 64-2048, default 512 |
No output schema declared.
No examples provided.
set_custom_domain Set custom domain ~426
Serve all of this tenant's short links on a domain it controls, e.g. "go.acme.com" → https://go.acme.com/{slug}. Once active, new short URLs and QR codes use it; links keep working on the platform domain too. One domain per tenant: setting a different one replaces (and tears down) the current one. Setting the same one again is harmless, and restarts it if it failed. Two DNS records are needed at the domain's DNS provider, returned one at a time: first a record (TXT or CNAME) that proves control (for the TLS certificate), then a CNAME pointing the domain at the platform. Lifecycle: pending_validation (create the certificate_validation record, and the optional ownership_verification TXT if listed) → provisioning (automatic, seconds) → pending_dns (create the routing CNAME from the domain to `target`) → active. Nothing advances on its own: call get_custom_domain after each DNS change to move it along. The response always carries `dnsRecords` (exact name/type/value to create, with `done` once seen) and `instructions` saying what to do next. Self-signed-up tenants (see /auth.md) pay once per new domain with x402: without a payment the tool returns an error whose structuredContent is an x402 PaymentRequired (x402Version 2, exact scheme, USDC). Retry with the signed PaymentPayload in the request's _meta["x402/payment"] (the x402 MCP transport), or, if your client cannot set _meta, in the `payment` argument. The settlement comes back in _meta["x402/payment-response"]. Re-setting the current domain, reading and removing are free; tenants given a key by an operator never pay.
| Name | Type | Req | Description |
|---|---|---|---|
| domain | string | yes | Bare hostname you control, e.g. go.acme.com - no scheme, port or path |
| payment | – | – | Only if your client cannot send _meta["x402/payment"]: the x402 PaymentPayload, as an object or base64 |
No output schema declared.
No examples provided.
set_domain_home_page Set custom domain home page ~84
Choose the link that the root (/) of this tenant's custom domain shows: a link page becomes the domain's home page, a redirect link sends / there. Pass linkId null to clear it (/ answers 404 again). Has no effect on the platform domain.
| Name | Type | Req | Description |
|---|---|---|---|
| linkId | string|null | yes | The link to show at /, or null to clear |
No output schema declared.
No examples provided.
test_redirect_rules Test redirect rules ~373
Dry run: which destination would a visit with these properties get from this link's rules? For a link page with no matching rule it returns page.itemIds (the buttons that visit would see) instead of targetUrl. Records no visit. Pass a real userAgent to test device routing, e.g. iPhone: "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", Android: "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Mobile Safari/537.36". Returns targetUrl, matchedRule (absent when the link's targetUrl is used) and the context the rules saw (os, device, browser, language, country, referrer, source, query, at).
| Name | Type | Req | Description |
|---|---|---|---|
| acceptLanguage | string | – | e.g. "pt-BR,pt;q=0.9,en;q=0.8" |
| at | string | – | ISO timestamp to evaluate time/weekday/hour rules at; default now |
| country | string | – | ISO 3166-1 alpha-2 country the visitor is in, e.g. "GB" |
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
| query | object | – | Query parameters on the short URL |
| referrer | string | – | Full referring URL, e.g. https://www.instagram.com/ |
| source | string | – | qr simulates a scanned QR code; default direct |
| userAgent | string | – | – |
No output schema declared.
No examples provided.
update_group Update group ~93
Rename a group or change its description or color. Membership doesn't change here.
| Name | Type | Req | Description |
|---|---|---|---|
| color | string | – | Hex colour for UIs, e.g. #3366ff |
| description | string | – | Up to 500 chars |
| groupId | string | yes | The group id (groupId), as returned by create_group or list_groups |
| name | string | – | Group name, up to 100 chars |
No output schema declared.
No examples provided.
update_short_link Update short link ~793
Change a short link. Only the fields you pass change; tags, metadata, qrStyle and groupIds are replaced wholesale (pass the full new list; [] clears). Set targetUrl to send visitors somewhere else: the short URL and printed QR codes keep working. Set status "paused" to make the short URL answer 410, "active" to resume. The slug cannot be changed. page replaces the whole link page (a redirect becomes a page); page: null with a targetUrl turns a page back into a redirect.
| Name | Type | Req | Description |
|---|---|---|---|
| groupIds | array | – | The complete new set of groups; replaces the current one |
| linkId | string | yes | The link id (linkId), as returned by create_short_link or list_short_links |
| metadata | object | – | Up to 20 string key/value pairs for your own bookkeeping |
| name | string | – | – |
| page | – | – | – |
| payment | – | – | 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 Paym… |
| qrStyle | object | – | 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… |
| rules | array | – | The complete new rule list; replaces the current one ([] removes all). Redirect rules, evaluated in order on every visit; the first enabled rule whose "when" matches sends the visitor to its targetUr… |
| status | string | – | – |
| tags | array | – | Free-form labels, up to 20; filter with list_short_links tag |
| targetUrl | string|null | – | New absolute http(s) destination |
No output schema declared.
No examples provided.
How do I install the esyURL MCP server?
esyURL is a hosted endpoint at https://esyurl.fyi/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · esyurl.fyi
claude mcp add --transport http esyurl-mcp 'https://esyurl.fyi/mcp'
What is the esyURL MCP server?
esyURL is an MCP server listed in the public MCP registry as io.github.esyurl/mcp. Short links and trackable QR codes: editable after printing, device routing, scan stats. This page covers its hosted endpoint (https://esyurl.fyi/mcp).
Is the esyURL MCP server safe to use?
esyURL scores 84 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the esyURL MCP server expose?
esyURL exposes 22 tools: create_short_link, list_short_links, get_short_link, update_short_link, preview_link_page, and 17 more. Their descriptions and schemas cost roughly 4,970 tokens of context every time the server is loaded.
Does the esyURL MCP server require authentication?
Yes. esyURL asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.
Is the esyURL MCP server still maintained?
esyURL is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.