What an MCP server for measurement uncertainty actually returns: a CD-SEM 45 nm worked example
A common reaction when I tell people about measurement-uncertainty-mcp is: "OK but show me what it actually does."
Fair. Here is one query, paste-ready for Claude Desktop, with the actual output.
The query
I measured a 45 nm linewidth on a CD-SEM twenty times: 45.12, 45.08, 45.15, 45.11, 45.09, 45.13, 45.10, 45.14, 45.07, 45.12, 45.11, 45.09, 45.13, 45.10, 45.14, 45.08, 45.16, 45.10, 45.12, 45.11 nm. Combine with magnification calibration of ±0.5 nm at k=2 (50 dof) and line-edge roughness ±0.4 nm at k=2 (50 dof). Report u_c, effective ν via Welch-Satterthwaite, and expanded U at 95%.
The tools the MCP calls
-
type_a_uncertainty(samples=[...])— sample mean, Bessel std, u_A, ν_A -
type_b_normal(U=0.5, k=2, nu=50)— u_B1 magnification -
type_b_normal(U=0.4, k=2, nu=50)— u_B2 line-edge roughness -
combine_uncertainty(components=[u_A, u_B1, u_B2])— u_c via root-sum-of-squares -
welch_satterthwaite(components=[...])— ν_eff -
expanded_uncertainty(u_c, nu_eff, level=0.95)— k from Student-t, then U = k × u_c
The actual numbers
| Quantity | Value |
|---|---|
| Mean | 45.1125 nm |
| Sample std (Bessel) | 0.0245 nm |
| u_A (Type A) | 0.0055 nm (ν = 19) |
| u_B1 magnification | 0.2500 nm (ν = 50) |
| u_B2 line-edge roughness | 0.2000 nm (ν = 50) |
| u_c combined | 0.3202 nm |
| ν_eff (Welch-Satterthwaite) | 95.5 |
| k @ 95% | 1.985 |
| U @ 95% | 0.636 nm |
Reported result: 45.11 ± 0.64 nm at 95% confidence (k = 1.99, ν_eff = 95).
Why each step matters (and where Excel gets it wrong)
u_A: the sample std must use the Bessel correction (n−1, not n). About one in ten Excel uncertainty templates I have audited use the population std formula by mistake. The MCP uses numpy.std(ddof=1) — no choice.
u_B from k-expanded inputs: a vendor datasheet that says "±0.5 nm at k = 2" means the standard uncertainty is 0.5/2 = 0.25 nm. The tool exposes this conversion explicitly so it cannot be skipped.
Welch-Satterthwaite: when you combine components with different degrees of freedom, the effective ν is not just the sum. The MCP uses the formula from JCGM 100:2008 §G.4.1 directly. Skipping this step and using k = 2 by default gives the wrong U whenever the dominant component has a small ν.
Coverage factor k: at νeff = 95.5 and confidence = 95%, k = scipy.stats.t.ppf(0.975, 95.5) = 1.985. Note this is _not 2 — using k = 2 by reflex (the common shortcut) gives U = 0.640 nm instead of 0.636 nm. Small difference here, large difference when ν_eff is small.
What this would take in Excel
About 20 minutes per budget, and roughly 10% of attempted budgets have at least one numerical error in my experience auditing calibration certificates. The errors are always one of:
- Bessel skip (population std vs sample std)
- Forgetting to divide a k-expanded input by k
- Using k = 2 by default instead of Welch-Satterthwaite + Student-t
- Misapplying the sensitivity coefficient when the model is non-linear
The MCP makes each of these into a tool call. You cannot skip Bessel because there is no type_a_population_std tool. You cannot skip the k-divide because type_b_normal requires both U and k. The whole point is that the wrong answer is not reachable without explicitly bypassing the typed interface.
Why this is relevant right now
ISO 10012:2026 was published in February — the first revision since 2003. It adds practical requirements around Test Uncertainty Ratio, decision rules, and guard-banding. Every calibration lab is currently updating their templates. The 10 MCP tools cover exactly the primitives the new standard requires.
Try it yourself
claude mcp add --transport http "Measurement Uncertainty" https://measurement-uncertainty.mcpize.run
Free tier: 50 calls/month, no credit card.
Paste the query above into Claude Desktop. The output you get should match the table above to four decimals.
Repo: github.com/kyb8801/measurement-uncertainty-mcp. Live MCP: measurement-uncertainty.mcpize.run. Weekly solo-builder build log: YB's AI Hustle Weekly.
Top comments (0)