FIRST CH TOOLS / 25 USER-AGENT PARSER

User-Agent Parser & Device Detector

Paste a User-Agent string from your access log and it is broken out into browser and version, rendering engine, OS and device type. Every token is explained, and what the UA cannot tell you — frozen values, spoofing, in-app browsers — is called out as you paste. The string you paste never leaves this device.

User-Agent
Browser
OS
Rendering engine
Device type
Result

Paste a User-Agent string above and the breakdown appears here.

Notes — what the UA cannot tell you
JSON
Paste a User-Agent string above and the result appears here as JSON.
Client Hints from this browser

The parts of the UA string that are frozen — Chrome’s minor version, the Android model name, Windows 10 versus 11 — can still be read accurately from User-Agent Client Hints. Below is what the browser you are using right now reports about itself. It is not sent anywhere.

How to Use

  1. Paste the UAPaste a User-Agent string copied from an access log or from your browser’s developer tools. A leading User-Agent: header name and surrounding quotes are stripped for you. To inspect the browser you are using right now, press “This browser”.
  2. Read the tableBrowser, OS, engine and device type appear in the panel above, with the full breakdown in the table below. The token breakdown shows, one token at a time, why fossils such as Mozilla/5.0 and like Gecko are still there.
  3. Check the limitsThe notes list what this particular UA cannot tell you — Windows 10 versus 11, a model name frozen to K, and so on. Know those limits before you write code that branches on them.

About This Tool

A User-Agent is a string the browser chooses to say about itself. Its contents are sediment from the compatibility wars of the 1990s, which is why almost every browser still opens with Mozilla/5.0. Chrome claims Safari/537.36; Edge claims both Chrome/ and Safari/. Matching on the substring “Safari” or “Chrome” will therefore misclassify most of your traffic. Detection has to try the more specific token first — Edg/, then OPR/, then Chrome/, then Safari/ — which is exactly the order this page uses.

The biggest change happening right now is User-Agent Reduction. Since Chrome 110 (2023) parts of the string are frozen to fixed values. The browser’s minor version is always 0.0.0, and the Android version and model are replaced by the fictional Android 10; K. On macOS both Safari and Chrome freeze the version at 10_15_7, so a brand-new Mac still reports “macOS 10.15.7”. None of this is a bug — it is deliberate, and it exists to limit fingerprinting. When you need the real values, use User-Agent Client Hints.

Some distinctions are impossible from the UA alone. Windows NT 10.0 covers both Windows 10 and Windows 11; telling them apart needs Sec-CH-UA-Platform-Version (14.0.0 or higher means Windows 11). An iPad in its default “Request Desktop Website” mode sends exactly the same UA as Safari on a Mac; navigator.maxTouchPoints > 1 is what separates them. And on iOS every browser is required to use WebKit, so Chrome for iOS renders with the same engine as Safari.

Spotting an in-app browser is the most practically useful result here. A page opened from LINE, Instagram, Facebook or X is running inside a WebView embedded in that app, not in Safari or Chrome. File downloads, redirects to external payment pages and some storage APIs may be unavailable, which is the usual explanation for “it works on my phone, but not for users who arrive from social”. This tool flags Line/, Instagram, FBAN and the Android WebView marker wv.

Never use a UA as the basis for access control. Anyone can claim any string with one line of configuration, so “allow it because it is Googlebot” is bypassed by simply saying you are Googlebot. To confirm a real search engine, run a forward-confirmed reverse DNS lookup on the source IP. Keep the UA for statistics, troubleshooting and legacy-browser notices.

When you want to branch on a capability, use feature detection rather than UA sniffing. Asking if (window.IntersectionObserver) — does this thing exist? — survives both UA quirks and future browsers. UA detection is genuinely needed only where feature detection cannot express the question, such as working around a bug in one specific version.

You can call it straight from the URL: /en/user-agent/?ua=Mozilla%2F5.0… (URL-encode the value), or /en/user-agent/?ua=me to load the browser’s own UA.

From AI Agents

The same parsing logic is available as the user_agent_parse tool of our MCP (Model Context Protocol) server @first-ch/tools-mcp, so an AI agent can call it directly without driving a browser — much faster when working through an access log. See Using these tools from AI agents for setup.

Setup

claude mcp add firstch-tools -- npx -y @first-ch/tools-mcp

Examples

# Parse one UA string
user_agent_parse(ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...")

# Pass a raw log line (a `User-Agent:` prefix is fine)
user_agent_parse(ua="User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) ...")

# Parse many UA strings at once and get a summary
user_agent_parse(uas=["Mozilla/5.0 ...", "Mozilla/5.0 ..."])

Other Tools