DEV Community

Jukka Blomberg
Jukka Blomberg

Posted on

A physics MCP server that shows its working: 31 calculators, 34 CODATA constants, no key

If you are building a homework helper or a tutoring agent, the hard part of a physics question is rarely the arithmetic. It is the formula, the units and the steps a student can follow. Language models are good at explaining and still slip on numbers, so we gave our physics calculators a door that agents can call directly.

Since yesterday (3 November 2026) the UsePhysics MCP server is listed in the official MCP Registry as com.usephysics/physics-calculators. It is a remote server (Streamable HTTP), free, and it needs no key:

https://usephysics.com/api/mcp
Enter fullscreen mode Exit fullscreen mode

What is behind it

Four read-only tools:

tool what it returns
list_calculators every calculator: id, formula, input keys with units and defaults, page URL
calculate the results with units, the formula, the worked steps where the engine can derive them, and a link to the solved page
get_constant one CODATA 2022 constant as NIST prints it, with its uncertainty (or "exact") and the NIST source
list_constants the constants we keep, in groups

As served today: 31 calculators in seven categories (15 of them mechanics: free fall, projectile motion, torque, tension, terminal velocity and so on) and 34 constants in six groups, from the seven SI defining constants to particle masses.

One call, end to end

No SDK needed. This is plain Python against the live endpoint, and the output below is what it printed this morning:

import json, urllib.request

URL = "https://usephysics.com/api/mcp"

def call(tool, args):
    body = {"jsonrpc": "2.0", "id": 1, "method": "tools/call",
            "params": {"name": tool, "arguments": args}}
    req = urllib.request.Request(URL, json.dumps(body).encode(), {
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream"})
    raw = urllib.request.urlopen(req).read().decode()
    data = next(l[6:] for l in raw.splitlines() if l.startswith("data: "))
    return json.loads(json.loads(data)["result"]["content"][0]["text"])

r = call("calculate", {"calculator_id": "free-fall", "inputs": {"h": 20}})
print([i["key"] + "=" + str(i["value"]) for i in r["inputs"]])
print("\n".join(r["show_work"]))
print(call("get_constant", {"query": "planck constant"})["value_as_printed"])
Enter fullscreen mode Exit fullscreen mode
['h=20']
Given: h = 20 m
Formula: t = √(2h/g)
Substitute: t = √(2 × 20 / 9.80665)
Result: t = 2.02 s
6.626 070 15 × 10^-34
Enter fullscreen mode Exit fullscreen mode

The same answer also carries the impact speed (19.81 m/s, or 71.3 km/h) and a link that reopens the solved calculator with the inputs filled in: usephysics.com/calculators/free-fall?h=20. That link is the useful bit for a tutoring agent: the student gets a page they can change and re-run, not just a number in a chat.

Three things worth knowing before you wire it in

  1. Call list_calculators first and use its keys. The free-fall height is h, kinetic energy takes m and v. Inputs are in the units listed next to each key.
  2. Read back the inputs array. Every answer echoes the values it actually used, including any default it filled in for a key you did not send. If an echoed value is not the one you meant, your key name was wrong.
  3. Worked steps are not there for every calculator yet. Free fall returns Given → Formula → Substitute → Result; some calculators return the result and the formula with show_work: null. The formula is always there, so an agent can still explain the step itself.

Constants come straight from NIST's 2022 CODATA listing (retrieved 26 July 2026), and exact constants say so: Planck's constant comes back with "exact": true and no uncertainty, because since 2019 it defines the kilogram.

The answers are educational calculations from the formula shown. They are good for homework and for checking your own working, not for engineering sign-off. The full calculator list, with formulas, is also in usephysics.com/llms.txt.

Top comments (0)