Math MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Math MCP ServerWhat is the derivative of x^3?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Math MCP Server
Powerful symbolic mathematics and statistical analysis for Cursor AI and Claude Desktop. Solve equations, compute derivatives and integrals, perform statistical tests, analyze data, and more—all through natural language requests. Powered by SymPy and SciPy.
What This Does
The Math MCP server provides Cursor and Claude Desktop with powerful symbolic and numerical math capabilities. Instead of guessing at math or writing code, you can ask natural language questions and get accurate mathematical results.
Available Tools (4-tool interface)
The server exposes 4 tools via list_tools. Discovery and execution use these:
Tool | Purpose |
| List available math tools. Call with no args for categories and a flat list (name + intent). Call |
| Return the full descriptor (name, description, inputSchema) for a named math tool. Use after |
| Execute a math tool by name. Call |
| Run multiple tools in one request; results in call order. Pass |
Discovery flow: Call math_ls() to see all 26 internal tools (algebra, calculus, numbers, stats, ode, charts, output). Use math_man(name) for one tool’s parameters or math_ls(category) for a full category. Then call math(name, arguments) to run.
Internal tools (26) include: simplify, solve, factor, expand, derivative, integral, evaluate, to_fraction, convert_unit, find_root, describe_data, ttest, correlation, linear_regression, moving_average, solve_ode, plot_ode_solution, plot_timeseries, plot_bar, plot_histogram, plot_scatter, plot_heatmap, plot_stacked_bar, plot_stackplot, plot_pie, latex.
Example Usage
Once configured, you can ask math questions naturally:
"Solve x^2 - 4 = 0" → Finds roots using
solvetool"What's the derivative of x^3?" → Computes derivative using
derivativetool"Simplify sin(x)^2 + cos(x)^2" → Simplifies expression using
simplifytool"Evaluate 2*pi" → Evaluates numerically using
evaluatetool"Factor x^2 - 4" → Factors expression using
factortool"Integrate x^2" → Computes integral using
integraltool"Convert x^2 + 1/2 to LaTeX" → Converts to LaTeX using
latextool"Convert 0.5 to a fraction" → Converts decimal using
to_fractiontool"Simplify 6/8" → Simplifies fraction using
simplifytool (e.g.math("simplify", {"expression": "6/8"})→ "3/4")"Convert 100 meters to kilometers" → Converts units using
convert_unittool"Solve dx/dt = -x with x(0)=1 from t=0 to t=5" → Solves ODE using
solve_odetool"Find the root of x^2 - 4 near x=1" → Finds root using
find_roottool"What's the p95 response time for these values?" → Computes descriptive statistics using
describe_datatool"Is there a significant difference between these two samples?" → Performs t-test using
ttesttool"What's the correlation between traffic and error rate?" → Calculates correlation using
correlationtool"Fit a linear trend to this data" → Performs regression using
linear_regressiontool"Smooth these metrics with a moving average" → Applies smoothing using
moving_averagetool"Plot this time series data" → Creates visualization using
plot_timeseriestool"Create a bar chart of these categories" → Creates chart using
math("plot_bar", {...})"Show me a histogram of these values" → Creates histogram using
plot_histogramtool"Plot this data with custom colors: red for series A, blue for series B" → Uses
colorsparameter in plotting tools"Create a bar chart with green bars" → Uses
colorparameter for single-color plots"Plot this time series with the legend in the upper right corner" → Uses
legend_locparameter"Show this data with a secondary y-axis for temperature" → Uses
secondary_yparameter for dual-axis plots"Plot with dashed lines for the first series and solid for the second" → Uses
linestylesparameter"Create a bar chart with horizontal bars" → Uses
horizontal=Trueparameter"Plot this data with x-axis limits from 0 to 100" → Uses
xlimparameter to set axis range"Show this histogram with y-axis from 0 to 50" → Uses
ylimparameter to set axis range"Plot with no grid lines" → Uses
grid=Falseparameter"Create a chart with only vertical grid lines" → Uses
grid='y'parameter"Plot this time series with rotated x-axis labels at 90 degrees" → Uses
xlabel_rotationparameter"Create a larger plot, 1200 by 800 pixels" → Uses
figsizeparameter to control plot dimensions (in pixels)"Plot this time series with values displayed on each point" → Uses
show_values=Trueparameter to display data point values"Format values as currency with 2 decimals" → Uses
value_format='$.2f'parameter for currency formatting"Create a chart as SVG" or "Output the plot as SVG" → Use
output_format='svg'on any plotting tool (default is'png')"Run simplify, evaluate, and solve in one go" → Use
math_batchwithcalls: list of{name, arguments}; results are returned in the same order
Cursor and Claude Desktop see the 4 tools; use math_ls() then math(name, arguments) or math_man(name) to discover and run the 26 math capabilities.
Perfect for code that involves math, physics simulations, data analysis, statistical testing, performance monitoring, engineering problems, or any task requiring mathematical computation.
Related MCP server: Vibe Math MCP
Quick Start
Get up and running with Math MCP in Cursor or Claude Desktop using Docker stdio (recommended).
Step 1: Build the Docker Image
docker build -t math-mcp .Step 2: Configure Cursor
Add to your Cursor MCP settings (~/.cursor/mcp.json):
{
"mcpServers": {
"math-mcp": {
"command": "docker",
"args": ["run", "-i", "--rm", "math-mcp"]
}
}
}If you already have other MCP servers configured, just add "math-mcp" to your existing mcpServers object:
{
"mcpServers": {
"your-existing-server": {
"command": "...",
"args": [...]
},
"math-mcp": {
"command": "docker",
"args": ["run", "-i", "--rm", "math-mcp"]
}
}
}Restart Cursor for the changes to take effect.
Step 3: Configure Claude Desktop
Add to your Claude Desktop MCP settings. The configuration file location varies by OS:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"math-mcp": {
"command": "docker",
"args": ["run", "-i", "--rm", "math-mcp"]
}
}
}Restart Claude Desktop for the changes to take effect.
That's It!
Once configured, you can ask math questions naturally in Cursor or Claude. See Example Usage above for examples.
Using the Cursor skill (in-repo)
This repo includes a Cursor skill tree in docs/skills/math-mcp/ that guides AI agents on when and how to use the Math MCP server: 4-tool interface, problem classification, data preparation, analysis workflow, visualization, and batching.
What’s included
Path | Purpose |
Main skill: when to use math-mcp, tool discovery ( | |
DuckDB + jq data pipeline, MCP artifacts pattern | |
Step-by-step analysis, data size, multi-variable and complex problems | |
Chart design, graph type selection, color and quality checklist |
Use in this repo
With the Math MCP server configured (see Quick Start or HTTP Endpoint Setup), Cursor can use the skill when working in this workspace. Reference the skill so the agent loads it for math-related tasks, for example:
In Cursor rules: add a rule that points at
docs/skills/math-mcp/SKILL.mdfor math, statistics, or data visualization tasks.In AGENTS.md: list
docs/skills/math-mcp/SKILL.mdunder key docs so agents read it when handling math or analysis.
Use in other projects (global install)
To make the math-mcp skill available in all Cursor projects:
# From this repo root
cp -r docs/skills/math-mcp ~/.cursor/skills/math-mcpOr symlink to stay in sync with the repo:
ln -s "$(pwd)/docs/skills/math-mcp" ~/.cursor/skills/math-mcpThen ensure the Math MCP server is configured in each project (or globally) where you want to use it. The skill will tell the agent to use math_ls() → math_man(name) / math_ls(category) → math(name, arguments) and math_batch for batched calls.
HTTP Endpoint Setup (Alternative)
For users who want a persistent MCP server accessible via HTTP, use Docker Compose to run a long-lived container. This is useful when:
You want a single server instance shared across multiple clients
You're integrating with other applications or services
You prefer managing the server lifecycle independently
Step 1: Start the Server with Docker Compose
# Build the image (first time only)
docker build -t math-mcp .
# Start the persistent server
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the server when done
docker-compose downConfiguration:
The server runs on port 8008 by default (configurable via
.envfile)See
env.examplefor all available environment variablesCopy
env.exampleto.envto customize settings
Step 2: Configure Cursor or Claude Desktop
To connect to the HTTP endpoint, you'll use the mcp-remote package which acts as a proxy between the stdio-based MCP client and your HTTP server.
Note: mcp-remote requires Node.js 20 or higher. Make sure you have a compatible version installed before configuring the HTTP endpoint.
For Cursor
Add to your Cursor MCP settings (~/.cursor/mcp.json):
{
"mcpServers": {
"math-mcp": {
"command": "/path/to/node",
"args": ["/path/to/npx", "-y", "mcp-remote", "http://localhost:8008/mcp"]
}
}
}Note: Replace /path/to/node and /path/to/npx with actual paths on your system. To find the paths:
macOS/Linux: Run
which nodeandwhich npxin your terminalWindows: Run
where nodeandwhere npxin your command prompt
For example, on macOS/Linux:
which node # Returns something like: /usr/local/bin/node
which npx # Returns something like: /usr/local/bin/npxThen use those paths in your configuration.
Example configuration files:
docs/mcp.json- stdio Docker configuration (recommended for most users)docs/mcp.json.http- HTTP endpoint configuration (requires persistent server)
For Claude Desktop
The configuration is the same format. Add to your Claude Desktop MCP settings:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"math-mcp": {
"command": "/path/to/node",
"args": ["/path/to/npx", "-y", "mcp-remote", "http://localhost:8008/mcp"]
}
}
}Note: Replace /path/to/node and /path/to/npx with actual paths. Use which node and which npx (macOS/Linux) or where node and where npx (Windows) to find them.
Example configuration files:
docs/claude_desktop_config.json- HTTP endpoint configuration exampleSame format as Cursor's
mcp.json(seedocs/mcp.jsonfor stdio Docker mode)
Step 3: Restart and Test
Restart Cursor or Claude Desktop for the changes to take effect. The client will now connect to your persistent HTTP server.
Managing the Server
# Check server status
docker-compose ps
# View logs
docker-compose logs -f math-mcp
# Restart server
docker-compose restart
# Stop server
docker-compose down
# Update and rebuild
docker build -t math-mcp .
docker-compose up -dTroubleshooting
Connection refused: Ensure the server is running with
docker-compose psPort conflict: Change
MCP_HOST_PORTin.envfile and update the URL in your configNode/npx not found: Install Node.js from nodejs.org or use your system package manager
mcp-remote errors:
mcp-remoterequires Node.js 20 or higher. Check your version withnode --versionand upgrade if needed
Running the Server
The server supports two transport modes:
stdio (default): For CLI usage and Cursor/Claude Desktop integration via Docker
streamable-http: For persistent hosting accessible via HTTP from Docker networks and host applications
CLI & Docker CLI (stdio mode)
Perfect for command-line usage and Cursor/Claude Desktop integration.
Build the Docker Image
docker build -t math-mcp .Test the Server
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | docker run -i --rm math-mcpLocal Python (Alternative to Docker)
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
python -m math_mcp.serverHTTP Mode
For persistent hosting accessible from Docker networks and host applications.
Option 1: Docker Compose (Recommended)
# Start the server (uses docker-compose.yml)
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the server
docker-compose downConfiguration:
Create a
.envfile or set environment variablesSee
docker-compose.ymlfor all available optionsDefault: HTTP server on port 8008, accessible from host and Docker network
Example .env file:
# Copy env.example to .env and customize
MCP_TRANSPORT=streamable-http
MCP_HOST=0.0.0.0
MCP_PORT=8008
MCP_HOST_PORT=8008
MCP_PATH=/mcpAccessing from other containers:
# Server is accessible at: http://math-mcp-server:8008/mcp
# (or use the container name and your configured port)Option 2: Docker CLI
# Start persistent HTTP server (using default port 8008)
docker run -d -p 8008:8008 --name math-mcp-server \
-e MCP_TRANSPORT=streamable-http \
-e MCP_HOST=0.0.0.0 \
-e MCP_PORT=8008 \
-e MCP_PATH=/mcp \
math-mcp
# Or use a custom port (e.g., 9000)
docker run -d -p 9000:9000 --name math-mcp-server \
-e MCP_TRANSPORT=streamable-http \
-e MCP_HOST=0.0.0.0 \
-e MCP_PORT=9000 \
-e MCP_PATH=/mcp \
math-mcp
# Server will be available at:
# - http://localhost:<MCP_PORT>/mcp (from host, use the port you configured)
# - http://math-mcp-server:<MCP_PORT>/mcp (from Docker network)
# - http://<container-ip>:<MCP_PORT>/mcp (from other containers)
# Stop the server
docker stop math-mcp-server
docker rm math-mcp-serverConfiguration options:
MCP_TRANSPORT=streamable-http- Enable Streamable HTTP transport (modern HTTP-based transport)MCP_HOST=0.0.0.0- Bind to all interfaces (accessible from host and Docker network)MCP_PORT=<port>- Port to listen on inside container (default: 8008). Important: Use-p <host-port>:<container-port>to map the port when running Docker, where<container-port>should matchMCP_PORTMCP_PATH=/mcp- HTTP endpoint path (default: /mcp)MCP_OUTPUT_DIR=/outputs/- Base directory for plot output files (default: /outputs/)MCP_OUTPUT_VOLUME=./outputs- Output volume mount path (bind mount or named volume)
Port mapping examples:
# Container listens on 8008, map to host port 8008
docker run -d -p 8008:8008 -e MCP_PORT=8008 ...
# Container listens on 9000, map to host port 9000
docker run -d -p 9000:9000 -e MCP_PORT=9000 ...
# Container listens on 8008, map to different host port 3000
docker run -d -p 3000:8008 -e MCP_PORT=8008 ...Docker network usage:
# Create a network
docker network create math-network
# Run server in network
docker run -d --name math-mcp-server --network math-network \
-e MCP_TRANSPORT=streamable-http \
-e MCP_HOST=0.0.0.0 \
-e MCP_PORT=8008 \
math-mcp
# Other containers in the same network can access:
# http://math-mcp-server:<MCP_PORT>/mcpOption 3: Local Python
MCP_TRANSPORT=streamable-http MCP_HOST=127.0.0.1 MCP_PORT=8008 python -m math_mcp.serverAdd to Cursor
Add to your Cursor MCP settings (~/.cursor/mcp.json) to enable the math server (4 tools: math_ls, math_man, math, math_batch). See What This Does above for discovery and capabilities.
CLI/Docker CLI Configuration (Recommended for Cursor)
This mode runs the server via Docker CLI, perfect for Cursor integration:
{
"mcpServers": {
"math-mcp": {
"command": "docker",
"args": ["run", "-i", "--rm", "math-mcp"]
}
}
}Note:
Make sure you've built the Docker image first:
docker build -t math-mcp .Initialization is automatic: Cursor automatically handles the MCP protocol initialization handshake. You don't need to do anything manually.
Local Python Configuration
If you prefer running locally without Docker:
{
"mcpServers": {
"math-mcp": {
"command": "python",
"args": ["-m", "math_mcp.server"]
}
}
}Note: Requires the package to be installed: pip install -e ".[dev]"
Complete Example
See example configuration file:
docs/mcp.json- Docker CLI configuration
You can copy it to ~/.cursor/mcp.json and customize as needed.
Adding to Existing Configuration
If you already have other MCP servers configured, just add "math-mcp" to your existing mcpServers object:
{
"mcpServers": {
"your-existing-server": {
"command": "...",
"args": [...]
},
"math-mcp": {
"command": "docker",
"args": ["run", "-i", "--rm", "math-mcp"]
}
}
}Add to Claude Desktop
Add to your Claude Desktop MCP settings. The configuration file location varies by OS:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Configuration
{
"mcpServers": {
"math-mcp": {
"command": "docker",
"args": ["run", "-i", "--rm", "math-mcp"]
}
}
}Note:
Make sure you've built the Docker image first:
docker build -t math-mcp .Initialization is automatic: Claude Desktop automatically handles the MCP protocol initialization handshake. You don't need to do anything manually.
After updating the configuration file, restart Claude Desktop for the changes to take effect.
Statistical Analysis
The Math MCP server includes powerful statistical analysis tools for data analysis, A/B testing, and performance monitoring. All tools use scipy.stats for reliable, production-ready statistical computations.
Available Statistical Tools
1. Descriptive Statistics (describe_data)
Compute comprehensive summary statistics
Calculate percentiles (p25, p50, p75, p95, p99) critical for SLAs
Perfect for: API response times, query performance, user session lengths
Returns: count, mean, median, std, variance, min, max, range, percentiles
Example:
data=[120, 145, 167, 123, 189, 134]→ Full statistics summary
2. T-Test (ttest)
Perform one-sample or two-sample t-tests
Determine if differences are statistically significant
Perfect for: A/B testing, before/after comparisons, feature impact analysis
Supports: two-sided, greater, less alternatives
Returns: statistic, p-value, degrees of freedom, significance (α=0.05)
Example:
sample1=[100, 102, 98, 105], sample2=[95, 97, 99, 94]→ Two-sample comparison
3. Correlation (correlation)
Calculate correlation coefficients between variables
Methods: Pearson (linear), Spearman (monotonic), Kendall (rank-based)
Perfect for: Traffic vs errors, cache hit rate vs response time, metric relationships
Returns: correlation coefficient, p-value, method used
Example:
x_data=[100, 200, 300], y_data=[0.02, 0.05, 0.03]→ Pearson correlation
4. Linear Regression (linear_regression)
Fit linear models and analyze trends
Perfect for: Capacity planning, trend analysis, growth forecasting
Returns: slope, intercept, R², p-value, equation string
Example:
x_data=[1, 2, 3, 4], y_data=[2, 4, 6, 8]→ Perfect fit (R²=1.0)
5. Moving Average (moving_average)
Smooth time series data to filter noise
Methods: Simple (equal weights) or Exponential (weighted toward recent)
Perfect for: Smoothing error rates, response time trends, cleaner dashboards
Returns: smoothed values, original data, window size, method
Example:
data=[10, 12, 11, 15, 13, 14, 12], window=3→ 3-period average
Use Cases for Web Developers
Performance Monitoring: Analyze response times, calculate p95/p99 latencies
A/B Testing: Compare conversion rates, feature adoption, user engagement
Capacity Planning: Forecast growth, predict when scaling is needed
Anomaly Detection: Identify trends vs. random fluctuations
Metric Relationships: Understand correlations between system metrics
Plotting & Visualization
The Math MCP server includes powerful plotting tools for data visualization. All plots are returned as inline images that appear directly in your conversation.
Available Plot Types
1. Time Series (plot_timeseries)
Plot metrics over time with multiple series
Perfect for: response times, traffic patterns, error rates
Features: Display values on data points, currency formatting, secondary y-axis, custom linestyles
Example:
timestamps=['2026-01-01T10:00', '2026-01-01T11:00'], series={'cpu': [45, 67], 'memory': [60, 62]}Example with values:
timestamps=['Q1', 'Q2', 'Q3'], series={'sales': [1000, 1200, 1150]}, show_values=True, value_format='$.0f'
2. Bar Charts (plot_bar via math)
Compare values across categories
Perfect for: endpoint usage, error counts by type, feature adoption
Features: Display values on bars, currency formatting, both vertical and horizontal orientations
Example:
categories=['Endpoint A', 'Endpoint B'], values=[1250, 890]Example with currency:
categories=['Q1', 'Q2'], values=[1000, 1200], value_format='$.0f'
3. Histograms (plot_histogram)
Visualize data distribution and frequency
Perfect for: response time distributions, latency analysis
Includes automatic statistics (mean, median, std dev)
Example:
data=[120, 145, 167, 123, 189, ...]
4. Scatter Plots (plot_scatter)
Show correlation between two variables
Perfect for: traffic vs errors, cache hit rate vs response time
Displays correlation coefficient
Optional point labels
Example:
x_data=[100, 200, 300], y_data=[0.02, 0.05, 0.03]
5. Heatmaps (plot_heatmap)
Visualize 2D patterns
Perfect for: request patterns by hour/day, geographic distribution, error hotspots
Customizable colormaps
Example:
data=[[10, 20], [30, 40]], x_labels=['Mon', 'Tue'], y_labels=['Morning', 'Evening']
6. Stacked Bar Charts (plot_stacked_bar)
Compare multiple series across categories
Perfect for: status code breakdown, multi-environment comparison
Supports both vertical and horizontal orientations
Example:
categories=['Jan', 'Feb'], series={'success': [100, 120], 'error': [10, 8]}
7. Stacked Area Charts (plot_stackplot)
Show composition of multiple components over a continuous variable
Perfect for: revenue breakdown over time, resource usage composition, multi-component trends
Supports customizable colors and baseline options
Example:
x_data=[0, 1, 2, 3], series={'component_a': [10.5, 12.3, 11.8, 13.2], 'component_b': [5.2, 4.8, 6.1, 5.5]}
8. Pie Charts (plot_pie via math)
Display proportional data and percentage breakdowns
Perfect for: market share, status code distribution, category proportions
Supports slice explosion, custom colors, and percentage display
Example:
labels=['Category A', 'Category B', 'Category C'], values=[25.5, 18.9, 32.1]
9. ODE Solution Plots (plot_ode_solution)
Visualize differential equation solutions
Automatically plots all variables from
solve_odeoutputExample:
ode_result='{"t": [0, 1, 2], "x": [1, 0.5, 0.25], ...}'
Integration with ODE Solver
You can solve differential equations and immediately visualize the results:
# 1. Solve ODE
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"solve_ode","arguments":{"equations":["dx/dt = -x"],"initial_conditions":{"x":1.0},"time_span":[0.0,5.0]}}}') | \
docker run -i --rm math-mcp
# 2. Plot the solution (pass the JSON result from step 1)
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_ode_solution","arguments":{"ode_result":"<paste result here>"}}}') | \
docker run -i --rm math-mcpFeatures
In-memory only: No disk I/O, all images generated in memory
Automatic display: Images appear inline in Cursor/Claude conversations
Consistent styling: Professional appearance with grid lines, labels, and legends
Memory efficient: Figures are immediately closed after saving
IT-focused: Designed for operational data visualization
Value display: Show data point values on charts with customizable formatting (including currency)
Pixel-based sizing: Figure sizes specified in pixels for consistent display across devices
Format flexibility: Support for PNG and SVG output formats
Examples
CLI & Docker CLI Usage
The MCP server communicates via JSON-RPC over stdio.
Note: When using with Cursor or Claude Desktop, initialization is handled automatically by the client. The examples below are for manual CLI/testing scenarios where you're directly sending JSON-RPC messages to the server.
For manual usage, you must initialize the server before calling tools.
Proper Initialization Sequence
MCP requires an initialization handshake before calling tools. Send all messages to a single container instance:
# Send initialization sequence + tool call together
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"simplify","arguments":{"expression":"sin(x)^2 + cos(x)^2"}}}') | \
docker run -i --rm math-mcpExpected response includes initialization result, then tool result:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{...},"serverInfo":{"name":"Math","version":"1.25.0"}}}
{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"1"}]}}List Available Tools
To see all available tools, use the tools/list method:
# List all available tools
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}') | \
docker run -i --rm math-mcpExpected response includes the 4 meta-tools (math_ls, math_man, math, math_batch). Use math_ls() to discover the 26 internal tools:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{...},"serverInfo":{"name":"Math","version":"1.25.0"}}}
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"math_ls","description":"List available math tools..."},{"name":"math_man",...},{"name":"math",...},{"name":"math_batch",...}]}}Example Tool Calls
Each tool call requires the initialization sequence. Here are examples:
# Solve equation: x^2 - 4 = 0
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"solve","arguments":{"equation":"x^2 - 4","variable":"x"}}}') | \
docker run -i --rm math-mcp
# Compute derivative of x^3
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"derivative","arguments":{"expression":"x^3","variable":"x"}}}') | \
docker run -i --rm math-mcp
# Evaluate 2*pi
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"evaluate","arguments":{"expression":"2*pi"}}}') | \
docker run -i --rm math-mcp
# Convert 100 meters to kilometers
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"convert_unit","arguments":{"value":100,"from_unit":"meter","to_unit":"kilometer"}}}') | \
docker run -i --rm math-mcp
# Solve ODE: dx/dt = -x with x(0)=1 from t=0 to t=5
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"solve_ode","arguments":{"equations":["dx/dt = -x"],"initial_conditions":{"x":1.0},"time_span":[0.0,5.0],"method":"rk45"}}}') | \
docker run -i --rm math-mcp
# Find root of x^2 - 4 = 0 near x=1
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"find_root","arguments":{"function":"x^2 - 4","initial_guess":1.0,"bracket":[0.0,3.0],"method":"brentq"}}}') | \
docker run -i --rm math-mcp
# Plot time series with custom colors
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_timeseries","arguments":{"timestamps":["2026-01-01T10:00","2026-01-01T11:00","2026-01-01T12:00"],"series":{"cpu":[45,67,52],"memory":[60,62,58]},"colors":["red","blue"],"title":"System Metrics"}}}') | \
docker run -i --rm math-mcp
# Create bar chart with custom color and horizontal orientation (via math dispatcher)
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"math","arguments":{"tool":"plot_bar","arguments":{"categories":["Endpoint A","Endpoint B","Endpoint C"],"values":[1250,890,1100],"color":"#FF5733","horizontal":true,"title":"Request Counts"}}}}') | \
docker run -i --rm math-mcp
# Plot histogram with axis limits and no grid
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_histogram","arguments":{"data":[120,145,167,123,189,134,156,178,145,167],"bins":10,"xlim":[100,200],"ylim":[0,5],"grid":false,"title":"Response Time Distribution"}}}') | \
docker run -i --rm math-mcp
# Plot time series with secondary y-axis and custom linestyles
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_timeseries","arguments":{"timestamps":["10:00","11:00","12:00","13:00"],"series":{"requests":[100,200,150,180],"temperature":[20.5,21.3,22.1,21.8]},"secondary_y":{"temperature":"Temperature (°C)"},"linestyles":["-","--"],"legend_loc":"upper left"}}}') | \
docker run -i --rm math-mcp
# Create scatter plot with custom figure size (in pixels) and rotated labels
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_scatter","arguments":{"x_data":[100,200,300,400,500],"y_data":[0.02,0.05,0.03,0.06,0.04],"color":"steelblue","figsize":[1200,800],"title":"Traffic vs Error Rate","xlabel":"Requests per second","ylabel":"Error Rate"}}}') | \
docker run -i --rm math-mcp
# Plot time series with values displayed on each point and currency formatting
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_timeseries","arguments":{"timestamps":["Q1","Q2","Q3"],"series":{"sales":[1000,1200,1150]},"show_values":true,"value_format":"$.0f","title":"Quarterly Sales"}}}') | \
docker run -i --rm math-mcp
# Plot stacked bar chart with custom colors and legend
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_stacked_bar","arguments":{"categories":["Jan","Feb","Mar"],"series":{"success":[100,120,110],"error":[10,8,12],"warning":[5,3,4]},"colors":["green","red","orange"],"legend_loc":"upper right","xlabel_rotation":0}}}') | \
docker run -i --rm math-mcp
# Create stacked area chart showing composition over time
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"plot_stackplot","arguments":{"x_data":["Q1","Q2","Q3","Q4"],"series":{"product_x":[100,120,110,130],"product_y":[80,90,95,100]},"title":"Revenue by Product"}}}') | \
docker run -i --rm math-mcp
# Create pie chart with percentage display and custom colors (via math dispatcher)
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'; \
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"math","arguments":{"tool":"plot_pie","arguments":{"labels":["Category A","Category B","Category C"],"values":[25.5,18.9,32.1],"title":"Distribution","colors":["steelblue","coral","lightgreen"]}}}}') | \
docker run -i --rm math-mcpNote: For local Python usage, replace docker run -i --rm math-mcp with python -m math_mcp.server.
Interactive Session with Multiple Requests
For multiple tool calls, send the full initialization sequence followed by your requests:
cat > requests.jsonl << 'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"simplify","arguments":{"expression":"x + x"}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"solve","arguments":{"equation":"x^2 - 9","variable":"x"}}}
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"derivative","arguments":{"expression":"x^3","variable":"x"}}}
EOF
cat requests.jsonl | docker run -i --rm math-mcpHTTP Usage
When running in HTTP mode, the server exposes a REST endpoint using Streamable HTTP transport. First, start the server (see HTTP Mode section above).
Important: The streamable-http transport requires:
Accept: application/json, text/event-streamheaderSession ID management via
mcp-session-idheader (extract from initialization response)
Initialize and Call Tools via HTTP
# Step 1: Initialize and capture session ID
RESPONSE=$(curl -s -X POST http://localhost:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-D - \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}')
# Extract session ID from response headers
SESSION_ID=$(echo "$RESPONSE" | grep -i "mcp-session-id" | cut -d' ' -f2 | tr -d '\r')
# Step 2: Call tools using the session ID
curl -X POST http://localhost:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"simplify","arguments":{"expression":"sin(x)^2 + cos(x)^2"}}}'
# Expected response (Streamable HTTP format):
# event: message
# data: {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"1"}],...}}Complete Example with Multiple Tool Calls
# Initialize
RESPONSE=$(curl -s -X POST http://localhost:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-D - \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}')
SESSION_ID=$(echo "$RESPONSE" | grep -i "mcp-session-id" | cut -d' ' -f2 | tr -d '\r')
# Simplify expression
curl -X POST http://localhost:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"simplify","arguments":{"expression":"sin(x)^2 + cos(x)^2"}}}'
# Solve equation
curl -X POST http://localhost:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"solve","arguments":{"equation":"x^2 - 4","variable":"x"}}}'
# Evaluate expression
curl -X POST http://localhost:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"evaluate","arguments":{"expression":"2*pi"}}}'From Other Docker Containers
# If running in a Docker network, use the container name and configured port
# (replace 8008 with your MCP_PORT value)
RESPONSE=$(curl -s -X POST http://math-mcp-server:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-D - \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}')
SESSION_ID=$(echo "$RESPONSE" | grep -i "mcp-session-id" | cut -d' ' -f2 | tr -d '\r')
curl -X POST http://math-mcp-server:8008/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"simplify","arguments":{"expression":"x + x"}}}'Local Development
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Run in stdio mode (default)
python -m math_mcp.server
# Run in HTTP mode
MCP_TRANSPORT=streamable-http MCP_HOST=127.0.0.1 MCP_PORT=8008 python -m math_mcp.serverTesting
source .venv/bin/activate
PYTHONPATH=src pytest tests/ -vSee docs/TESTING.md for details.
License
This project is licensed under the MIT License. See LICENSE for details.
Copyright (c) 2026 codeprimate
Docs
AGENTS.md — Development guide for AI agents (build, test, lint)
docs/skills/math-mcp/ — Cursor skill tree for using Math MCP (see Using the Cursor skill)
docs/SPEC.md — Specification
docs/TESTING.md — Testing guide
Available Tools
4 toolsmathA
Execute a math tool by name. Discovery: call math_ls() first to get tool names and intents; get parameters via math_man(name) or math_ls(category); then call math(name, arguments) with the chosen tool name and its arguments.
| Name | Required | Description | Default |
|---|---|---|---|
| tool | Yes | Name of the math tool to run. | |
| arguments | No | Arguments for the tool as a JSON object. Omit or {} for no arguments. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry disclosure. It discloses the required discovery-before-call behavior and dynamic dispatch, but it does not state failure modes, validation behavior, or side effects. This is minimally adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, with the core action first and the discovery workflow second. No filler; every clause contributes to correct invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers discovery, parameter lookup, and invocation, and an output schema exists for return values. It is complete for the main execution path, though it leaves unknown-tool errors and the batch sibling unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are already documented. The description adds that tool names and parameters can be discovered via math_man and math_ls, which is useful routing information rather than new semantic detail about the parameters themselves.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Execute') and a clear resource ('a math tool by name'), presenting the tool as a dispatcher rather than a single math operation. It also distinguishes itself from its discovery siblings by listing the preceding math_ls and math_man steps.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs the agent to call math_ls first)Skip earlier? It tells the agent when to use this tool: after discovering tool names and parameters. It does not mention math_batch as an alternative for batched execution, so the guidance is not complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
math_batchA
Run multiple tools in one request. Pass a list of objects with 'name' (tool name) and optional 'arguments' (dict). Results are returned in the same order. At most 64 calls per request. Execution is parallel with concurrency limited by CPU count minus one.
| Name | Required | Description | Default |
|---|---|---|---|
| calls | No | List of tool calls. Each item: {'name': str (required), 'arguments': dict (optional, default {}).} |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral disclosure burden. It discloses parallelism, concurrency limited by CPU count minus one, result ordering, and the maximum call count. It does not explain per-call failure behavior, but the required input semantics and execution guarantees are reasonably covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the core purpose, and subsequent sentences add only necessary operational constraints. Every sentence earns its place, with no filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic batching tool, the description fully covers how to construct calls, limits, ordering, and execution semantics. Since an output schema exists, return-value details are already structured and do not need to be repeated in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the single 'calls' parameter with 100% coverage, describing the array of objects and the required 'name' and optional 'arguments' fields. The description restates this structure without adding new parameter-level detail, so it meets the baseline but does not elevate it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Run multiple tools in one request,' and immediately clarifies the input shape as a list of objects with 'name' and optional 'arguments'. This distinguishes it clearly from the sibling tools math_ls, math_man, and math as the batching/composite tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes the batching use case and provides operational constraints such as the 64-call limit and parallel execution. It does not explicitly name alternatives or state 'use this instead of individual calls,' but the context is clear enough for an agent to select it when multiple calls need to be grouped.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
math_lsA
List available math tools. Call with no args to get categories and a flat list of all tools (name, intent). Then: use math_man(name) for one tool's parameters, or math_ls(category) for full descriptors (name, description, inputSchema) for every tool in that category. Finally call math(name, arguments) to run.
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Optional category id. If omitted, returns all categories and a flat list of tools with name and intent. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses two call modes and what each returns: categories plus flat list of name/intent without category, and full descriptors with name/description/inputSchema with category. Minor edge behaviors like invalid category handling are not mentioned, but core behavior is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the tool's core purpose. The workflow phrasing is efficient and every sentence contributes useful routing information without filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter listing tool with an output schema, the description fully covers both invocation modes and the surrounding discovery workflow. An agent has everything it needs to select and call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage for the optional category parameter, including what happens when omitted. The description adds meaningful extra semantics by specifying that category changes output granularity to full descriptors per tool, going beyond the schema's basic description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Explicitly states it lists available math tools, and the description clearly separates this from math_man (one tool's parameters) and math (running a tool). The purpose is immediately actionable and distinguishable from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear workflow: call with no args for categories and a flat list, use math_man(name) for one tool's parameters, use math_ls(category) for full descriptors, and finally call math(name, arguments) to run. This gives explicit when-to-use guidance and names the alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
math_manA
Return the full descriptor (name, description, inputSchema) for a named math tool. Use after math_ls() to get parameters for a chosen tool, then call math(name, arguments) to run.
| Name | Required | Description | Default |
|---|---|---|---|
| tool | Yes | Name of the math tool to describe. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior, and it does so clearly by stating exactly what is returned and by implying through the workflow that this tool only describes, it does not execute math. A short note about not running the tool would have made it fully explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; the core capability is front-loaded and the workflow context earns its place. Every word contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter metadata lookup with an output schema, the description is complete: it names the tool, the return content, and the surrounding workflow. An agent has everything needed to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already has 100% coverage for the single parameter, so the description adds no new semantic detail beyond 'named math tool.' Baseline 3 is appropriate because the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Return') and resource ('full descriptor ... for a named math tool'), and precisely names the descriptor fields. It clearly positions math_man between math_ls and math, so an agent can distinguish it from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit workflow: use after math_ls() to get parameters, then call math(name, arguments) to run. This directly tells the agent when this tool fits relative to its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.2.0- First observed
math - First observed
math_batch - First observed
math_ls - First observed
math_man
TDQS
Scored across 4 tools
math_ls and math_man both provide tool descriptors and could be confused when seeking detailed parameter info, but their descriptions clearly separate listing from individual manual lookup. math and math_batch are distinct as single vs. batch execution.
math_ls and math_man follow a Unix-style abbreviation convention while math_batch is descriptive, and math drops the prefix entirely. The shared math_ prefix helps, but the mix of styles is noticeable.
Four tools is a reasonable size for a meta-server that delegates to a dynamic math tool set. It feels slightly thin because no actual math operations are exposed statically, but the scaffolding tools each earn their place.
The set covers the full discovery, documentation, execution, and batching lifecycle with no obvious dead ends. Agents can go from listing tools to inspecting parameters to running single or batched operations. Assuming the underlying math tool registry is populated, this is complete.
Maintenance
Related MCP Connectors
Integrates Wolfram Language and Wolfram|Alpha accessing curated data and sophisticated algorithms.
Transform your data analysis with our Data Compute & Stats Bot. Effortlessly calculate descriptive
Precision math engine for AI agents. 203 exact methods. Zero hallucination.
The statistical analyst in your AI chat — validated, citable, re-runnable analysis of your data.
Related MCP Servers
- FlicenseAqualityDmaintenanceProvides access to Wolfram Alpha's computational knowledge engine for mathematical calculations, scientific computing, data analysis, and factual information through natural language queries.26-
- AlicenseAqualityCmaintenanceProvides 21 mathematical tools across 6 domains including basic calculations, array operations, statistics, financial mathematics, linear algebra, and calculus. Supports batch execution for complex multi-step workflows with intelligent dependency resolution.216MIT
- AlicenseNot gradedqualityDmaintenanceProvides advanced mathematical calculation capabilities including symbolic algebra, numerical computing, data analysis, and image processing through SymPy, NumPy, SciPy, and pandas integration.3MIT
- AlicenseNot gradedqualityDmaintenanceProvides comprehensive mathematical capabilities including basic arithmetic, advanced functions, statistical tools, and access to mathematical constants. It allows users to perform computations and generate math-related prompts through a standardized MCP interface.MIT