We Built a CrUX MCP Server — Real Core Web Vitals Field Data, Directly in Claude Code
What Google actually measures for ranking isn’t in your Lighthouse report. It’s in the Chrome User Experience Report — 28 days of real user data, p75 percentile, split by device. This MCP server makes that field data queryable in seconds.
01The PSI Paradox
Every SEO team knows the situation: PageSpeed Insights shows 94 on Mobile — all green. Two weeks later, Search Console flags a Core Web Vitals warning for the same page.
No bug. No error. That’s the difference between lab data and field data.
| PageSpeed Insights (Lab) | CrUX (Field) | |
|---|---|---|
| Data source | Simulated test machine | Real Chrome users |
| Device profile | Fixed (Mobile 4G, throttled) | All real devices and connections |
| Form factor | Single view | Mobile / Desktop / Tablet separate |
| Refresh rate | Every test run | 28-day rolling window |
| What Google uses | ✗ Not for CWV ranking | ✓ Direct ranking input |
| Feedback latency | Instant | 28 days to full visibility |
PageSpeed Insights is indispensable for diagnosis and optimisation — but it is not what Google uses for its ranking algorithm. For that, you need CrUX.
02What CrUX Actually Measures
CrUX (Chrome User Experience Report) is Google’s collection of field data from real Chrome users (Real-User Monitoring, RUM) — aggregated over 28 days — used to assess Core Web Vitals at URL or origin level. Users who have opted into performance reporting contribute automatically, without any personally identifiable data being collected.
Three properties make CrUX relevant for SEO:
- 28-day rolling window. The current dataset always covers the last 28 days. No cut-off date, no monthly report — rolling, continuous.
- p75 — not the average. Google assesses the 75th percentile, not the median: 75% of users experience this metric at least as well, 25% experience it worse. Ignoring that bottom quartile produces false-positive assessments.
- Form factor split. CrUX can be queried separately for Mobile, Desktop, and Tablet. The aggregated “ALL” view often hides completely different problems for mobile and desktop users.
The five CrUX metrics:
| Metric | Code | Good | NI | Poor |
|---|---|---|---|---|
| Largest Contentful Paint | LCP | ≤ 2,500 ms | 2,500–4,000 ms | > 4,000 ms |
| Cumulative Layout Shift | CLS | ≤ 0.10 | 0.10–0.25 | > 0.25 |
| Interaction to Next Paint | INP | ≤ 200 ms | 200–500 ms | > 500 ms |
| First Contentful Paint | FCP | ≤ 1,800 ms | 1,800–3,000 ms | > 3,000 ms |
| Time to First Byte | TTFB | ≤ 800 ms | 800–1,800 ms | > 1,800 ms |
LCP, CLS, and INP are the three Core Web Vitals — all three must be “good” for an origin to pass CWV.
03The Stack
The MCP server is written in Python, runs locally, and is wired into Claude Code. The core framework is FastMCP — the same foundation as our Keyword and GSC servers.
seo_crux_querycwv_pass flag.A typical call:
seo_crux_query("https://example.com", form_factor="PHONE")
Returns: p75 values for all available metrics, good/NI/poor rating, histogram buckets (share of users in each bucket), and a cwv_pass flag. If the origin lacks sufficient traffic, the API returns 404 — the most honest answer CrUX can give.
04Two Brands, One Pattern
Two eCommerce brands, both mobile-heavy. Both failing CWV. And both with completely different problems — depending on the device.
Brand A (Snapshot · 2026-05-30 → 2026-06-26)
| Metric | Mobile (84%) | Desktop (13%) | Note |
|---|---|---|---|
| LCP | 2,903 ms ⚠️ NI | 2,403 ms ✅ Good | Mobile problem |
| CLS | 0.02 ✅ Good | 0.17 ⚠️ NI | Desktop problem |
| INP | 194 ms ✅ Good | 114 ms ✅ Good | Both fine |
| TTFB | 1,601 ms ⚠️ NI | 1,456 ms ⚠️ NI | Server-side |
| CWV | ❌ Fail | ❌ Fail |
The aggregated “ALL” shows LCP at 2,891 ms — Needs Improvement. Unremarkable. Only the form factor split reveals: mobile fails on LCP, desktop fails on CLS — two different root causes, two different optimisation tracks.
Brand B (Snapshot · 2026-05-30 → 2026-06-26)
| Metric | Mobile (86%) | Desktop (13%) | Note |
|---|---|---|---|
| LCP | 4,270 ms ❌ Poor | 2,797 ms ⚠️ NI | Critical on mobile |
| CLS | 0.08 ✅ Good | 0.39 ❌ Poor | Desktop problem |
| INP | 537 ms ❌ Poor | 344 ms ⚠️ NI | Critical on mobile |
| TTFB | 3,129 ms ❌ Poor | 2,318 ms ❌ Poor | Infrastructure issue |
| CWV | ❌ Fail | ❌ Fail |
Brand B is significantly more critical: LCP, INP, and TTFB are Poor on Mobile. Desktop fails on CLS at 0.39. A TTFB of over 3 seconds on Mobile points to a fundamental server speed or CDN issue — all other metrics suffer as a consequence.
- 01The aggregated “ALL” averages across all device types. With 84–86% mobile share, mobile dominates — desktop problems disappear statistically.
- 02Brand A: mobile fails on LCP (image load time), desktop fails on CLS (layout shift). Both problems require different fixes.
- 03Brand B: TTFB > 3 sec on mobile is an infrastructure problem. No frontend fix resolves it — the root cause sits before the first byte.
05The History Behind the Numbers
A snapshot shows the current state. CrUX history shows why the current state exists.
Brand A — Recovery with Silent Regression
| Date | LCP p75 | Status | What happened |
|---|---|---|---|
| 2025-12-07 | 4,026 ms | ❌ Poor | Baseline — critical |
| 2025-12-21 | 3,614 ms | ❌ Poor | Slight improvement |
| 2026-01-25 | 3,643 ms | ❌ Poor | New year effect |
| 2026-02-22 | 3,142 ms | ❌ Poor | Performance push visible |
| 2026-04-12 | 2,686 ms | ⚠️ NI | Best result — close to “good” |
| 2026-05-24 | 2,895 ms | ⚠️ NI | Silent regression since April |
Between December and April, LCP improved by 33% — from Poor to nearly Good. Since April the value has been drifting back with no visible triggering event. The classic silent regression: no deployment, no obvious change — but something shifted.
Brand B — No Recovery in Sight
| Date | LCP p75 | Status | What happened |
|---|---|---|---|
| 2025-12-07 | 2,752 ms | ⚠️ NI | Still acceptable |
| 2026-01-04 | 3,508 ms | ❌ Poor | Crosses into Poor territory |
| 2026-01-18 | 4,058 ms | ❌ Poor | Worst point so far |
| 2026-02-22 | 3,514 ms | ❌ Poor | No real recovery |
| 2026-04-12 | 3,709 ms | ❌ Poor | Stagnation at high level |
| 2026-05-24 | 4,073 ms | ❌ Poor | New all-time low |
Brand B was still in the NI range in December — 25 weeks later LCP is Poor and getting worse. The TTFB history shows the same pattern: from 2,259 ms in December to 3,052 ms in May. No corrective action visible.
A single PSI run would have shown neither of these trajectories — neither the recovery nor the uninterrupted decline.
06What Google Actually Measures for Ranking
The CWV report in Google Search Console is not an approximation of CrUX data — it is CrUX data. Core Web Vitals aren’t the only ranking factor. But they are a measurable part of Page Experience — and the only one Google backs with real user data.
Three practical implications:
- The 28-day lag is real. An optimisation that goes live today takes 28 days to be fully visible in the CrUX window. A PSI improvement is measurable immediately; a CWV improvement in Search Console only appears fully after a month.
- CWV is binary. Either all three metrics (LCP, CLS, INP) are “good” — or the origin fails. NI on one metric = fail. There is no “close enough”.
- Form factor matters. Google’s mobile-first indexing means mobile CrUX data carries the most weight. Brand A and Brand B fail primarily because of their mobile scores — even where desktop partially fares better.
- 01LCP ≤ 2,500 ms AND CLS ≤ 0.10 AND INP ≤ 200 ms = ✅ CWV passed. All three. Simultaneously.
- 02Brand A mobile: LCP 2,903 ms = NI → CWV fail. One metric is enough to fail.
- 03TTFB is not a CWV metric, but it directly drives LCP: a slow first byte means a slow LCP element load. For Brand B (TTFB 3,129 ms on mobile), LCP optimisation is impossible without fixing TTFB first.
07In Client Work
The CrUX server is the ninth module in our MCP stack. When it comes before PSI, when PSI comes first:
- Search Console flags a CWV warning → CrUX first: what does Google see right now? Which metric, which device?
- Split CrUX by form factor → Query mobile and desktop separately. The aggregated view isn’t wrong, it just hides the detail.
- Query CrUX history → When did this problem develop? Was it a deployment event or a silent regression?
- PSI for root cause analysis → What exactly is causing the LCP problem? Which element? Which resource type? PSI answers this instantly; CrUX doesn’t.
- Deploy the fix, verify via PSI → Immediate lab-based feedback.
- Wait 28 days, re-query CrUX → Has the ranking signal improved?
The module set
| Module | Function |
|---|---|
| Keywords | Search volume, competition, CPC, trends |
| SERP | Live top-10 for any keyword |
| Authority | Domain authority (Open PageRank) |
| GSC | Impressions, clicks, position |
| Trends | Time series + rising queries |
| Geo | Local visibility by region |
| Lighthouse | Core Web Vitals & technical audit (lab) |
| Schema | Structured data validation |
| CrUX ← NEW | Core Web Vitals field data — what Google actually sees |
08Why It Matters
- 01CrUX is the data source for Google’s CWV ranking signal — not PSI, not Lighthouse. Optimising only lab data means optimising around the ranking signal, not for it.
- 02The form factor split is not optional. Brand A fails mobile on LCP and desktop on CLS — two completely different root causes. The aggregated “ALL” hides both.
- 03CrUX history shows what one-off measurements never reveal: the silent post-April regression (Brand A) and the uninterrupted decline with no recovery (Brand B).
- 04The 28-day lag is not a bug — it’s the system. PSI and CrUX are complementary: PSI for instant feedback, CrUX for what actually counts in ranking.
- 05One of nine MCP modules — Keywords, SERP, Authority, GSC, Trends, Geo, Lighthouse, Schema, and now CrUX. All in-session, no tool switching.