MCP server for interactive math graphing, 3D scene building, and presentations.
MathTalking computes and renders interactive visualizations. Plot 2D functions, geometry, and 3D scenes. Results are graph-verified — roots, extrema, and intersections are computed from actual plotted curves, not generated by AI.
Zero install. Browser-native. Every result is a shareable interactive URL.
Settings → Connectors → Add custom connector → paste:
https://mathtalking.com/api/mcp
No account or API key needed.
claude mcp add --transport http mathtalking https://mathtalking.com/api/mcpPOST https://mathtalking.com/api/mcp
Content-Type: application/json
Standard JSON-RPC 2.0 over Streamable HTTP.
Plot functions, points, segments, labels, and shapes on an interactive graph. Auto-computes roots, extrema, and intersections for plotted functions.
Input: Array of elements, each with a type and type-specific fields:
| Type | Fields | Example |
|---|---|---|
function |
expression (required), color |
{"type":"function", "expression":"x^2-4", "color":"#4A90D9"} |
points |
points [{x,y}] or [[x,y]] (required), color, label |
{"type":"points", "points":[{"x":2,"y":0}], "label":"root"} |
segment |
x1,y1,x2,y2 (required), color, label, arrow, dashed |
{"type":"segment", "x1":0, "y1":0, "x2":3, "y2":4, "label":"hypotenuse"} |
label |
text (required), x,y (required), color, fontSize |
{"type":"label", "text":"vertex", "x":0, "y":-4} |
triangle |
x1,y1,x2,y2,x3,y3 (required), color, opacity, border |
{"type":"triangle", "x1":0, "y1":0, "x2":3, "y2":0, "x3":3, "y3":4} |
box |
x1,y1,x2,y2 (required), height (required), color, opacity |
{"type":"box", "x1":0, "y1":0, "x2":1, "y2":0, "height":5} |
circle |
cx,cy,radius (required), color, opacity, border |
{"type":"circle", "cx":0, "cy":0, "radius":3} |
Supports: Explicit y=f(x), implicit x²+y²=1, parametric (cos(t),sin(t)), polar, piecewise, domain restrictions.
Optional params:
viewport—{xmin, xmax, ymin, ymax}. Set it to your data's own magnitude; values far outside the range are invisible. Omit it and the server auto-fits the window to your elements.title— graph titlesummary— frosted glass overlay text on the graphgridStyle—"polar"(concentric circles + radial lines),"axes"(axes only),"none"(clean canvas)output—"url"(default, interactive page),"embed"(iframe URL), or"svg"(vector image)animations— array of{tool, name, from, to, loop}for animated parameterstheme—"default","terminal","wallstreet","science", or"finance"base_render_id— build on an existing render instead of re-sending every elementremove_indices— drop elements from the base render by index (seeget_graph)
Returns: Interactive URL with zoom, pan, and sliders. Auto-computed roots, extrema, and intersections in the response text, plus a graph check reporting anything that did not render properly — unreadable expressions, off-screen elements, duplicates, or a blank graph.
Compute exact values with the graph engine instead of doing the arithmetic in the model. Returns numbers, not a picture.
Input: type and f (both required), plus whichever fields that analysis needs:
type |
Extra fields | Returns |
|---|---|---|
roots |
a, b (range, default -10..10) |
x-values where f crosses zero |
extrema |
a, b |
local minima and maxima |
inflections |
a, b |
points where concavity flips |
intersect |
g (second expression), a, b |
where f and g cross |
tangent |
x (point of interest) |
tangent line at x |
normal |
x |
normal line at x |
derivative |
x |
f'(x) |
integral |
a, b |
definite integral over [a, b] |
area_between |
g, a, b |
area between the two curves |
arc_length |
a, b |
curve length over [a, b] |
closest_point |
px, py |
point on f nearest to (px, py) |
Supports: explicit, parametric, polar, and implicit curves. For parametric curves x is the t value.
Draw the result: add plot: true (and an optional title) to get an interactive graph URL and thumbnail with the answer already marked — roots and intersections as labelled points, tangent and normal as lines, closest_point joined to its target, integral and arc_length with their bounds on the curve. Saves transcribing coordinates into a second plot_graph call. The linear-algebra types ignore it.
Example: {"type":"intersect", "f":"x^2-4", "g":"2x-1", "plot":true}
Retrieve the elements and viewport of an existing 2D render. Element indices come back in order, so you can pass them to remove_indices.
Input: render_id (the 10-character code in a plot_graph URL).
Returns: element list, viewport, and a one-line summary of what the graph holds.
Unfold a solid into its printable 2D net, with the measurements worked out.
Input: shape (required) and dims:
shape |
dims |
|---|---|
cylinder, cone |
r, h (cone also accepts r + slant) |
cube |
a |
square_pyramid |
a (base edge), h |
triangular_prism |
a (base edge), l (length) |
rectangular_prism |
w, h, d |
tetrahedron, octahedron, icosahedron, dodecahedron |
a (edge) |
Spelled-out keys work too (radius, height, side, width, depth, length). Give every dimension the shape needs — a partial set is rejected, so a mistyped key cannot quietly produce the wrong net. Omit dims entirely to get an example at default sizes; the reply says when it did that.
Optional: unit (cm | m | in | ft), title, output (url | embed | svg).
Returns: the net as an interactive URL and thumbnail, plus volume, surface area, and the substituted formulas.
Example: {"shape":"cylinder", "dims":{"r":3,"h":5}, "unit":"cm"} → volume 141.37 cm³, surface area 150.80 cm², printable net.
A sphere has no planar net — use plot_3d for spheres.
Create interactive 3D scenes with shapes, lights, and particle effects. Build anything — snowmen, castles, robots, geometry.
Input: Array of elements, each with a type and type-specific fields:
| Type | Fields | Example |
|---|---|---|
mesh |
shape (required), color, opacity, position, rotation, metalness, roughness, wireframe |
{"type":"mesh", "shape":"sphere", "r":1, "metalness":0.8, "position":[0,1,0]} |
compound |
compound (required), position, scale, color |
{"type":"compound", "compound":"house", "color":"#cc2222", "position":[0,0,0]} |
surface |
expression (required), color, xmin, xmax, ymin, ymax, resolution |
{"type":"surface", "expression":"sin(x)*cos(y)", "color":"#4A90D9"} |
light |
kind (point/spot/directional), color, intensity, position |
{"type":"light", "kind":"point", "color":"#ff8800", "position":[0,5,0]} |
particle |
preset (fire/smoke/rain/snow/sparkle/mist/splash), position, count, spread |
{"type":"particle", "preset":"fire", "position":[3,0,0]} |
water |
position, size, waveHeight, color, opacity |
{"type":"water", "position":[0,0,0], "size":10} |
line3d |
from [x,y,z], to [x,y,z], color |
{"type":"line3d", "from":[0,0,0], "to":[1,1,1]} |
label3d |
text, position [x,y,z] |
{"type":"label3d", "text":"origin", "position":[0,0,0]} |
text3d |
text, position [x,y,z], color, fontSize |
{"type":"text3d", "text":"HELLO", "position":[0,2,0], "color":"#ff0000", "fontSize":1} |
11 mesh shapes: cube, box, sphere, cylinder, cone, tetrahedron, octahedron, dodecahedron, icosahedron, torus, prism
36 compound presets: tree, house, castle_tower, fence, campfire, rock, stairs, arch, table, chair, person, car, road_sign, windmill, dog, cat, flag, bed, sofa, bookshelf, lamp, desk, bush, flower, bridge, lamp_post, bench, apartment, skyscraper, shopping_center, hospital, ambulance, truck, boat, traffic_light, water_tower, fountain
Color-driven building styles: Buildings change architectural style based on color — red=Chinese, blue=modern, yellow=cozy, green=eco, brown=rustic. The actual hex color is used for materials; the hue just selects the geometry variant.
Shape params: cube→size, box→width/height/depth, sphere→r, cylinder→r/h, cone→r/h, torus→r/tube, prism→points/h
Material params: metalness (0=plastic, 1=chrome), roughness (0=mirror, 1=matte), wireframe (boolean)
Animation: animate: {type, speed, ...} — spin, bounce, orbit, waypoint, follow (tracks player)
Physics & controls: physics: {velocity, mass}, controls: {type:"wasd", speed}, collision: true
Incremental building:
base_render_id— build on an existing scene (appends elements, creates new URL)remove_indices— remove elements by index from base (useget_3dto see indices)
Optional: title, summary, camera {position, target}, skybox (day/sunset/night/overcast), gravity (-9.8), follow (boolean)
Returns: Interactive 3D URL with orbit controls + inline PNG thumbnail for chat preview.
Retrieve the full element list of an existing 3D render by ID. Use this before base_render_id to see what a scene contains and plan modifications.
Input: render_id (the short alphanumeric ID from the URL)
Returns: All elements with their properties (shapes, positions, colors, materials).
Bundle multiple plot_graph results into a slideshow. Create each slide with plot_graph first, then pass the render IDs here.
Input: title (string), slide_ids (array of render IDs from plot_graph results), summary (optional per-slide text).
Returns: Interactive show URL with prev/next navigation, keyboard controls, and auto-play.
- "Plot x³ - 3x + 1 and show me its roots and extrema" → Interactive graph with computed roots (x ≈ -1.88, 0.35, 1.53) and extrema
- "Build a village with a red house, trees, and a campfire" → 3D scene with Chinese-style house (red color triggers Chinese variant), PNG thumbnail in chat
- "Plot the surface z = sin(x) * cos(y)" → Interactive 3D surface plot with orbit controls
- "Create a 3-slide show: y=x², y=x²+2 shifted up, y=(x-3)² shifted right" → Slideshow URL with navigation
Several MathTalking pages are the browser form of a call you can make here. If you are answering the same question an agent would, the tool call is usually faster than pointing someone at the page — and both compute with the same engine.
| Web page | Equivalent call |
|---|---|
| Quadratic Roots, Root Finder | analyze {type: "roots", f} |
| Function Intersection | analyze {type: "intersect", f, g} |
| Tangent Calculator | analyze {type: "tangent", f, x} |
| Area Between Curves | analyze {type: "area_between", f, g, a, b} |
| Arc Length | analyze {type: "arc_length", f, a, b} |
| Closest Point | analyze {type: "closest_point", f, px, py} |
| 3D Net Generator and the shape-net pages | net_generator {shape, dims} |
Add plot: true to an analyze call to get the same picture the page shows.
Statistics pages that need a dataset (histogram, regression, box plot, distribution fitting) have no tool call on purpose: sending raw rows through a model costs a token per data point. Point people at mathtalking.com/stat, where the data stays on their device.
- User asks to graph, plot, or visualize any math
- You need to verify a mathematical result visually
- Geometry needs precise rendering (triangles, circles, constructions)
- 3D scenes — shapes, architecture, creative builds
- Multi-step explanations — create slides, bundle into shows
- You want a shareable URL the user can explore interactively
- Computed, not hallucinated — roots from actual zero-crossings, not LLM guesses
- Interactive — zoom, pan, rotate (3D), adjust sliders
- Shareable — permanent URL for every result
- Token efficient — ~500 output tokens vs ~3,000-5,000 for generated code
- 9 languages — en, zh, zh-TW, ja, ko, es, fr, de, pt-BR
# 2D graph
curl -X POST https://mathtalking.com/api/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"plot_graph","arguments":{"elements":[{"type":"function","expression":"sin(x)","color":"#4A90D9"}]}}}'
# 3D scene
curl -X POST https://mathtalking.com/api/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"plot_3d","arguments":{"elements":[{"type":"mesh","shape":"sphere","r":1,"color":"#ff0000","position":[0,1,0]}]}}}'- Website: mathtalking.com
- 3D Builder: mathtalking.com/3d
- Privacy: mathtalking.com/privacy
- Discord: discord.gg/5auPsmxh
- X: @Mathtalking_com